A reusable Pytest-based framework for API testing. The project separates API-agnostic framework code from concrete API test packs, so new APIs can be added without changing the core framework.
The current repository includes DummyJSON as the reference API pack.
src/framework/
core/
client.py # reusable requests-based API client
config.py # framework runtime settings
utils/
api_context.py # redacted request/response context
data_loader.py # project-relative JSON/CSV loading
schema_validator.py # JSON Schema helpers
security.py # redaction and security helpers
performance.py # lightweight timing helpers
test_application/
conftest.py # shared pytest hooks for API packs
<api_name>/
conftest.py # API-specific fixtures
helpers.py # API-specific schema/data helpers
schemas/ # API-specific JSON Schemas
test_data/ # API-specific test data
tests/ # API-specific test cases
services/ # optional future service clients
tests/framework/
core/ # framework unit tests
utils/ # framework utility unit tests
test_data/ # framework-only test data
Create and activate a virtual environment:
python -m venv .venv
source .venv/bin/activateInstall dependencies:
python -m pip install --upgrade pip
python -m pip install -r requirements.txtOptional local environment file:
cp .env.example .envFramework-wide settings:
TEST_TIMEOUT=10
TEST_RETRY_COUNT=1
TEST_RETRY_BACKOFF_SECONDS=0.5
TEST_ENV=local
LOG_LEVEL=INFO
API packs may define their own environment variables, such as base URLs,
credentials, account IDs, or feature flags. API-specific settings should stay
with the API pack and should not be added to src/framework/core/config.py.
The framework uses marker-based suites.
| Marker pattern | Purpose |
|---|---|
framework_unit_test |
Unit tests for reusable framework code. These should not call live APIs. |
<api_name> |
Full test coverage for a concrete API pack. |
<api_name>_smoke |
Minimal happy-path suite for a concrete API pack. |
Current API-pack markers:
dummyjson
dummyjson_smoke
Run all collected tests:
python -m pytestRun framework unit tests:
python -m pytest -m framework_unit_testRun the current smoke suite:
python -m pytest -m dummyjson_smokeRun the current full API pack suite:
python -m pytest -m dummyjsonRun the default CI selection locally:
python -m pytest -m "framework_unit_test or dummyjson_smoke"Run tests in parallel:
python -m pytest -m "framework_unit_test or dummyjson_smoke" -n autoRun code quality checks:
python -m ruff check .
python -m compileall -q src tests test_applicationGenerate local HTML, JUnit, and Allure result files:
python -m pytest \
-m "framework_unit_test or dummyjson_smoke" \
-n auto \
--html=reports/pytest-report.html \
--self-contained-html \
--alluredir=reports/allure-results \
--junitxml=reports/junit.xmlGenerated reports are written under reports/ and are ignored by Git.
The API client logs request and response details at INFO level. Sensitive
headers, query parameters, and common token/password fields are redacted before
they are logged or attached to failure reports.
APIClient defaults to:
Accept: application/jsonIt does not set a global Content-Type. Request body content type is inferred
per request by requests, for example:
client.post("/json-endpoint", json={"name": "example"})
client.post("/form-endpoint", data={"name": "example"})Use request-level headers when an endpoint needs a custom media type.
GitHub Actions workflow:
.github/workflows/framework-tests.yml
Runs on:
- push to
main - pull request to
main - manual workflow dispatch
Python matrix:
3.10
3.12
CI runs:
python -m compileall -q src tests test_application
python -m ruff check .
python -m pytest -m "framework_unit_test or dummyjson_smoke" -n autoThe pytest command also generates HTML, JUnit, and Allure result artifacts.
Manual workflow dispatch currently supports:
| Scope | Runs |
|---|---|
framework_unit_test |
Framework unit tests only |
dummyjson_smoke |
Current API smoke suite |
dummyjson |
Current full API pack suite |
Manual dispatch also supports parallel=true|false. It defaults to true.
Add new APIs under:
test_application/<api_name>/
Recommended pack structure:
test_application/<api_name>/
conftest.py
helpers.py
schemas/
test_data/
tests/
services/
The framework should stay reusable and API-agnostic. API-specific fixtures, schemas, expected identities, credentials, and base URLs belong to the API pack.
See docs/architecture.md for detailed framework architecture, conventions, and guidance for adding new API test packs.