Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: API Tests

on:
push:
branches: [main]
branches: [master]
pull_request:
branches: [main]
branches: [master]
schedule:
- cron: '0 6 * * *'

Expand Down Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ venv/
# Test reports
reports/
.pytest_cache/
.coverage
.coverage.*
htmlcov/

# Type checking
.mypy_cache/
Expand All @@ -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
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -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/master/graph/badge.svg)](https://codecov.io/gh/ThomasTDS/qa-api-python)

## Descrição

Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -116,17 +119,18 @@ 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.
- 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).

---

### 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
Expand Down
3 changes: 0 additions & 3 deletions api/booking_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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:"]
Loading