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.
Define the whole case in code (recommended)
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 referencing a named stub/spy (or 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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file skilltest_pytest-0.6.0.tar.gz.
File metadata
- Download URL: skilltest_pytest-0.6.0.tar.gz
- Upload date:
- Size: 21.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e5deb0606515022e9fd0de4bff74648da2dbf264ab1f24c8833c5358e03c6e2
|
|
| MD5 |
b5e4c42a8878bf0d6d863f97b0a661c9
|
|
| BLAKE2b-256 |
4a24b27ec099ee630b1ae83b89adbfaad6efe7cc5e1d163d2d84629c1c9014ff
|
File details
Details for the file skilltest_pytest-0.6.0-py3-none-any.whl.
File metadata
- Download URL: skilltest_pytest-0.6.0-py3-none-any.whl
- Upload date:
- Size: 5.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63b8bf5af2c1e09bfc3be43179178f1e6d78903998af25d530aa6e47919c7312
|
|
| MD5 |
566a2599241659f5ad7064e69f402303
|
|
| BLAKE2b-256 |
84841d2c097743623fe00eb9820ceb048619d8f80292bb2392f65ade0d845910
|