python-unit-tests
Use when writing, fixing, or reviewing Python pytest unit tests, fixtures, mocks, or test PR feedback.
来源信息
- 仓库
- dimensionalOS/dimos
- 最近来源活动
- 2026年7月1日 07:41
- 检测到的 SKILL.md 语言
- 英语
- 星标
- 4,584
- 分支
- 814
安装方式
默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。
检查来源文件
决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。
正在显示 SKILL.md
SKILL.md
来源说明 · 只读预览- name
- python-unit-tests
- description
- Use when writing, fixing, or reviewing Python pytest unit tests, fixtures, mocks, or test PR feedback.
# Python Unit Tests
Use this skill before adding, changing, or reviewing Python unit tests. The goal is **hermetic** tests: behavior-focused, deterministic, isolated, and cheap to run.
Consult these only when the branch needs more context:
- `docs/coding-agents/testing.md`
- `docs/coding-agents/code-quality-rules.md`
- `docs/development/testing.md`
- `misc/auto-fixes/fix_template.md`
## Steps
1. **Scope the behavior.** Identify the code under test, the caller-visible outcome, and the smallest test file next to it: `dimos/core/foo.py` gets `dimos/core/test_foo.py`. Completion: every new or changed test has a named behavior target and lives beside the code it covers.
2. **Build a hermetic setup.** Use module-level imports, Arrange-Act-Assert structure, fixtures for shared or resource-owning setup, and context managers for one-test local resources. Completion: setup owns all cleanup, restores global state, reuses existing fixtures when they match, and contains no fixed sleeps.
3. **Assert the contract.** Use small examples and exact expected values. Completion: every test has an unconditional assertion that proves behavior a caller depends on.
4. **Mock the boundary.** Mock only slow, nondeterministic, or external boundaries. Completion: patches use `mocker.patch`, `mocker.patch.object`, or `monkeypatch`; no direct method assignment or `__new__` fixture shells remain.
5. **Validate tightly.** Run the smallest command that can fail for the change, then broaden only when the edit justifies it. Completion: the relevant pytest command has run, and mypy/pre-commit have run only when production source typing or broad quality gates changed.
## Test shape
- Test behavior, not implementation trivia. A useful test proves an outcome the user or caller depends on.
- Use descriptive test names and Arrange-Act-Assert ordering.
- Keep all imports at module level. Do not import inside test functions unless there is a documented circular-import reason.
- Prefer `assert result == expected` over shape-only checks.
- Do not add no-value tests that only prove a dataclass stored constructor arguments or that a default equals itself.
- Do not add test-only type annotations unless they clarify the test.
## Fixtures and cleanup
- Prefer cleanup in fixtures. Keep resource setup and teardown together so teardown runs even when assertions fail.
- Before adding a fixture, check whether matching setup already exists. Reuse or extract a shared fixture when the behavior matches; do not force reuse when the resemblance is only partial.
- Use `tmp_path` for temporary files and directories.
- Clean up modules, stores, servers, transports, subscriptions, sessions, threads, subprocesses, and global state.
- Do not put `stop()`, `close()`, or cleanup calls at the end of a test body after assertions; an earlier failure skips them.
- If a resource supports a context manager and the setup is local to one test, use `with`.
- In rare cases where setup and teardown both belong in the test body, use `try`/`finally`.
## Assertions
- Every test needs a meaningful assertion.
- Do not over-assert. Assert what matters for the behavior under test, not incidental details.
- Do not print in unit tests. Replace prints with assertions.
- Avoid conditional assertions. If the test says `if hasattr(...)`, it probably does not know what it is testing.
- For async or threaded behavior, wait for a condition with a timeout, such as `threading.Event`, then assert the final values. Do not use fixed `time.sleep()` waits.
## Mocking
- Prefer `mocker.patch(...)` or `mocker.patch.object(...)` for patches and call assertions.
- Use `monkeypatch` for environment variables, paths, and module attributes that should be restored automatically.
- Prefer real lightweight value objects over mocks for dataclasses and simple message objects.
- Do not replace methods by direct assignment when a patch or spy gives clearer assertions and automatic cleanup.
- Do not build fake modules out of custom classes when standard pytest mocking can express the same behavior.
- Do not construct objects with `__new__` and fill in fields by hand. Construct normally and patch the one side effect you need to avoid.
For call assertions, use the standard pattern: patch the target with `mocker.patch.object(...)`, run the behavior, then assert with `assert_called_once_with(...)` or another precise mock assertion.
## Global state
- Use `monkeypatch.setenv`, `monkeypatch.delenv`, or fixtures instead of direct `os.environ[...]` mutation.
- Restore `global_config` or other shared state after changing it.
- A shared fixture must leave the system in the same state for the next test.
## Validation
Focused test edit:
```bash
uv run pytest dimos/path/to/test_file.py -k test_name
```
Explicit default marker filter:
```bash
uv run pytest dimos/path/to/test_file.py -k test_name -m 'not (self_hosted or mujoco or self_hosted_large)'
```
Broader local check:
```bash
./bin/pytest-fast
```
Do not run mypy for test-only edits. Run `uv run mypy` when production source typing changed or before a broader quality gate. Run `pre-commit run --all-files` for broad/autofix/final review work, not after every small unit-test edit.
## Final self-check
- Is the test next to the code it tests?
- Does it prove behavior with real assertions?
- Are imports at the top?
- Are resources cleaned by fixtures or context managers?
- Are mocks minimal and managed by `mocker` or `monkeypatch`?
- Is the test deterministic without fixed sleeps or conditional assertions?
- Did you run the smallest useful pytest command?
在 GitHub 查看