Skip to main content

APITestka

Python License PyPI Documentation Status

APITestka is a lightweight, cross-platform Python framework for automated API testing. It started as an HTTP/HTTPS / SOAP-XML / JSON request runner with reporting and a JSON-driven executor, and now ships with a much wider toolkit — variable chaining, OpenAPI / Postman / HAR / cURL importers, a record-replay proxy, security probes, parallel runners, an MCP server for Claude, and more.

Translations / Other Languages: 繁體中文 | 简体中文


Table of Contents


Highlights

Area What you get
Backends requests (sync, sessions), httpx (sync + async, HTTP/2), WebSocket, SSE, GraphQL
Data layer Variable store, {{var}} templating, CSV/JSON data-driven loops, env profiles, fake data
Assertions Field assertions, JSON Schema, JSONPath, snapshot, structural diffs, OpenAPI contract drift, response-time SLAs
Connection mTLS, proxies, DNS override, VCR-style cassette record/replay
Mock server Static, dynamic, stateful, fault injection, OpenAPI-driven, Jinja templating, webhook receiver, record-replay proxy
Runner Sequential & parallel execution, tag filters, dependency-aware ordering, retry policies
Reports HTML / JSON / XML / JUnit / Allure / Markdown / shields.io badge / SQLite trend store / run diff
Integrations Slack / Teams / Discord webhook, GitHub PR comment, cURL & HAR importers, OpenAPI / Postman importer
CLI / DX Subcommand CLI, REPL, terminal summary, shell completion, scaffold
Security Auth helpers (Basic / Bearer / JWT / AWS SigV4), header / CORS / rate-limit / SSRF probes, pip-audit wrapper, fuzz inputs
Spec inference Test record → OpenAPI, JSON Schema inference, OpenAPI changelog
AI Pluggable backend with deterministic fallback for test generation, fake data, failure classification
MCP First-class Claude Code / MCP server exposing the framework as tools
GUI Optional PySide6 GUI (English / 繁中 / 简中 / 日本語) plus Swagger UI embed
Cross-platform Windows, macOS, Linux. Python 3.10–3.14

Installation

pip install je_api_testka

Optional extras (install with pip install 'je_api_testka[<extra>]'):

Extra Adds
gui PySide6 GUI
websocket websockets for the WebSocket wrapper
schema jsonschema and jsonpath-ng for advanced assertions
security pyjwt and botocore for JWT / AWS SigV4 helpers
otel opentelemetry-api / opentelemetry-sdk for tracing hooks
mcp mcp Python SDK for the MCP server

Quick Start

from je_api_testka import test_api_method_requests, generate_html_report

test_api_method_requests(
    "get", "https://httpbin.org/get",
    result_check_dict={"status_code": 200},
)
generate_html_report("smoke")

JSON-driven equivalent (smoke.json):

{
  "api_testka": [
    ["AT_test_api_method_requests", {
      "http_method": "get",
      "test_url": "https://httpbin.org/get",
      "result_check_dict": {"status_code": 200}
    }],
    ["AT_generate_html_report", {"html_file_name": "smoke"}]
  ]
}
apitestka run smoke.json

Core Concepts

  • Backends — every HTTP call goes through requests_wrapper, httpx_wrapper, websocket_wrapper, sse_wrapper, or graphql_wrapper. They share a record format.
  • test_record_instance — a thread-safe singleton that captures every request / response. Reports, diffs, badges, and the trend store all read from it.
  • Executor — a command map (AT_* keys) over Python callables. JSON action lists drive it. New features register themselves here so apitestka run can use them without writing Python.
  • VariableStore — a thread-safe key/value store. {{var}} placeholders inside payloads, URLs, headers, and templates resolve against it. Combine with AT_extract_and_store to chain requests.
  • Optional dependencies — heavyweight features (WebSockets, JSON Schema, JWT, MCP) live behind extras and raise a friendly error if you call them without installing.

Feature Map

HTTP / Protocol Backends

