From aaa844272cfa520d4160b153d36e93dba24e6a13 Mon Sep 17 00:00:00 2001 From: ThomasTDS Date: Thu, 1 Oct 2026 23:25:17 -0300 Subject: [PATCH] =?UTF-8?q?Usa=20dados=20de=20teste=20=C3=BAnicos=20e=20av?= =?UTF-8?q?isa=20quando=20a=20limpeza=20falha?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cada booking criado ganha um sufixo aleatório no sobrenome, para que a busca por nome encontre só o booking do próprio teste na API pública compartilhada. Falhas de rede ou de autenticação na limpeza passam a gerar um aviso do pytest com o id do booking, em vez de serem ignoradas em silêncio. --- README.md | 3 ++- conftest.py | 11 +++++++++-- steps/booking_data.py | 6 +++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a6ee0d6..2b0c8b8 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,8 @@ Autenticação: `POST /auth` com `{ "username": "admin", "password": "password12 - Cobertura de autenticação, CRUD completo, PUT vs. PATCH, e casos de acesso não autorizado (403). - Relatório HTML automatizado a cada execução (`reports/report.html`, via `pytest-html`), com a versão da `master` publicada em [thomastds.github.io/qa-api-python](https://thomastds.github.io/qa-api-python/) via GitHub Pages. - Cobertura de código (`pytest-cov`) de `api/` e `models/` em cada execução, acompanhada no [Codecov](https://codecov.io/gh/ThomasTDS/qa-api-python). -- Limpeza automática: a fixture `context` remove o booking criado no cenário (via token próprio de limpeza) ao final de cada teste, evitando acúmulo de dados na API pública. +- Limpeza automática: a fixture `context` remove o booking criado no cenário (via token próprio de limpeza) ao final de cada teste, evitando acúmulo de dados na API pública. Se a remoção falhar por erro de rede ou de autenticação, o pytest mostra um aviso com o id do booking que ficou para trás, sem mudar o resultado do teste. +- Dados de teste únicos: cada booking criado leva um sufixo aleatório no sobrenome (ex: `Ciclano-3f9a1c`). Como a API pública é compartilhada, inclusive pelas execuções paralelas do CI, a busca por nome encontra só o booking do próprio teste. - Retry automático só para falhas de rede (`pytest-rerunfailures`, com `--reruns 1` e `only_rerun` no `pyproject.toml`): um teste que falha por erro de conexão ou timeout roda uma segunda vez, amortecendo a instabilidade da API pública de demonstração. Falhas de asserção ou de schema nunca são repetidas, para que um bug intermitente não passe na segunda tentativa. - Integração contínua via GitHub Actions, em dois jobs: `unit` roda as checagens estáticas e os testes unitários, sem rede, e `integration` só começa se o `unit` passar, rodando a suíte completa contra a API pública. Assim, uma falha no `integration` com o `unit` verde aponta para a API ou para um cenário, e não para o código dos clients. Os dois rodam a cada push e pull request para `master`, em Python 3.12 e 3.13, e também diariamente às 06:00 UTC (ver [.github/workflows/tests.yml](.github/workflows/tests.yml)) para detectar quebras causadas pela própria API pública, com o relatório HTML publicado como artifact do workflow. - Dependências atualizadas automaticamente pelo Dependabot (pip e GitHub Actions, semanal — ver [.github/dependabot.yml](.github/dependabot.yml)). PRs de patch/minor com CI verde são mergeados automaticamente ([.github/workflows/dependabot-auto-merge.yml](.github/workflows/dependabot-auto-merge.yml)); bumps de major exigem revisão manual. diff --git a/conftest.py b/conftest.py index f737131..1255a5c 100644 --- a/conftest.py +++ b/conftest.py @@ -1,10 +1,12 @@ import json import os +import warnings from collections.abc import Generator from typing import Any import pytest import requests +from pydantic import ValidationError from api.auth_api_client import AuthApiClient from api.booking_api_client import BookingApiClient @@ -53,8 +55,13 @@ def context() -> Generator[Context, None, None]: try: cleanup_token = ctx.auth_client.get_valid_token() ctx.booking_client.delete_booking(ctx.booking_id, cleanup_token) - except Exception: - pass # booking já pode ter sido removido pelo próprio cenário; ignora falha de limpeza + except (requests.RequestException, ValidationError) as error: + # Falha de rede ou de autenticação na limpeza não muda o resultado + # do teste, que já verificou o que precisava, mas deixa o booking + # para trás na API pública. O aviso aparece no resumo do pytest. + # (Se o próprio cenário já removeu o booking, a API só devolve um + # status de erro, sem exceção, e nada é avisado.) + warnings.warn(f"booking {ctx.booking_id} não foi removido na limpeza: {error}", stacklevel=1) session.close() diff --git a/steps/booking_data.py b/steps/booking_data.py index 87b582e..3b2be76 100644 --- a/steps/booking_data.py +++ b/steps/booking_data.py @@ -1,13 +1,17 @@ from datetime import date from typing import Any +from uuid import uuid4 from models.booking import Booking, BookingDates +# O sufixo aleatório no sobrenome deixa cada booking identificável na API +# pública, que é compartilhada: a busca por nome encontra só o booking do +# próprio teste, mesmo com outras execuções rodando ao mesmo tempo. def default_booking() -> Booking: return Booking( firstname="Fulano", - lastname="Ciclano", + lastname=f"Ciclano-{uuid4().hex[:6]}", totalprice=150, depositpaid=True, bookingdates=BookingDates(checkin=date(2026, 1, 1), checkout=date(2026, 1, 5)),