Unit Tests
SkillMediaDesign unit tests for yash-rs crates: organization, naming, Arrange-Act-Assert structure, imports, and VirtualSystem-based test doubles. Use when writing, adding, reviewing, or restructuring unit tests in any yash-* crate, and when writing the test in the test-first step of Canon TDD.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Unit Tests skill
What this skill tells your AI
The instructions your AI receives, as published by magicant/yash-rs in .agents/skills/unit-tests/SKILL.md and read by ahel’s review.
Design unit tests as follows unless you are instructed otherwise:
Organization
- Unit tests should be written in the same file as the function they test, in a
#[cfg(test)]module namedtests, unless existing tests are already organized otherwise. - Unit tests should be sorted in the order of the functions they test.
- Unit tests for the same function should be sorted so that the most basic tests come first, followed by more complex or minor cases.
Naming
- Unit test function names should describe the behavior being tested while omitting verbose words.
- Prefer:
open_returns_enoent_when_file_is_missing - Avoid:
test_that_the_open_function_returns_enoent_when_the_file_is_missing
- Prefer:
Test implementation
- Each unit test should be self-contained and independent of other tests.
- Each unit test should follow the Arrange-Act-Assert pattern.
- The values used to specify the pre- and post-conditions of the behavior being tested should be explicitly specified as literals or named constants directly in the unit test function.
- Do not rely on a helper function to produce a value that is significant to the behavior being tested. Exceptions: the helper function is clearly named to indicate the value it produces, or the unit test function passes the value to the helper function as an argument.
- Do not compute the expected values in the unit test function; write the final expected values directly. A computed expectation duplicates the implementation's logic, so the test passes even when both are wrong.
- Prefer:
assert_eq!(result, "foobar") - Avoid:
assert_eq!(result, format!("{prefix}bar"))
- Prefer:
Test doubles for yash_env::system::* traits
Creating an Env instance requires a yash_env::system::* trait implementation, which should be prepared as follows:
- Never use
yash_env::system::real::RealSystemin unit tests, unless you are testing the behavior ofRealSystemitself and the test has no side effects. - Use
yash_env::system::r#virtual::VirtualSystem,Rc<Concurrent<VirtualSystem>>, or otherVirtualSystem-based test doubles for unit tests that require anEnvinstance.- However, you can define and employ a test double dedicated to specific units tests if it is shorter than using
VirtualSystem. - Prefer a simple
VirtualSystemover a more complex test double likeRc<Concurrent<VirtualSystem>>if possible. - Tip: An
Env<Rc<Concurrent<VirtualSystem>>>can be created simply by callingEnv::new_virtual(). However, if you need to modify theVirtualSystembefore putting it into anEnv, instantiate aVirtualSystemfirst, modify it, and then wrap it in anRc<Concurrent<_>>before passing it toEnv::with_system.
- However, you can define and employ a test double dedicated to specific units tests if it is shorter than using
Test helpers about yash_env items
- Consider using items in
yash_env::test_helperfor unit tests that involveyash_envitems. Particularly,in_virtual_system,assert_stdout, andassert_stderrare often useful for tests that involveVirtualSystem. - The
yash_env::test_helpermodule is available only when thetest-helperfeature is enabled. If you want to use it in a crate that does not haveyash-envas a dev-dependency or thetest-helperfeature enabled, ask the user what they want to do rather than adding a dev-dependency and enabling the feature without consent.
Testing asynchronous code
- If applicable, use the
now_or_nevermethod from thefutures_util::future::FutureExttrait to drive aFutureto completion in a unit test. This is often applicable when there is only one asynchronous task involved in the unit test. - If multiple asynchronous tasks are involved, consider using
yash_env::test_helper::in_virtual_systemto run a main asynchronous task to completion while allowing other asynchronous tasks to progress concurrently. - If
in_virtual_systemis not applicable, manually set up ayash_executor::Executorand drive theFutureto completion using its methods. You might want to see the implementation ofin_virtual_systemfor an example of how to do this. - Avoid using
futures_executor::block_onin unit tests, though it may be found in existing unit tests.
Imports
- Imports for unit tests should be placed at the top of the
testsmodule, not at the top of the file or in each unit test function.- Exception: In case of name conflicts, imports can be placed in the unit test function.
- The
testsmodule should importsuper::*to access items from the outer module. - Items that are already in scope should not be re-imported, particularly items from the outer module.
Signals
- GitHub stars
- 101
- Forks
- 6
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
unit-tests-magicant- Source
- github.com/magicant/yash-rs