Backend Function
requests test_api_method_requests (sync, sessions)
httpx sync test_api_method_httpx
httpx async test_api_method_httpx_async (HTTP/2 via http2=True)
WebSocket test_api_method_websocket, test_api_method_websocket_async (extra: websocket)
SSE iter_sse_events, test_api_method_sse
GraphQL test_api_method_graphql, test_api_method_graphql_async
from je_api_testka import test_api_method_graphql

test_api_method_graphql(
    "https://api.example.invalid/graphql",
    query="query Get($id: ID!) { user(id: $id) { id name } }",
    variables={"id": "42"},
)

Data Layer

from je_api_testka import (
    variable_store, render_template, extract_and_store, load_env_profile,
    fake_uuid, iter_csv_rows,
)

load_env_profile("envs/dev.json")           # populates variable_store
extract_and_store({"data": {"id": 7}}, "data.id", "user_id")
render_template("/users/{{user_id}}")        # -> "/users/7"

for row in iter_csv_rows("data/users.csv"):
    variable_store.set("email", row["email"])
    test_api_method_requests("post", "https://x.invalid/login", json=row)

Executor commands: AT_set_variable, AT_get_variable, AT_clear_variables, AT_extract_and_store, AT_render_template, AT_fake_uuid, AT_fake_email, AT_fake_word, AT_load_env_profile.

Assertions, Diffs and SLAs

from je_api_testka import (
    check_json_schema, check_jsonpath, assert_snapshot,
    diff_payloads, diff_openapi_specs, RetryPolicy, retry_call,
)
from je_api_testka.diff.sla_check import ResponseSLA, assert_sla

check_json_schema(payload, {"type": "object", "required": ["id"]})
check_jsonpath(payload, "$.data.id", expected=7)
assert_snapshot("user-by-id", payload, ignore_keys=["timestamp"])
diff = diff_payloads(prod_response, staging_response, ignore_paths=["server_time"])
assert_sla(records, ResponseSLA(max_ms=2000, p95_ms=1500))

Connection Layer

from je_api_testka.connection import (
    ConnectionOptions, apply_to_requests_kwargs,
    dns_override, Cassette, replay_or_record,
)

options = ConnectionOptions(cert=("c.crt", "c.key"),
                            proxies={"https": "http://proxy:8080"})

with dns_override({"api.example.invalid": "127.0.0.1"}):
    test_api_method_requests("get", "https://api.example.invalid/health")

cassette = Cassette("tape.json")  # offline replay-or-record

Mock Server

The bundled FlaskMockServer now supports several layered features:

Feature API
Static routes flask_mock_server_instance.add_router({...})
Dynamic routes server.add_dynamic_route(...) + DynamicRouter rules
Stateful store server.state (StatefulStore)
Fault injection server.fault_injector.configure(latency_seconds=..., failure_probability=...)
OpenAPI driven server.load_openapi(spec)
Templated server.add_template_route("/x", {"msg": "{{name}}"})
Webhook receive server.add_webhook("/hook") then read server.webhook_receiver.all()
Record-replay server.add_proxy("https://upstream", "tape.json")
apitestka mock --host 0.0.0.0 --port 9000

Runner

from je_api_testka.runner import (
    run_actions_parallel, filter_actions_by_tag, order_actions,
)

actions = order_actions(filter_actions_by_tag(actions, {"smoke"}))
results = run_actions_parallel(actions, max_workers=8)

Reports and Observability

from je_api_testka import (
    generate_html_report, generate_json_report, generate_xml_report,
)
from je_api_testka.utils.generate_report.junit_report import generate_junit_report
from je_api_testka.utils.generate_report.allure_report import generate_allure_report
from je_api_testka.utils.generate_report.markdown_report import generate_markdown_report
from je_api_testka.utils.generate_report.badge import generate_badge
from je_api_testka.utils.generate_report.run_diff import diff_runs
from je_api_testka.utils.generate_report.trend_store import record_current_run

generate_html_report("report")
generate_junit_report("junit.xml")          # GitHub Actions / Jenkins
generate_allure_report("allure-results")    # `allure generate` consumable
generate_markdown_report("report.md")       # Slack / GitHub-friendly
generate_badge("badge.json")                # shields.io endpoint
record_current_run("trend.sqlite")          # historical trend

