home-manager/programs/agent-skills/skills/testing-patterns/SKILL.md
This skill should be used when the user asks to "write tests", "test strategy", "coverage", "unit test", "integration test", or needs testing guidance. Provides testing methodology and patterns.
npx skillsauth add takeokunn/nixos-configuration Testing PatternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
<test_phase>Act: Execute the code under test</test_phase>
total = cart.calculate_total
<test_phase>Assert: Verify expected outcomes</test_phase>
assert_equal 0, total
</example>
<note>Separates setup, execution, and verification into distinct phases</note>
</pattern>
<pattern name="given_when_then">
<description>BDD-style test structure focusing on behavior</description>
<decision_tree name="when_to_use">
<question>Is the test focused on business behavior rather than technical implementation?</question>
<if_yes>Apply given-when-then pattern for BDD-style tests</if_yes>
<if_no>Use arrange-act-assert for technical unit tests</if_no>
</decision_tree>
<example>
<bdd_step>Given: Initial context (preconditions)</bdd_step>
given_a_user_with_an_empty_cart
<bdd_step>When: Action or trigger</bdd_step>
when_the_user_calculates_total
<bdd_step>Then: Expected outcome</bdd_step>
then_the_total_should_be_zero
</example>
<note>Emphasizes business behavior over technical implementation</note>
</pattern>
<pattern name="stub">
<description>Provide canned responses for dependencies</description>
<decision_tree name="when_to_use">
<question>Does the test need dependency responses but not interaction verification?</question>
<if_yes>Apply stub pattern for canned responses</if_yes>
<if_no>Use mock if interaction verification is needed</if_no>
</decision_tree>
<example>
api_client = stub(
fetch_user: { id: 1, name: "John" }
)
</example>
<use_case>Replace slow/unreliable dependencies</use_case>
</pattern>
<pattern name="mock">
<description>Verify interactions occurred with dependencies</description>
<decision_tree name="when_to_use">
<question>Does the test need to verify specific interactions occurred?</question>
<if_yes>Apply mock pattern to verify method calls and arguments</if_yes>
<if_no>Use stub if only canned responses are needed</if_no>
</decision_tree>
<example>
email_service = mock()
email_service.expect(:send_email, args: ["[email protected]", "Welcome"])
user_service.register(email_service)
email_service.verify
</example>
<use_case>Ensure methods called with correct arguments</use_case>
</pattern>
<pattern name="spy">
<description>Record calls while using real implementation</description>
<decision_tree name="when_to_use">
<question>Does the test need real behavior plus interaction verification?</question>
<if_yes>Apply spy pattern to record calls while using real implementation</if_yes>
<if_no>Use stub for canned responses or mock for behavior replacement</if_no>
</decision_tree>
<example>
logger = spy(Logger.new)
service.process(logger)
assert_called logger, :log, with: "Processing complete"
</example>
<use_case>Verify side effects without changing behavior</use_case>
</pattern>
<pattern name="fake">
<description>Working implementation suitable for testing</description>
<decision_tree name="when_to_use">
<question>Does the test need a simplified but working implementation?</question>
<if_yes>Apply fake pattern for lightweight working implementation</if_yes>
<if_no>Use stub for simple canned responses</if_no>
</decision_tree>
<example>
class FakeDatabase
def initialize
@data = {}
end
def save(key, value)
@data[key] = value
end
def find(key)
@data[key]
end
end
</example>
<use_case>In-memory database, fake file system</use_case>
</pattern>
<pattern name="descriptive_naming">
<description>Test names that clearly describe scenario and outcome</description>
<decision_tree name="when_to_use">
<question>Is this a technical unit test for a specific method?</question>
<if_yes>Apply descriptive naming with method-scenario-result format</if_yes>
<if_no>Consider should naming for BDD-style tests</if_no>
</decision_tree>
<example>
test_calculateTotal_withEmptyCart_returnsZero
test_calculateTotal_withMultipleItems_returnsSumOfPrices
test_calculateTotal_withDiscount_appliesDiscountCorrectly
</example>
<note>Format: test_[method]_[scenario]_[expected_result]</note>
</pattern>
<pattern name="should_naming">
<description>BDD-style naming that reads like natural language</description>
<decision_tree name="when_to_use">
<question>Is this a behavior-focused test readable by non-technical stakeholders?</question>
<if_yes>Apply should naming for natural language readability</if_yes>
<if_no>Use descriptive naming for technical unit tests</if_no>
</decision_tree>
<example>
calculateTotal_should_returnZero_when_cartIsEmpty
calculateTotal_should_applyDiscount_when_couponIsValid
calculateTotal_should_throwError_when_pricesAreNegative
</example>
<note>Format: [method]_should_[expected_behavior]_when_[condition]</note>
</pattern>
<pattern name="property_based_testing">
<description>Generate random inputs to verify properties that should always hold</description>
<decision_tree name="when_to_use">
<question>Does the function have a property or invariant that holds for all valid inputs?</question>
<if_yes>Apply property-based testing to generate random inputs and verify invariants</if_yes>
<if_no>Use example-based tests with arrange-act-assert</if_no>
</decision_tree>
<example>
<note>Haskell (QuickCheck/Hedgehog)</note>
prop_reverse_involutive xs = reverse (reverse xs) == xs
<note>JS/TS (fast-check)</note>
fc.assert(
fc.property(fc.array(fc.integer()), (arr) =>
deepEqual(arr, reverse(reverse(arr)))
)
)
</example>
<tools>QuickCheck (Haskell), Hedgehog (Haskell), fast-check (JS/TS), Hypothesis (Python)</tools>
<use_case>Serialization round-trips, sorting invariants, mathematical properties, parser correctness</use_case>
</pattern>
<pattern name="snapshot_testing">
<description>Capture output and compare against a stored reference snapshot</description>
<decision_tree name="when_to_use">
<question>Is the output complex and best verified by comparing against a known-good reference?</question>
<if_yes>Apply snapshot testing to detect unintended output changes</if_yes>
<if_no>Use explicit assertions for specific values</if_no>
</decision_tree>
<example>
expect(renderComponent()).toMatchSnapshot()
</example>
<note>Vitest 4.x supports visual regression testing via Browser Mode for comparing rendered UI screenshots against baseline images</note>
<use_case>Component rendering, serialized data structures, CLI output</use_case>
</pattern>
<best_practices> <practice priority="critical"> <name>Test happy path first</name> <description>Start with the normal, expected flow before edge cases</description> <example> test_userLogin_withValidCredentials_succeeds test_userLogin_withInvalidPassword_fails test_userLogin_withLockedAccount_fails </example> </practice>
<practice priority="critical"> <name>Test edge cases</name> <description>Test boundary conditions and limits</description> <example> Empty inputs, maximum values, null values, zero values, negative numbers </example> </practice> <practice priority="critical"> <name>Test error cases</name> <description>Verify error handling paths work correctly</description> <example> Invalid inputs, network failures, permission errors, timeout scenarios </example> </practice> <practice priority="high"> <name>Isolate tests</name> <description>Each test should be independent</description> <example> <note>Use setup/teardown to reset state</note> def setup @database = TestDatabase.new @service = UserService.new(@database) end def teardown
@database.clear
end
</example>
</practice>
<practice priority="high">
<name>Make tests readable</name>
<description>Tests serve as documentation</description>
<example>
<note>Good: Clear and descriptive</note>
test_userRegistration_withExistingEmail_returnsError
<note>Bad: Unclear purpose</note>
test_user_reg_1
</example>
</practice>
<practice priority="high">
<name>One assertion per concept</name>
<description>Each test should verify one logical concept</description>
<example>
<note>Good: Single concept</note>
test_userCreation_setsDefaultRole
user = create_user
assert_equal "member", user.role
end
<note>Avoid: Multiple unrelated assertions</note>
test_userCreation
user = create_user
assert_equal "member", user.role
assert_not_nil user.email
assert_true user.active
end
</example>
</practice>
<practice priority="medium">
<name>Use test fixtures and factories</name>
<description>Extract common test data setup</description>
<example>
<note>Create reusable test data</note>
def create_test_user(overrides = {})
defaults = {
name: "Test User",
email: "[email protected]",
role: "member"
}
User.new(defaults.merge(overrides))
end
</example>
</practice>
<practice priority="medium">
<name>Avoid magic numbers</name>
<description>Use named constants for test values</description>
<example>
<good_example>Good</good_example>
VALID_USER_AGE = 25
MINIMUM_AGE = 18
test_userValidation_withValidAge_succeeds
user = User.new(age: VALID_USER_AGE)
assert user.valid?
end
<bad_example>Bad</bad_example>
test_userValidation_withValidAge_succeeds
user = User.new(age: 25)
assert user.valid?
end
</example>
</practice>
<practice priority="medium">
<name>Test corner cases</name>
<description>Test unusual combinations and scenarios</description>
<example>
Concurrent access, timezone edge cases, leap years, DST transitions
</example>
</practice>
</best_practices>
<anti_patterns> <avoid name="testing_implementation"> <description>Testing implementation details instead of behavior</description> <instead>Focus on testing observable behavior and outcomes, not internal implementation details. Test what the code does, not how it does it.</instead> </avoid>
<avoid name="excessive_mocking"> <description>Over-mocking dependencies throughout test suites</description> <instead>Use real implementations where practical; excessive mocking often indicates poor design. Only mock external dependencies or slow operations.</instead> </avoid> <avoid name="flaky_tests"> <description>Tests that sometimes pass and sometimes fail</description> <instead>Ensure tests are deterministic by controlling time, randomness, and async operations. Use fixed timestamps, seeded random generators, and proper async handling.</instead> </avoid> <avoid name="slow_tests"> <description>Tests that take too long to run</description> <instead>Use unit tests for fast feedback; reserve slow integration/e2e tests for critical paths. Unit tests should run in milliseconds, not seconds.</instead> </avoid> <avoid name="test_interdependence"> <description>Tests that depend on execution order or shared state</description> <instead>Make each test independent with proper setup/teardown and isolated state. Each test should create its own test data.</instead> </avoid> </anti_patterns> <rules priority="standard"> <rule>Aim for high coverage but prioritize meaningful tests over coverage numbers</rule> <rule>80%+ coverage is a good target for critical code paths</rule> <rule>100% coverage does not guarantee bug-free code</rule> <rule>Focus on testing behavior, not achieving coverage metrics</rule> </rules><error_escalation> <level severity="low"> <example>Minor coverage gap in non-critical path</example> <action>Note in report, proceed</action> </level> <level severity="medium"> <example>Test flakiness detected</example> <action>Document issue, use AskUserQuestion for clarification</action> </level> <level severity="high"> <example>Critical path lacks test coverage</example> <action>STOP, present options to user</action> </level> <level severity="critical"> <example>Tests reveal security vulnerability</example> <action>BLOCK operation, require explicit user acknowledgment</action> </level> </error_escalation>
<constraints> <must>Follow project test patterns</must> <must>Run tests after creation</must> <must>Cover critical paths first</must> <avoid>Creating tests without understanding implementation</avoid> <avoid>Writing flaky or non-deterministic tests</avoid> <avoid>Ignoring existing test conventions</avoid> </constraints><related_skills> <skill name="requirements-definition">Use to define test requirements and acceptance criteria</skill> <skill name="execution-workflow">Use to implement tests as part of feature development workflow</skill> <skill name="investigation-patterns">Use when debugging test failures or flaky tests</skill> </related_skills>
tools
This skill should be used when the user asks to parse, search, grep, query, filter, or extract headings, sections, tasks, code blocks, links, or tables from Markdown files. Use when working with mdq, jq-style Markdown querying, section extraction, checklist validation, CI task scripts, or documentation automation pipelines.
development
Practical SBCL (Steel Bank Common Lisp) operations guide. Use this skill whenever the user mentions SBCL execution/debugging, --script usage, REPL workflows, backtraces, ASDF loading, save-lisp-and-die, profiling, or SLY-based Common Lisp development.
tools
Context7 MCP documentation retrieval patterns for up-to-date library and API references. Use this skill whenever current library docs, API signatures, version-specific behavior, or migration notes are needed.
development
Patterns for output formats, reflection checkpoints, agent references, and self-evaluation shared across agents and commands.