Skip to main content

python-unit-tests

Use when writing, fixing, or reviewing Python pytest unit tests, fixtures, mocks, or test PR feedback.

Source facts

Repository
dimensionalOS/dimos
Last source activity
July 1, 2026 at 07:41
Detected SKILL.md language
English
Stars
4,584
Forks
814

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
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?
View on GitHub