OpenTelemetry hook (no-op when opentelemetry-api is absent):

from je_api_testka.utils.observability import instrument_request

with instrument_request("GET", "https://x.invalid"):
    test_api_method_requests("get", "https://x.invalid")

Integrations

from je_api_testka.integrations import (
    notify_via_webhook, post_pr_comment,
    curl_to_action, convert_har,
)
from je_api_testka.cli.import_specs import convert_spec_file

notify_via_webhook("https://hooks.slack.invalid/...", summary="...", platform="slack")
post_pr_comment("acme/widget", pr_number=42, token="<gha-token>")

action = curl_to_action("curl -X POST https://api/x -d '{\"a\":1}'")
actions = convert_har("traffic.har")
actions = convert_spec_file("openapi.json", spec_format="openapi")

CLI / Developer Experience

apitestka run actions.json              # or directory
apitestka create my_project
apitestka mock --port 9000
apitestka import openapi.json out.json --format openapi
apitestka repl                          # JSON action REPL
apitestka summary                       # ANSI-coloured summary
apitestka scaffold https://api/x out.json
apitestka completion bash               # source >> ~/.bashrc
apitestka mcp                           # MCP server over stdio

Security Probes

from je_api_testka.security import (
    basic_auth_header, bearer_token_header, build_jwt, aws_sigv4_headers,
    scan_security_headers, cors_preflight, probe_rate_limit, probe_ssrf,
    fuzz_string_inputs, run_pip_audit,
)

scan_security_headers(response_headers)              # HSTS, CSP, nosniff…
cors_preflight("https://api/x", origin="https://app")
probe_rate_limit("https://api/x", burst=20)
probe_ssrf("https://api/fetch", parameter="url")
run_pip_audit()                                      # delegates to pip-audit

OpenAPI Inference

from je_api_testka.spec import infer_schema, records_to_openapi, openapi_changelog

records_to_openapi(title="Recovered", version="0.1.0")
openapi_changelog(prev_spec, current_spec)           # markdown diff

GUI

pip install 'je_api_testka[gui]'

Headless models (HistoryPanelModel, EnvManagerModel, render_side_by_side) live in je_api_testka.gui, allowing tests and headless tooling to drive panels without PySide6. The actual Qt widgets live in main_widget.py.

Locales: English, 繁體中文, 简体中文, 日本語. Switch via LanguageWrapper.reset_language(...).

Pluggable AI Backend

Default backend (NoOpAIBackend) never calls a network. Plug in your own to enable LLM-driven test generation:

from je_api_testka.ai import AIBackend, set_ai_backend, generate_tests_from_openapi

class AnthropicBackend(AIBackend):
    def complete(self, prompt, *, context=None):
        ...  # call your provider
        return llm_response_text

set_ai_backend(AnthropicBackend())
actions = generate_tests_from_openapi(my_openapi_spec)  # falls back to a deterministic
                                                        # happy path if the LLM reply is
                                                        # not valid JSON

MCP Server for Claude

APITestka ships an MCP server so Claude (and any other MCP-compatible client) can drive the framework. Eight tools are exposed:

Tool Purpose
apitestka_run_action Execute an action list
apitestka_test_api One-shot HTTP request via requests backend
apitestka_curl_to_action cURL → action JSON
apitestka_har_import HAR file → action list
apitestka_render_markdown Markdown report from current records
apitestka_records_to_openapi Reconstruct an OpenAPI document
apitestka_clear_records Wipe the test record
apitestka_get_records Return successes / failures

Install and run:

pip install 'je_api_testka[mcp]'
apitestka-mcp        # or: apitestka mcp / python -m je_api_testka.mcp_server

Claude Code config (~/.claude/mcp.json):

{
  "mcpServers": {
    "apitestka": {
      "command": "apitestka-mcp"
    }
  }
}

Project Structure

