From f52108b76ef7804bfdf86a2f628e064384a3c319 Mon Sep 17 00:00:00 2001 From: ThomasTDS Date: Sat, 19 Sep 2026 14:09:39 -0300 Subject: [PATCH 1/2] =?UTF-8?q?Remove=20m=C3=A9todo=20morto=20e=20adiciona?= =?UTF-8?q?=20cobertura=20de=20c=C3=B3digo=20com=20Codecov?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove exemplo_com_bug de BookingApiClient, que não era usado em lugar nenhum do projeto. - Adiciona pytest-cov medindo api/ e models/ em toda execução de pytest, exportando reports/coverage.xml. - CI envia a cobertura para o Codecov e o README ganha o badge correspondente. --- .github/workflows/tests.yml | 8 ++++++++ .gitignore | 6 ++++++ README.md | 6 +++++- api/booking_api_client.py | 3 --- pyproject.toml | 9 ++++++++- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b7af428..dbb7da2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -37,6 +37,14 @@ jobs: - name: Rodar testes run: pytest + - name: Enviar cobertura para o Codecov + if: always() + uses: codecov/codecov-action@v7 + with: + files: reports/coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false + - name: Publicar relatório HTML if: always() uses: actions/upload-artifact@v7 diff --git a/.gitignore b/.gitignore index 9993f66..d82cc2a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ venv/ # Test reports reports/ .pytest_cache/ +.coverage +.coverage.* +htmlcov/ # Type checking .mypy_cache/ @@ -25,3 +28,6 @@ reports/ # VS Code .vscode/ + +# Log de decisões do projeto (uso pessoal, não é material público) +Decisões projeto.md diff --git a/README.md b/README.md index f6dfb8d..073c7fe 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # 🔌 QA API + pytest-bdd - restful-booker [![API Tests](https://github.com/ThomasTDS/qa-api-python/actions/workflows/tests.yml/badge.svg)](https://github.com/ThomasTDS/qa-api-python/actions/workflows/tests.yml) +[![codecov](https://codecov.io/gh/ThomasTDS/qa-api-python/branch/main/graph/badge.svg)](https://codecov.io/gh/ThomasTDS/qa-api-python) ## Descrição @@ -25,7 +26,7 @@ qa-api-python/ ├── steps/ # Implementação dos steps do pytest-bdd ├── api/ # API Clients (AuthApiClient, BookingApiClient) ├── models/ # Schemas Pydantic e tipos derivados (shape dos dados da API) -├── reports/ # Relatório HTML gerado a cada execução (não versionado) +├── reports/ # Relatório HTML e cobertura (coverage.xml) gerados a cada execução (não versionado) ├── conftest.py # Fixtures (contexto por cenário) e captura de evidência de falha ├── pyproject.toml # Dependências, scripts e configuração (pytest, ruff, mypy) ├── .pre-commit-config.yaml # Hook de pre-commit (ruff) @@ -75,6 +76,8 @@ ruff format . # formatação, aplica as correções O CI roda `mypy`, `ruff check` e `ruff format --check` antes dos testes, então mudanças com problema de tipo ou estilo falham rápido, sem gastar tempo batendo na API pública. +Cada execução de `pytest` já gera cobertura de `api/` e `models/` (código dos API Clients e dos schemas), impressa no terminal e também em `reports/coverage.xml` (não versionado). No CI esse arquivo é enviado para o [Codecov](https://codecov.io/gh/ThomasTDS/qa-api-python), que mantém o histórico e mostra o badge no topo deste README. + Um hook de pre-commit (framework `pre-commit`, instalado via `pre-commit install` após o `pip install`) roda `ruff --fix` e `ruff format` nos arquivos staged antes de cada commit, então a maioria dos problemas de lint/formatação já é corrigida localmente antes de chegar no CI. ### Rodar contra outra URL @@ -116,6 +119,7 @@ Autenticação: `POST /auth` com `{ "username": "admin", "password": "password12 - Validação de schema com [Pydantic](https://docs.pydantic.dev/): as respostas da API são validadas em tempo de execução contra os modelos em `models/booking.py` (fonte única de verdade), não só tipadas por anotação — se a API mudar o formato de uma resposta, o teste falha com uma mensagem clara em vez de passar silenciosamente ou quebrar mais adiante. - 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`). +- 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. - Retry automático (`pytest-rerunfailures`, `--reruns 1`): um cenário que falha roda uma segunda vez antes de ser reportado como falha, amortecendo instabilidade transitória da API pública de demonstração. - Integração contínua via GitHub Actions: os testes rodam automaticamente a cada push e pull request para `main`, 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. diff --git a/api/booking_api_client.py b/api/booking_api_client.py index d1e678f..921572a 100644 --- a/api/booking_api_client.py +++ b/api/booking_api_client.py @@ -48,6 +48,3 @@ def partial_update_booking(self, booking_id: int, partial_booking: dict[str, Any def delete_booking(self, booking_id: int, token: str) -> requests.Response: return self.session.delete(f"{self.base_url}/booking/{booking_id}", cookies={"token": token}) - - def exemplo_com_bug(self, booking_id: int) -> None: - self.get_booking(booking_id) diff --git a/pyproject.toml b/pyproject.toml index ce28281..8e828b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ dev = [ "pytest-bdd>=8.1", "pytest-rerunfailures>=15.0", "pytest-html>=4.1", + "pytest-cov>=6.0", "ruff>=0.14", "mypy>=1.14", "types-requests>=2.32", @@ -29,7 +30,7 @@ include = ["api*", "models*"] [tool.pytest.ini_options] testpaths = ["steps"] -addopts = "--reruns 1 --html=reports/report.html --self-contained-html" +addopts = "--reruns 1 --html=reports/report.html --self-contained-html --cov=api --cov=models --cov-report=term-missing --cov-report=xml:reports/coverage.xml" markers = [ "smoke: fluxos ponta-a-ponta mais críticos (equivalente a npm run test:smoke)", "TC-001: id do test case, ver docs/test-cases.md", @@ -59,3 +60,9 @@ python_version = "3.12" strict = true ignore_missing_imports = true exclude = ["reports"] + +[tool.coverage.run] +branch = true + +[tool.coverage.report] +exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:"] From 791ec592ec0cc3b1aa20fc171857ed914b4ec4ca Mon Sep 17 00:00:00 2001 From: ThomasTDS Date: Sat, 19 Sep 2026 14:14:26 -0300 Subject: [PATCH 2/2] Corrige workflow e README para referenciar master em vez de main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit O repositório sempre usou master como branch principal, mas o tests.yml e o README foram escritos referenciando main. Na prática isso significava que o CI nunca disparava em push nem pull request, e a branch master nunca teve proteção de fato configurada no GitHub. --- .github/workflows/tests.yml | 4 ++-- README.md | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index dbb7da2..5a54b70 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -2,9 +2,9 @@ name: API Tests on: push: - branches: [main] + branches: [master] pull_request: - branches: [main] + branches: [master] schedule: - cron: '0 6 * * *' diff --git a/README.md b/README.md index 073c7fe..cf32e18 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # 🔌 QA API + pytest-bdd - restful-booker [![API Tests](https://github.com/ThomasTDS/qa-api-python/actions/workflows/tests.yml/badge.svg)](https://github.com/ThomasTDS/qa-api-python/actions/workflows/tests.yml) -[![codecov](https://codecov.io/gh/ThomasTDS/qa-api-python/branch/main/graph/badge.svg)](https://codecov.io/gh/ThomasTDS/qa-api-python) +[![codecov](https://codecov.io/gh/ThomasTDS/qa-api-python/branch/master/graph/badge.svg)](https://codecov.io/gh/ThomasTDS/qa-api-python) ## Descrição @@ -122,7 +122,7 @@ Autenticação: `POST /auth` com `{ "username": "admin", "password": "password12 - 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. - Retry automático (`pytest-rerunfailures`, `--reruns 1`): um cenário que falha roda uma segunda vez antes de ser reportado como falha, amortecendo instabilidade transitória da API pública de demonstração. -- Integração contínua via GitHub Actions: os testes rodam automaticamente a cada push e pull request para `main`, 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. +- Integração contínua via GitHub Actions: os testes rodam automaticamente a cada push e pull request para `master`, 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. - Rastreabilidade de QA: matriz de test cases em [docs/test-cases.md](docs/test-cases.md), com tags `@TC-XXX` em cada `Scenario` e um subconjunto `@smoke` (`pytest -m smoke`) cobrindo os fluxos ponta-a-ponta mais críticos. Bugs reais encontrados são documentados como GitHub Issues usando o template em [.github/ISSUE_TEMPLATE/bug_report.md](.github/ISSUE_TEMPLATE/bug_report.md). @@ -130,7 +130,7 @@ Autenticação: `POST /auth` com `{ "username": "admin", "password": "password12 ### Fluxo de Trabalho -A branch `main` é protegida: toda mudança passa por Pull Request, e o merge só é liberado depois que o check de CI (`test`) passa. Fluxo padrão: +A branch `master` é protegida: toda mudança passa por Pull Request, e o merge só é liberado depois que o check de CI (`test`) passa. Fluxo padrão: ``` git checkout -b minha-branch