tmck-code/dotfiles/pytest-style
Claude Code and agent skill by tmck-code/dotfiles
- community
Checking that the SKILL.md file is still in the repository.
Write pytest tests for this repo — correct structure, no unnecessary mocking, xdist-safe, consistent setup/result/expected/assert shape. Use when writing or editing test files, adding test coverage, or reviewing tests for style.
Install
npx vskill@latest install tmck-code/dotfiles/pytest-styleSKILL.md
Pytest Style
Rules
File layout
- Test files live in
test/. - Shared utilities go in
test/helper.py— import from there, not from conftest. test/conftest.pyholds only pytest fixtures (e.g.tmp_home,strip_ansi).- Never create a new conftest; extend the existing one.
helper.py
- Put any function used by more than one test file in
test/helper.py. - Name helpers after what they build or return, not after the test that first needed them.
- No fixtures in helper.py — only plain functions.
Grouping
- Group related tests into a class when they test the same function or a closely related family of behaviours.
- Name classes
Test<Subject>(e.g.,TestFmtTok,TestSessionCost). - Do not group unrelated tests into a class just to have a class.
- Module-level tests are fine when there is only one or two and no natural grouping.
Test names
- Name tests after the behaviour they assert.
- Good:
test_returns_zero_for_empty_log,test_stale_rows_pruned - Bad:
test_3_4_empty_log,test_feature_REQ042 - No numbers in test function names.
- No spec IDs, ticket numbers, or section labels in names.
Test body shape
Every test follows this order — no exceptions, no skipping steps:
- setup / run / expected / assert name the phases for the reader. They are
not literal comments — never emit # setup, # run, # expected or # assert into a test body.
- Use blank lines, not comments, to separate the phases, and only where they
aid reading. A short test needs no internal breaks at all.
resultholds the actual value;expectedholds the expected value.- Put
resultbeforeexpectedin the assert:assert result == expected. - For void calls being tested for side effects, omit
result/expectedand assert directly.
Assertions
- Compare whole objects, not indexes or attribute extractions.
```python # good result = list(chunk_daterange(start, end, days=7)) expected = [ (datetime(2020, 1, 1), datetime(2020, 1, 8)), (datetime(2020, 1, 8), datetime(2020, 1, 15)), ] assert result == expected
# bad assert result[0][0] == datetime(2020, 1, 1) assert result[1][1] == datetime(2020, 1, 15) ```
- When asserting on multi-line output, build the full expected string, not fragments.
- Use
assert x in yonly when the test intentionally checks membership, not as a shortcut for incomplete comparison.
Mocking
- Do not mock real interactions — file I/O, subprocess calls, class methods that contain logic.
- Acceptable to monkeypatch:
- Constants or module-level variables that control thresholds (e.g.,
sl.TokenRate.WINDOW). - Time (
time.time,datetime.now) using a minimal stub class ormonkeypatch.setattr. sl.HOMEvia thetmp_homefixture so tests never touch the real$HOME.- The test should exercise real code paths. If you feel the need to mock a method body, restructure the test or the production code instead.
Filesystem and isolation (xdist safety)
- Tests must not share mutable state. No module-level variables written by tests.
- Use
tmp_path(or thetmp_homefixture) for any filesystem writes. - Never hardcode paths that could collide across workers.
- Tests must pass in any order and in parallel.
- Do not use
@pytest.mark.serialunless you can justify why isolation is structurally impossible.
Comments
- No banner comments (
# ===== Section =====etc.). - No phase-marker comments (
# setup,# run,# expected,# assert). - Only add a comment when the why is non-obvious — a hidden constraint, a workaround, a subtle invariant.
- A docstring on a test is acceptable when the behaviour being tested is subtle; keep it to one short line.
Fixtures
- Define fixtures in
conftest.py, not in individual test files. - Prefer
monkeypatchover class-level setup/teardown. - Keep fixture scope as narrow as possible (function scope is the default and usually correct).
Style
- Single quotes throughout (strings, docstrings).
- No type annotations required on test functions, but add them on helpers in
helper.py. - Vertical kwarg alignment is fine; ruff format is excluded from
test/for this reason.
Checklist before declaring done
- [ ] No new mocks of real logic (only constants/time/HOME)
- [ ] Related tests grouped into a
Test<Subject>class - [ ] Shared helpers in
test/helper.py, not duplicated inline - [ ] Every test: setup → result → expected → assert shape
- [ ] Whole-object comparison, not index access
- [ ] No numbers in test function names
- [ ] No banner comments, no phase-marker comments
- [ ]
tmp_path/tmp_homeused for all filesystem writes - [ ] Tests pass with
pytest -x -p no:randomlyand withpytest -n auto
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckinghome/general/.claude/skills/pytest-style/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/tmck-code/dotfiles/pytest-style)