QueryQA is a lightweight YAML-driven API testing CLI for QA engineers.
PowerShell:
python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install .
python3 -m venv .venv
source .venv/bin/activate
python -m pip install .
qa run examples/httpbin_smoke.yaml
This will produce unique reports like:
reports/httpbin-smoke-report/httpbin-smoke-YYYYMMDD-HHMMSS.jsonreports/httpbin-smoke-report/httpbin-smoke-YYYYMMDD-HHMMSS.html
qa run PATH [--env NAME] [--tag TAG ...] [--tag-all] [--name SUBSTRING] [--fail-fast]
[--report-json FILE] [--report-html FILE]
Examples:
qa run examples/httpbin_smoke.yaml
qa run examples/ --tag smoke
qa run examples/httpbin_post.yaml --name "Post"
qa run examples/httpbin_smoke.yaml --fail-fast
qa run examples/httpbin_smoke.yaml --report-html run-1.html
Exit codes:
0= all steps passed1= at least one step failed2= configuration/validation error
See docs/cli.md for a full CLI guide.
version: 1
name: "User API smoke"
defaults:
base_url: ${env.BASE_URL}
headers:
Content-Type: application/json
auth: bearer:${env.API_TOKEN}
timeout_ms: 5000
retries: 1
envs:
staging:
BASE_URL: https://staging.api.example.com
API_TOKEN: ${env.STAGING_TOKEN}
scenarios:
- name: "Create and fetch user"
tags: ["smoke", "users"]
data:
- _name: "valid"
name: "Ada"
email: "ada@example.com"
- _name: "invalid"
name: "Bad"
email: "bad-email"
steps:
- name: "Create user"
request:
method: POST
path: /users
json:
name: "Ada"
email: "ada@example.com"
extract:
user_id: $.id
assert:
status: 201
json:
$.name: "Ada"
$.email: "ada@example.com"
headers:
Content-Type:
contains: "application/json"
- name: "Get user"
request:
method: GET
path: /users/${user_id}
assert:
status:
between: [200, 299]
json:
$.id: ${user_id}
$.name: "Ada"
schema: schemas/user.jsonA request must include either path (combined with defaults.base_url) or a full url.
Supported request fields:
method(required)pathorurlheadersquery(query string params)json(JSON body)body(raw string body)timeout_msretriesauth(overrides defaults)
- Bearer:
auth: bearer:YOUR_TOKEN - Basic:
auth: basic:username:password
Top-level assertion keys:
status: integer, list, or range (between: [min, max])headers: header name -> matcherjson: JSONPath -> matcherschema: JSON Schema file path (relative to suite file)timing: integer (max ms) or{ max_ms: N }
Matchers:
equalscontainsregextype(string, number, boolean, object, array, null)one_ofgt,gte,lt,ltelen/lengthexists(true/false)
${env.X}resolves from suite envs and OS environment variables.${var}resolves from extracted variables in the same scenario.
Scenario controls in YAML:
- name: "Create and fetch user"
tags: ["smoke", "users"]
skip: false # true or a string reason
only: false # if any scenario has only: true, only those runCLI filters:
qa run examples/httpbin_smoke.yaml --tag smoke
qa run examples/httpbin_smoke.yaml --tag smoke --tag users --tag-all
qa run examples/httpbin_smoke.yaml --name "UUID"
qa run examples/httpbin_smoke.yaml --fail-fast
Use data to repeat a scenario with different inputs:
- name: "Echo values"
data:
- _name: "alpha"
value: "alpha"
- _name: "beta"
value: "beta"
steps:
- name: "Echo value"
request:
method: GET
path: /anything/${value}- JSON report: detailed data for automation, unique name under
reports/. - HTML report: human-friendly and includes per-assertion PASS/FAIL, unique name under
reports/.
JSON report structure includes suites -> scenarios -> steps, and each step has:
requestresponseassertions(spec,results,failures)status/error
For data-driven scenarios, each scenario entry can also include:
iterationdata
examples/httpbin_smoke.yamlexamples/httpbin_post.yamlexamples/httpbin_auth.yamlexamples/httpbin_status.yamlexamples/httpbin_data.yaml
See examples/README.md for walkthroughs.
Additional documentation:
docs/cli.mddocs/httpbin.md
- No data-driven tables or CSV parameterization yet
- No hooks/fixtures yet
- No multipart/file uploads (yet!)
python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -e .
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .