Python Test
| This documentation was generated with the assistance of AI. Please report any inaccuracies. |
Run a Python project’s pytest suite through whichever environment runner it actually uses, scope the run to what the caller asked for, and report a compact pass/fail summary parsed from pytest’s own JUnit XML log. It is a read-only reporting skill: it never fixes a failing test, edits code, installs dependencies, relocks, or starts databases unless asked to as a follow-up.
Purpose
Python projects differ in how they are run: uv run --frozen, poetry run, pdm run, pipenv run, a project .venv, or a bare interpreter. iru-python-test detects the runner, confirms pytest is really installed, reads the pytest configuration (markers, addopts, async mode, DJANGO_SETTINGS_MODULE) and detects plugins (pytest-django, anyio, pytest-asyncio, xdist, testcontainers). It then separates fast, container-free tests from integration tests that need Docker or a real database, runs exactly the requested selection, and reports counts and failures. A selector that matched nothing, a bad invocation, an unwired runner and an unavailable Docker daemon are each reported plainly, never as a clean run or as "0 tests".
For a Django project with pytest-django and pytest-playwright it also supports a ui selection (tests marked ui): it probes for an installed browser, runs the live-server UI tests behind the same lock, then collects and validates the .ui-screenshots/ captures (states × left-to-right/right-to-left × light/dark) and summarizes accessibility (axe) results at the level set in .ui-quality.yml. See Building user interfaces.
Plugin
Shipped by the iru-python plugin of the ai-catalog marketplace (install with /plugin install iru-python@ai-catalog; see Plugins).
Inputs
| Argument | Required | Description | Default |
|---|---|---|---|
|
No |
Any combination of a path, a node id ( |
|
|
No |
A |
Not set — the skill takes the lock itself for container-backed selections. |
Runner resolution (first match wins):
| Signal | Runner |
|---|---|
|
|
|
|
|
|
|
|
|
|
none of the above |
|
Fast versus integration is decided from an integration marker declared in the pytest config, else a tests/integration/ directory, else there is no split. Container-backed selections check docker info first and are serialized repository-wide behind the shared atomic-mkdir .integration-test.lock directory (owner file, stale after 60 minutes, released on every exit path).
Outputs
-
A plain-text summary in the conversation: the runner and selection used, total/passed/failed/error/skipped counts parsed from a JUnit XML log (
build/test-results/pytest.xml, orpytest-integration.xmlfor the integration selection), and for each failure theclassname::namewith the first line of its message. Errors (fixtures, collection failures) are counted separately from assertion failures. -
For
ui: the full-vs-scoped run, the screenshot count per kind in.ui-screenshots/(with malformed names and captures moved in from pytest-playwright’s output directory), failure screenshots left in place, and the accessibility level applied with violation count and rule ids (never raw axe JSON); the JUnit log isbuild/test-results/pytest-ui.xml. A missing Playwright browser is reported as unverified (never installed by this skill), anduion FastAPI or a plain package is reported as "nouiselection in this project". -
For
all, the fast and integration halves are reported separately, together with whether the lock was acquired, waited for, or held by the caller. -
An integration stage that could not run is reported as unverified (Docker unavailable, blocked by a concurrent run, database unreachable), never as passed or as failed tests.
-
Exit code 5 (no tests collected) is reported as "selector matched nothing" and exit code 4 as a bad invocation. Wiring problems (pytest not installed, pytest-django missing, no async plugin) are named as such.
-
No source or test code is ever modified.
Execution flow
Dependencies
Invokes
None — iru-python-test is a leaf skill; it only runs pytest commands and reports on their output.
Invoked by
-
FastAPI Code One Task Group — fast tests per bucket, the full fast suite, and the container-backed integration run (with
lock: held), via theiru-gate-runneragent. -
Django Code One Task Group — fast tests per bucket, the full fast suite, the container-backed integration run and, for UI buckets, the
uiselection (withlock: held), via theiru-gate-runneragent.
Its selector syntax, runner detection and fast/integration split are also reused by Python Coverage and Python Code Quality.
Related agents
-
iru-gate-runner— calling skills normally run it inside this sub-agent. It spawns no agents itself.
Source
SKILL.md on GitHub — the file this page was generated from.