je_api_testka/
├── __init__.py              # Public API exports
├── __main__.py              # Legacy CLI entry point
├── ai/                      # Pluggable AI backend + helpers
├── cli/                     # apitestka CLI subcommands + REPL + completions
├── connection/              # ConnectionOptions, DNS override, Cassette
├── data/                    # VariableStore, templates, faker, env profiles
├── diff/                    # Response diff / contract drift / SLA
├── graphql_wrapper/         # GraphQL helper
├── gui/                     # Optional PySide6 GUI + headless models
├── httpx_wrapper/           # httpx sync + async wrapper
├── integrations/            # Notifications, PR comments, importers
├── mcp_server/              # Claude / MCP server
├── pytest_plugin/           # pytest fixtures
├── requests_wrapper/        # requests wrapper
├── runner/                  # Parallel runner, tag filter, dependency runner
├── security/                # Auth helpers, fuzz, header / CORS / SSRF / rate-limit / CVE
├── spec/                    # OpenAPI inference / changelog
├── sse_wrapper/             # Server-Sent Events helper
├── utils/                   # Executor, mock server, generators, etc.
└── websocket_wrapper/       # WebSocket wrapper

Optional Extras

pip install 'je_api_testka[websocket]'
pip install 'je_api_testka[schema]'
pip install 'je_api_testka[security]'
pip install 'je_api_testka[otel]'
pip install 'je_api_testka[mcp]'
pip install 'je_api_testka[gui]'

Development

git clone https://github.com/Integration-Automation/APITestka.git
cd APITestka
pip install -r dev_requirements.txt
pytest                     # full suite (~300+ tests)

CI runs the suite against Python 3.10 – 3.14 on Ubuntu, macOS, and Windows.


Contributing

See CONTRIBUTING.md. Every commit must ship with unit tests (see CLAUDE.md → Testing Guidelines).


License

MIT — see licenses/APITestka_LICENSE.


Release files for je-api-testka 0.0.142

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for je-api-testka 0.0.142
File Size Uploaded
je_api_testka-0.0.142.tar.gz 106.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for je-api-testka 0.0.142
File Interpreter ABI Platform
je_api_testka-0.0.142-py3-none-any.whl Python 3 none any Details

Total release size: 252.7 kB

Release files / je_api_testka-0.0.142.tar.gz

Download URL je_api_testka-0.0.142.tar.gz
Size 106.9 kB
Tags Source
SHA-256 checksum
How to use checksums
fdb5c9bfbb489e1d89495856ab8f8d9a920c2b3585c9b80f29f93c406e205727
BLAKE2b-256 checksum
How to use checksums
2672a2345204c7fb6f6255b60914292cb07e60d92fc4de335900c8e841709572
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / je_api_testka-0.0.142-py3-none-any.whl

Download URL je_api_testka-0.0.142-py3-none-any.whl
Size 145.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ada5244a7d0e5e765cfcc2bdd3c1da5f02578c193ac5d95eae055acb74b66a4b
BLAKE2b-256 checksum
How to use checksums
2d25411c4fc0a595eaf1f2858ccbd2f030995e6371857c89e056335eceb22e94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

This release

0.0.142 This release

2 release files

0.0.99

2 release files

0.0.98

2 release files

0.0.94

2 release files

0.0.93

2 release files

0.0.92

2 release files

0.0.88

2 release files

0.0.87

2 release files

0.0.82

2 release files

0.0.81

2 release files

0.0.80

2 release files

0.0.79

2 release files

0.0.78

2 release files

0.0.75

2 release files

0.0.74

2 release files

0.0.73

2 release files

0.0.71

2 release files

0.0.70

2 release files

0.0.64

2 release files

0.0.63

2 release files

0.0.62

2 release files

0.0.61

2 release files

0.0.60

2 release files

0.0.59

2 release files

0.0.58

2 release files

0.0.55

2 release files

0.0.54

2 release files

0.0.53

2 release files

0.0.52

2 release files

0.0.51

2 release files

0.0.50

2 release files

0.0.48

2 release files

0.0.47

2 release files

0.0.46

2 release files

0.0.45

2 release files

0.0.44

2 release files

0.0.43

2 release files

0.0.42

2 release files

0.0.41

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page