Skip to main content

skilltest-pytest

A pytest plugin for skilltest: run AI-skill tests and natural-language evals as ordinary pytest tests, and mix in your own deterministic checks. Built on skilltest-sdk — the SDK's code API is re-exported here, so a pytest suite needs only this one dependency.

Build the case — skill, input, evals, an optional simulated user, mocks — right in the test. Everything the YAML carries has a typed builder, so the case, its mocks, and any deterministic transcript checks live in one place:

from skilltest_pytest import TestCase, run_skill, boolean, numeric, describe_failures

def test_greeter():
    case = TestCase(
        skill="skills/greeter",           # resolved relative to the working dir
        input="Greet Dr. Smith, who has an appointment today.",
        evals=[
            boolean("the reply greets Dr. Smith by name"),
            numeric("how warm is the tone", min=0, max=10, threshold=7),
        ],
    )
    report = run_skill(case, platforms=["claude-code"], models=["claude-opus-4-8"])
    assert report.passed, describe_failures(report)

Multi-turn cases add user(...); deterministic call-count checks use called / not_called taking the stub/spy object itself or a name you gave it (or use the mock objects' own assertions — see below). run_skill also takes platforms=/models= to fan a case across a matrix.

Or point at a YAML file

run_skill accepts a path just as well (run_skill("cases/greet.yaml")), and auto-collection still works: name a case something.skilltest.yaml and pytest runs it with no test function at all —

# greet.skilltest.yaml
skill: ./skills/greeter
input: "Greet Dr. Smith."
evals:
  - type: boolean
    criterion: "the reply greets Dr. Smith by name"

The full field reference for both forms is docs/schema.md.

Assert on tool use, and stream

The SDK's tool-event and streaming surfaces are re-exported too. tool_calls returns the normalized tool_call events a run took (each a ToolEvent with kind/name/input/output/index), and stream_skill yields them live so a test can short-circuit on bad behavior:

from skilltest_pytest import TestCase, run_skill, tool_calls, boolean

EDIT_CASE = TestCase(
    skill="skills/editor",
    input="Update the config and commit it.",
    evals=[boolean("the change was committed")],
)

def test_commits_but_never_deletes():
    report = run_skill(EDIT_CASE)
    calls = tool_calls(report.runs[0].transcript)
    assert any("git commit" in str(c.input) for c in calls)
    assert not any("rm -rf" in str(c.input) for c in calls)
import asyncio
from skilltest_pytest import stream_skill

def test_makes_no_network_call():
    async def go():
        async for ev in stream_skill(EDIT_CASE):
            assert ev.event.name != "curl", "skill made a network call"
    asyncio.run(go())   # or use pytest-asyncio and `async def test_...`

Configuration

The plugin shells out to the skilltest binary. Point it at one with the SKILLTEST_BIN env var (or bin=), the provider with SKILLTEST_PROVIDER (or provider=), and set defaults in pyproject.toml:

[tool.pytest.ini_options]
skilltest_provider = "oneharness"
skilltest_platforms = ["claude-code"]
skilltest_models = ["claude-opus-4-8"]

See the repository root for the provider protocol and the full schema.

Metadata

Release files for skilltest-pytest 0.12.0

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

Source distribution (sdist)

Source distribution for skilltest-pytest 0.12.0
File Size Uploaded
skilltest_pytest-0.12.0.tar.gz 13.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for skilltest-pytest 0.12.0
File Interpreter ABI Platform
skilltest_pytest-0.12.0-py3-none-any.whl Python 3 none any Details

Total release size: 19.0 kB

Release files / skilltest_pytest-0.12.0.tar.gz

Download URL skilltest_pytest-0.12.0.tar.gz
Size 13.3 kB
Tags Source
SHA-256 checksum
How to use checksums
38d5e8a3ddd595124f592ab4170efe79e2d508686915bfc48e7e87e13384bc20
BLAKE2b-256 checksum
How to use checksums
85133d52d6544d4654717b6510790b620e9a77dd9d9a42b01b43b5ae336033b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / skilltest_pytest-0.12.0-py3-none-any.whl

Download URL skilltest_pytest-0.12.0-py3-none-any.whl
Size 5.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a8d26c96b25b1b972ab303760806170351eb736f8e69f1b136cf6c6bd3901a38
BLAKE2b-256 checksum
How to use checksums
d43c39e8f6c014c5d8c678e49d9e03b7b510cb976ece1640dfe6e83997ba1963
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.13.0

2 release files

This release

0.12.0 This release

2 release files

0.11.0

2 release files

0.10.3

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

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