Skip to content

Commit aa6ac9b

Browse files
feat: update project
1 parent 8dc1904 commit aa6ac9b

15 files changed

Lines changed: 168 additions & 100 deletions

.env

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
BASE_URL=https://swapi.dev/api
2+
CONNECT_TIMEOUT=3.0
3+
READ_TIMEOUT=5.0
4+
RETRY_TOTAL=3
5+
RATE_LIMIT_SLEEP=0.1

api-batch-test/config/settings.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import os
2+
from dotenv import load_dotenv
3+
4+
load_dotenv()
5+
6+
BASE_URL = os.getenv("BASE_URL", "https://swapi.dev/api")
7+
CONNECT_TIMEOUT = float(os.getenv("CONNECT_TIMEOUT", "3.0"))
8+
READ_TIMEOUT = float(os.getenv("READ_TIMEOUT", "5.0"))
9+
RETRY_TOTAL = int(os.getenv("RETRY_TOTAL", "3"))
10+
RATE_LIMIT_SLEEP = float(os.getenv("RATE_LIMIT_SLEEP", "0.0")) # seconds between requests

api-batch-test/pytest.ini

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@ python_functions = test_*
66
norecursedirs = lib bin include .venv venv build dist *.egg-info __pycache__
77
addopts = --template=html1/index.html --report=./reports/html1-report.html
88
markers =
9-
smoke: mark a test as a smoke test.
10-
testdb: mark tests that require database connection.
9+
smoke: testes rápidos de disponibilidade
10+
contract: validação de schema/contrato
11+
pagination: validação de paginação
12+
negative: casos de erro/limites

api-batch-test/requirements.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
pytest
2-
requests
2+
pytest-xdist
33
pytest-reporter-html1
44
mypy
5-
psycopg2-binary
5+
psycopg2-binary
6+
jsonschema
7+
python-dotenv
8+
vcrpy
9+
pytest-recording

api-batch-test/tests/conftest.py

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,48 @@
1+
import time
12
import pytest
2-
from src.api_client import APIClient
3-
from src.database import DatabaseConnection
4-
5-
@pytest.fixture(scope="module")
6-
def api_client():
7-
client = APIClient(base_url="https://fakerestapi.azurewebsites.net/")
8-
yield client
3+
import requests
4+
from requests.adapters import HTTPAdapter
5+
from urllib3.util.retry import Retry
6+
from config import settings
97

8+
class HttpClient:
9+
"""Cliente HTTP focado em testes: timeout, retry e rate-limit simples."""
10+
def __init__(self, base_url: str, connect_timeout: float, read_timeout: float, retry_total: int, rate_sleep: float):
11+
self.base_url = base_url.rstrip("/")
12+
self.session = requests.Session()
13+
retry = Retry(
14+
total=retry_total,
15+
backoff_factor=0.5,
16+
status_forcelist=[429, 500, 502, 503, 504],
17+
allowed_methods=["GET"],
18+
respect_retry_after_header=True,
19+
)
20+
adapter = HTTPAdapter(max_retries=retry, pool_connections=10, pool_maxsize=10)
21+
self.session.mount("https://", adapter)
22+
self.session.mount("http://", adapter)
23+
self.session.headers.update({"Accept": "application/json"})
24+
self.timeout = (connect_timeout, read_timeout)
25+
self.rate_sleep = rate_sleep
1026

11-
@pytest.fixture(scope="module")
12-
def db_connection():
13-
"""
14-
Fixture to create a conection with PostreSQL DB.
15-
16-
Set up the env variables or parameters as needed:
17-
- DB_HOST: localhost
18-
- DB_DATABASE: seu_banco
19-
- DB_USER: seu_usuario
20-
- DB_PASSWORD: sua_senha
21-
- DB_PORT: 5432
22-
"""
23-
db = DatabaseConnection(
24-
host="localhost",
25-
database="testdb",
26-
user="user",
27-
password="1234",
28-
port=5432
29-
)
30-
yield db
31-
db.close()
27+
def get(self, path_or_url: str, **kwargs) -> requests.Response:
28+
"""GET com base_url opcional e respeito a rate-limit."""
29+
if path_or_url.startswith("http://") or path_or_url.startswith("https://"):
30+
url = path_or_url
31+
else:
32+
url = f"{self.base_url}/{path_or_url.lstrip('/')}"
33+
time.sleep(self.rate_sleep) # rate-limit simples
34+
return self.session.get(url, timeout=self.timeout, **kwargs)
35+
36+
@pytest.fixture(scope="session")
37+
def base_url() -> str:
38+
return settings.BASE_URL
39+
40+
@pytest.fixture(scope="session")
41+
def http() -> HttpClient:
42+
return HttpClient(
43+
base_url=settings.BASE_URL,
44+
connect_timeout=settings.CONNECT_TIMEOUT,
45+
read_timeout=settings.READ_TIMEOUT,
46+
retry_total=settings.RETRY_TOTAL,
47+
rate_sleep=settings.RATE_LIMIT_SLEEP,
48+
)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from typing import Dict, Generator
2+
from tests.conftest import HttpClient
3+
4+
def iter_pages(http: HttpClient, first_path: str) -> Generator[Dict, None, None]:
5+
# Iterate through pages starting from first_path
6+
resp = http.get(first_path)
7+
resp.raise_for_status()
8+
data = resp.json()
9+
yield data
10+
next_url = data.get("next")
11+
while next_url:
12+
resp = http.get(next_url)
13+
resp.raise_for_status()
14+
data = resp.json()
15+
yield data
16+
next_url = data.get("next")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
PAGE_SCHEMA = {
2+
"type": "object",
3+
"required": ["count", "next", "previous", "results"],
4+
"properties": {
5+
"count": {"type": "integer", "minimum": 0},
6+
"next": {"type": ["string", "null"]},
7+
"previous": {"type": ["string", "null"]},
8+
"results": {"type": "array"},
9+
},
10+
"additionalProperties": True,
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
PEOPLE_ITEM_SCHEMA = {
2+
"type": "object",
3+
"required": ["name", "url"],
4+
"properties": {
5+
"name": {"type": "string", "minLength": 1},
6+
"url": {"type": "string", "pattern": "^https?://"},
7+
},
8+
"additionalProperties": True,
9+
}

api-batch-test/tests/test_activities.py

Lines changed: 0 additions & 55 deletions
This file was deleted.

api-batch-test/tests/test_db_connection.py

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)