Python testing
Skill bitwise-media-group/skills/plugins/python/skills/python-testing
Coding agent marketplace for skills used by the BitWise Media Group.
npx -y skills add bitwise-media-group/skills --skill python-testingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Python test authoring and review with pytest. Use when writing, adding, generating, or reviewing Python tests or unit tests for a function, module, or class; running pytest or a single test (the -k flag and other invocation flags for a Makefile or CI); parametrizing test cases into the table-driven pattern; setting up pytest fixtures or using the built-in tmp_path, monkeypatch, or capsys; choosing between hand-written fakes and mock objects; asserting a function raises with pytest.raises; or adding property-based or fuzz tests to a Python parser, encoder, or validator with Hypothesis. Covers pytest conventions, fixtures, parametrization, fakes vs mocks, error-path testing, and Hypothesis property testing. Not for non-Python test frameworks (Jest, Go testing), type hints, ruff/linting, or scaffolding a project.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
3.9 KB, as published. Nobody here has run it
Python testing conventions
pytest is the whole toolkit — plain assert, fixtures, parametrization, and Hypothesis for
property tests. No unittest.TestCase boilerplate, no assertion DSLs. Tests live in tests/ and
run with uv run pytest.
1. Parametrize instead of repeating
One test, a row per case — the table-driven pattern. Adding a behavior is adding a row:
import pytest
from myapp.kv import parse
@pytest.mark.parametrize(
("line", "want_key", "raises"),
[
("a=b", "a", False),
("ab", None, True), # missing separator
("=b", None, True), # empty key
("a=", "a", False), # empty value is fine
],
)
def test_parse(line: str, want_key: str | None, raises: bool) -> None:
if raises:
with pytest.raises(ValueError):
parse(line)
else:
assert parse(line)[0] == want_key
Name each test for the behavior it pins down; assert directly — pytest rewrites it into a rich
failure message.
2. Fixtures for setup, built-ins first
Shared setup is a @pytest.fixture; teardown goes after a yield. Reach for the built-in fixtures
before inventing your own — tmp_path (a real temp directory), monkeypatch (patch env/attrs,
auto-reverted), capsys (capture stdout/stderr). Put cross-file fixtures in tests/conftest.py.
3. Fakes over mocks
Prefer a small hand-written fake — a class with canned returns satisfying the consumer's Protocol
(see python-typing) — to unittest.mock.MagicMock. Assert on observable behavior (return values,
recorded state), not on which methods were called. Use monkeypatch to swap a dependency at a
boundary; reserve mock for third-party seams you do not own, and avoid asserting call counts —
they couple tests to implementation.
4. Property tests with Hypothesis
Every parser, encoder, or validator handling untrusted input gets a Hypothesis test — the analogue of Go's native fuzzing. Generate inputs and assert the invariants that must hold for any input (no crash, round-trips, never emits an invalid result):
from hypothesis import given, strategies as st
from myapp.kv import parse
@given(st.text())
def test_parse_never_crashes(s: str) -> None:
try:
key, _ = parse(s)
except ValueError:
return # rejecting bad input is fine
assert key != "" # but a parsed key is never empty
Hypothesis shrinks any failing case to a minimal example and records it, so the regression replays
on every run. Use @given with explicit strategies; seed known tricky cases with @example.
5. Invocations
uv run pytest # the suite (unit + property tests)
uv run pytest -q # quiet, for the make/CI gate
uv run pytest -k name # run tests matching an expression
uv run pytest --cov=myapp # coverage (needs the pytest-cov dev dependency)
make test runs uv run pytest (see python-project); CI runs the same (see python-release).
For the interfaces that make code testable see python-typing; for house style see python-style.