test-best-pratice
Goal
Write tests with a high signal-to-noise ratio:
- Fail when something is actually wrong, and do not fail randomly when nothing is wrong.
- Make it easy to locate the cause after a failure.
- Require minimal changes when internal implementation is refactored.
- Run fast enough for daily development and CI.
- Stay maintainable over time instead of becoming team overhead.
This skill is not tied to any specific framework. It can be used for unit tests, integration tests, API tests, component tests, and end-to-end tests.
Core Principles
1. The goal of testing is to build confidence, not to chase coverage
Ask first:
- What are the most important user scenarios for this code?
- Which paths would cause the greatest business impact if they broke?
- Which edge cases are most likely to produce bugs?
Do not start with “I need to test every function and every branch.” Start with use cases. Coverage can be a useful signal, but it cannot replace judgment about test value.
2. Test behavior and contracts, not implementation details
Prefer testing:
- Public API behavior
- User-observable outcomes
- Input/output contracts between modules
- Whether critical side effects happen, such as database writes, message dispatch, or state changes
Avoid directly testing:
- Private methods
- Internal state layout
- Temporary variables
- Component internals
- Assertions written only to fit the current implementation
Principle: implementations may be refactored, but contracts should not change casually.
3. Choose the smallest test that gives enough confidence
Test size is not “smaller is always better” or “bigger is always better.” Choose the cheapest layer that gives enough confidence.
Default decision order:
- If a unit test can verify it reliably, do not jump to UI or E2E.
- If you need to verify collaboration between modules, prefer an integration test.
- Use a small number of end-to-end tests only for high-value flows such as payments, login, or submission.
Remember: a large number of slow, brittle high-level tests is worse than a well-layered test suite.
4. Stability matters more than “it looks like we tested a lot”
A flaky test destroys trust in the test suite.
Actively control anything that introduces instability:
- Time
- Time zone
- Randomness
- Network jitter
- Third-party services
- Test execution order
- Shared state across tests
- Uncertain async timing
5. A test is both documentation and an alarm
A high-quality test should make it obvious, from its name and assertions alone:
- What guarantee this feature provides
- Which edge case or historical pitfall it protects against
- Which business rule has been broken when it fails
So tests should first be clear, and only then “beautifully abstract.”
When to Use
Use this skill when you need to:
- Add tests for a new feature
- Write regression tests for a bug fix
- Build a safety net before refactoring
- Define behavioral contracts for shared modules
- Verify APIs, components, pages, or workflows reliably
- Clean up flaky tests or low-value tests
Output Standards
A finished test should satisfy these standards as much as possible:
- Clear purpose: every test should answer “what does this protect?”
- Single failure reason: a failure should not leave people guessing.
- Independent execution: it should pass alone and in random order.
- Repeatability: the same commit should produce the same result in the same environment.
- Readability: names, data, and assertions should be easy to understand.
- Maintainability: refactoring internals should not require broad test rewrites.
- Reasonable speed: tests should be fast by default; slow tests need a strong reason.
Workflow
Step 1: Identify the test target and the risk
Before writing a test, clarify:
- What is the target: function, module, API, component, page, or workflow?
- What is its external contract?
- What is the main success path?
- What are the main failure paths?
- Where are the high-risk edges?
- How expensive is failure?
Prioritize coverage for:
- Core success paths
- Boundary conditions most likely to fail
- Previously reported bugs
- Critical rules that refactors could easily break
Step 2: Choose the test layer
Use the following guidance:
Unit tests
Good for:
- Pure functions
- Rule evaluation
- Data transformation
- Validation logic
- Sorting, filtering, aggregation
- Single-step state-machine behavior
Characteristics:
- Fast
- Stable
- Precise diagnosis
- Low cost
Do not use them to verify:
- Real collaboration across many modules
- UI interaction flows
- Real network or database integration
Integration tests
Good for:
- Service and database collaboration
- Combined behavior across modules
- API routes with middleware and persistence
- Components working with state management or the data layer
Characteristics:
- More realistic than unit tests
- Higher confidence
- Moderate cost
They are often high leverage because they balance realism and maintenance cost well.
End-to-end tests (E2E)
Good for:
- Login
- Registration
- Checkout and payment
- Form submission
- Critical business flows
- Cross-page workflows
Characteristics:
- Closest to the user
- Most expensive, slowest, and easiest to make brittle
Strategy:
- Cover only a small number of critical happy paths
- Do not use E2E as a substitute for lower-level tests
Step 3: Turn scenarios into a test checklist
For every test target, list at least:
- Valid input
- Boundary input
- Invalid input
- Null or missing values
- Duplicate or conflicting input
- Insufficient permissions
- Timeout, failure, or exception paths
- Idempotency, if relevant
- Sorting, pagination, precision, and time zone, if relevant
Do not start coding immediately. List scenarios first.
Step 4: Design test data
Test data should be:
- Minimal, containing only what the test needs
- Semantically clear, so the purpose is obvious from the name
- Free from magic numbers and meaningless strings
- Explicit rather than implicitly reused
Prefer:
- Factory functions
- Fixtures
- Builders
- Clearly named test samples
Avoid:
- Oversized shared test datasets
- “Universal” objects created only for reuse
- Implicit dependence on a global seed database
Step 5: Write tests in AAA structure
Recommended structure:
- Arrange: prepare inputs, dependencies, and initial state
- Act: execute one core action
- Assert: verify externally visible results
Constraints:
- A test should usually perform only one core action
- Do not scatter assertions everywhere
- If there are too many assertions, check whether the scope is too large
Step 6: Prefer meaningful assertions
Characteristics of good assertions:
- They assert business outcomes rather than procedural noise
- They are easy to understand when they fail
- They are strongly tied to the purpose of the test
Prefer asserting:
- Return values and output structure
- Persisted results
- User-visible text and state
- Clear error types and messages
- Required side effects
Avoid:
- Meaningless “object exists” assertions
- Low-value assertions such as “the page rendered”
- Assertions about intermediate steps that are irrelevant to the business outcome
Step 7: Handle external dependencies
Use real collaboration when practical; do not mock by reflex
For collaboration between modules you control, prefer assembling the real pieces and testing them together. Only consider mocks or stubs when the dependency is:
- Unstable
- Slow
- Expensive
- Hard to construct
- Uncontrollable
- Side-effectful, such as sending real SMS or charging money
Mock boundaries
Good places to mock:
- Third-party payment services
- SMS or email services
- Cloud storage
- External HTTP APIs
- Slow dependencies that are irrelevant to the current test
Do not over-mock:
- Large parts of your own internal system
- Everything, just to make the test easier to write
Rule of thumb: mock at the system boundary, not across the entire inside of the system.
Step 8: Control stability
Eliminate these sources of non-determinism whenever possible:
- Freeze the clock or inject a time source
- Fix the random seed
- Create state explicitly before each test and do not rely on someone else to clean up
- Avoid leftover shared database state
- Avoid dependence on execution order
- Do not call real third-party networks
- Do not use arbitrary sleeps or waits
Waiting strategy:
- Wait for a clear condition
- Wait for an element to become visible, text to appear, a request to finish, or state to be persisted
- Do not write “wait 2 seconds and see”
Step 9: Check whether the test is brittle
After writing the test, ask:
- If I refactor the internals without changing behavior, will this test fail for no good reason?
- If the execution order changes, will this test break?
- If the network or machine is slightly slower, will this test break?
- If the UI copy or DOM structure changes slightly, will this test trigger mass failures?
- If this test fails, can I know the rough cause within one minute?
If the answers are poor, improve the test.
Specific Rules by Test Type
A. Unit test best practices
- Prefer testing pure logic and boundary conditions.
- Test the public API, not private methods.
- Each test should protect one rule.
- Use parameterized tests for similar input families.
- Test error paths too, and assert error type or key message.
- Name tests as “scenario + expected result.”
- Do not turn the test into another complicated business program.
- Avoid using real databases or networks in unit tests.
Good naming style
returns_discounted_price_for_vip_user
rejects_empty_email
keeps_original_order_when_scores_are_equal
B. Integration test best practices
- Cover key collaboration paths, not every possible combination.
- Prefer real assembly, mocking only external boundaries.
- Manage the lifecycle of test data carefully.
- For databases, use controlled schema setup, cleanup, transaction rollback, or temporary instances.
- Assert side effects clearly for queues, caches, and file systems.
- In API tests, verify status code, response body, persisted results, and permission constraints together.
C. UI and component test best practices
- Query elements from the user’s perspective, preferring role, label, and text.
- Do not depend on class names, DOM hierarchy, or
nth-child unless necessary.
- Avoid testing only “it renders”; test real interaction and outcomes.
- Assert user-visible state changes, not component internals.
- After interactions, wait for a clear result instead of sleeping.
- Accessible UI is usually easier to test reliably.
Recommended query priority
Prefer:
- role
- label text
- placeholder text
- visible text
Use only as a fallback:
D. E2E best practices
- Keep them few and high value.
- Protect only critical main flows, not every branch.
- Every test must be independent and must not depend on earlier tests.
- Manage login state, test accounts, and seed data explicitly.
- Wait for system state, not fixed time.
- Use stable selectors that align with user semantics.
- Do not validate every detail in E2E.
- Preserve enough diagnostic information on failure: logs, screenshots, traces, HAR files, and error responses.
Flaky Test Handling Rules
If a test sometimes passes and sometimes fails on the same code, investigate in this order:
- Is it using arbitrary sleep or wait?
- Does it depend on execution order or shared state?
- Does it depend on the real network or third-party services?
- Is the assertion happening too early?
- Is the selector too brittle?
- Is there a problem with time, time zone, or randomness?
- Is the scope too large, mixing several possible failure sources?
Treatment principles:
- Fix it first; do not normalize rerunning.
- If it cannot be fixed immediately, isolate it temporarily and record the reason.
- Do not tolerate flaky tests sitting on the main branch long term.
Coverage Strategy
Do not focus only on code coverage numbers. Care more about these forms of coverage:
- Use-case coverage
- Risk coverage
- Boundary coverage
- Permission coverage
- Exception-path coverage
- Regression coverage
Recommended priority:
- Core main flows
- High-risk edges
- Regression tests for historical bugs
- Permission and security logic
- Contracts likely to break during refactors
Maintainability Rules
Tests should be DAMP, not excessively DRY
Some duplication in tests is acceptable if it makes intent clearer.
Prefer:
- Clear readability
- Explicit data
- Independent scenarios
Abstract carefully:
- Extract helpers only when the repetition is truly stable and improves understanding
- Do not hide test data, test behavior, and assertions inside black-box helpers
Rule of thumb:
If the abstraction forces the reader to jump through many layers just to understand what the test does, the abstraction has probably gone too far.
Test failures should be diagnosable
When an assertion fails, it should ideally show:
- The expected value
- The actual value
- The current scenario
- The key inputs
When needed, also provide:
- Request and response snapshots
- Database state summaries
- Page screenshots
- Traces or logs
Anti-Patterns
Common bad smells:
- Writing tests only for coverage numbers
- Testing private implementation details
- Using lots of fixed sleep or wait calls
- Tests depending on one another
- Sharing dirty data or shared account state
- Too many actions and intentions inside a single test
- Assertions that only check “exists” or “does not throw”
- Too many E2E tests and too few unit or integration tests
- Mocking everything until the test no longer reflects the real system
- Over-abstracted helpers that hide test intent
- Vague names such as
should work
- Fixing a bug without adding a regression test
- Rerunning flaky tests instead of finding the root cause
Recommended Working Templates
Template 1: Writing tests for a new feature
- List the core use cases
- Choose the test layer
- Write the main success path first
- Add high-risk boundary cases
- Add exception paths
- Run locally multiple times to check stability
- Before merging, verify that failure messages are clear
Template 2: Writing regression tests for a bug fix
- Reproduce the bug first
- Write a failing test first
- Fix the code
- Confirm the test turns green
- Add nearby boundary cases to prevent the same class of issue from returning
Template 3: Adding tests to existing code
- Start from the clearest external contract
- Cover the most critical success path first
- Then add the most fragile boundaries
- Avoid diving into private internals at the beginning
- If the code is hard to test, record the design smell and refactor in small steps
Expected Output
When using this skill to produce tests, the default output should include:
Test strategy explanation
- Why this test layer was chosen
- Which scenarios are covered
- Which scenarios are intentionally not covered, and why
Test code
- Runnable as-is
- Clearly structured
- Clearly named
Stability notes
- How flakiness is avoided
- How test data, time, randomness, and network dependencies are controlled
Follow-up suggestions
- Whether integration or E2E tests should be added later
- Whether the design could be improved to make the code more testable
Short Checklist
Before submitting, quickly check:
- Which business rule does this test protect?
- Does it test behavior or implementation details?
- Can it run independently?
- Does it rely on fixed sleep?
- Does it rely on shared state?
- If it fails, can the cause be located quickly?
- Is it worth maintaining long term?
If you cannot answer two or more of these clearly, do not submit it yet.
One-Sentence Principle
Write tests that provide real confidence. Prefer user behavior and system contracts, cover the highest-risk scenarios with the smallest sufficient test layer, and reject brittle, vague, and flaky tests.
1---2name: test-best-pratice3description: A general skill for writing high-quality automated tests. Use it to design and implement stable, maintainable, and diagnosable tests for functions, modules, APIs, components, pages, and critical business workflows.4---56# test-best-pratice78## Goal910Write tests with a **high signal-to-noise ratio**:1112- Fail when something is actually wrong, and do not fail randomly when nothing is wrong.13- Make it easy to locate the cause after a failure.14- Require minimal changes when internal implementation is refactored.15- Run fast enough for daily development and CI.16- Stay maintainable over time instead of becoming team overhead.1718This skill is not tied to any specific framework. It can be used for unit tests, integration tests, API tests, component tests, and end-to-end tests.1920---2122## Core Principles2324### 1. The goal of testing is to build confidence, not to chase coverage2526Ask first:2728- What are the most important user scenarios for this code?29- Which paths would cause the greatest business impact if they broke?30- Which edge cases are most likely to produce bugs?3132Do not start with “I need to test every function and every branch.” Start with **use cases**. Coverage can be a useful signal, but it cannot replace judgment about test value.3334### 2. Test behavior and contracts, not implementation details3536Prefer testing:3738- Public API behavior39- User-observable outcomes40- Input/output contracts between modules41- Whether critical side effects happen, such as database writes, message dispatch, or state changes4243Avoid directly testing:4445- Private methods46- Internal state layout47- Temporary variables48- Component internals49- Assertions written only to fit the current implementation5051Principle: **implementations may be refactored, but contracts should not change casually.**5253### 3. Choose the smallest test that gives enough confidence5455Test size is not “smaller is always better” or “bigger is always better.” Choose the **cheapest layer that gives enough confidence**.5657Default decision order:58591. If a unit test can verify it reliably, do not jump to UI or E2E.602. If you need to verify collaboration between modules, prefer an integration test.613. Use a small number of end-to-end tests only for high-value flows such as payments, login, or submission.6263Remember: **a large number of slow, brittle high-level tests is worse than a well-layered test suite.**6465### 4. Stability matters more than “it looks like we tested a lot”6667A flaky test destroys trust in the test suite.6869Actively control anything that introduces instability:7071- Time72- Time zone73- Randomness74- Network jitter75- Third-party services76- Test execution order77- Shared state across tests78- Uncertain async timing7980### 5. A test is both documentation and an alarm8182A high-quality test should make it obvious, from its name and assertions alone:8384- What guarantee this feature provides85- Which edge case or historical pitfall it protects against86- Which business rule has been broken when it fails8788So tests should first be **clear**, and only then “beautifully abstract.”8990---9192## When to Use9394Use this skill when you need to:9596- Add tests for a new feature97- Write regression tests for a bug fix98- Build a safety net before refactoring99- Define behavioral contracts for shared modules100- Verify APIs, components, pages, or workflows reliably101- Clean up flaky tests or low-value tests102103---104105## Output Standards106107A finished test should satisfy these standards as much as possible:1081091. **Clear purpose**: every test should answer “what does this protect?”1102. **Single failure reason**: a failure should not leave people guessing.1113. **Independent execution**: it should pass alone and in random order.1124. **Repeatability**: the same commit should produce the same result in the same environment.1135. **Readability**: names, data, and assertions should be easy to understand.1146. **Maintainability**: refactoring internals should not require broad test rewrites.1157. **Reasonable speed**: tests should be fast by default; slow tests need a strong reason.116117---118119## Workflow120121### Step 1: Identify the test target and the risk122123Before writing a test, clarify:124125- What is the target: function, module, API, component, page, or workflow?126- What is its external contract?127- What is the main success path?128- What are the main failure paths?129- Where are the high-risk edges?130- How expensive is failure?131132Prioritize coverage for:133134- Core success paths135- Boundary conditions most likely to fail136- Previously reported bugs137- Critical rules that refactors could easily break138139### Step 2: Choose the test layer140141Use the following guidance:142143#### Unit tests144Good for:145146- Pure functions147- Rule evaluation148- Data transformation149- Validation logic150- Sorting, filtering, aggregation151- Single-step state-machine behavior152153Characteristics:154155- Fast156- Stable157- Precise diagnosis158- Low cost159160Do not use them to verify:161162- Real collaboration across many modules163- UI interaction flows164- Real network or database integration165166#### Integration tests167Good for:168169- Service and database collaboration170- Combined behavior across modules171- API routes with middleware and persistence172- Components working with state management or the data layer173174Characteristics:175176- More realistic than unit tests177- Higher confidence178- Moderate cost179180They are often high leverage because they balance realism and maintenance cost well.181182#### End-to-end tests (E2E)183Good for:184185- Login186- Registration187- Checkout and payment188- Form submission189- Critical business flows190- Cross-page workflows191192Characteristics:193194- Closest to the user195- Most expensive, slowest, and easiest to make brittle196197Strategy:198199- Cover only a small number of critical happy paths200- Do not use E2E as a substitute for lower-level tests201202### Step 3: Turn scenarios into a test checklist203204For every test target, list at least:205206- Valid input207- Boundary input208- Invalid input209- Null or missing values210- Duplicate or conflicting input211- Insufficient permissions212- Timeout, failure, or exception paths213- Idempotency, if relevant214- Sorting, pagination, precision, and time zone, if relevant215216Do not start coding immediately. List scenarios first.217218### Step 4: Design test data219220Test data should be:221222- Minimal, containing only what the test needs223- Semantically clear, so the purpose is obvious from the name224- Free from magic numbers and meaningless strings225- Explicit rather than implicitly reused226227Prefer:228229- Factory functions230- Fixtures231- Builders232- Clearly named test samples233234Avoid:235236- Oversized shared test datasets237- “Universal” objects created only for reuse238- Implicit dependence on a global seed database239240### Step 5: Write tests in AAA structure241242Recommended structure:2432441. **Arrange**: prepare inputs, dependencies, and initial state2452. **Act**: execute one core action2463. **Assert**: verify externally visible results247248Constraints:249250- A test should usually perform only one core action251- Do not scatter assertions everywhere252- If there are too many assertions, check whether the scope is too large253254### Step 6: Prefer meaningful assertions255256Characteristics of good assertions:257258- They assert business outcomes rather than procedural noise259- They are easy to understand when they fail260- They are strongly tied to the purpose of the test261262Prefer asserting:263264- Return values and output structure265- Persisted results266- User-visible text and state267- Clear error types and messages268- Required side effects269270Avoid:271272- Meaningless “object exists” assertions273- Low-value assertions such as “the page rendered”274- Assertions about intermediate steps that are irrelevant to the business outcome275276### Step 7: Handle external dependencies277278#### Use real collaboration when practical; do not mock by reflex279280For collaboration between modules you control, prefer assembling the real pieces and testing them together. Only consider mocks or stubs when the dependency is:281282- Unstable283- Slow284- Expensive285- Hard to construct286- Uncontrollable287- Side-effectful, such as sending real SMS or charging money288289#### Mock boundaries290291Good places to mock:292293- Third-party payment services294- SMS or email services295- Cloud storage296- External HTTP APIs297- Slow dependencies that are irrelevant to the current test298299Do not over-mock:300301- Large parts of your own internal system302- Everything, just to make the test easier to write303304Rule of thumb: **mock at the system boundary, not across the entire inside of the system.**305306### Step 8: Control stability307308Eliminate these sources of non-determinism whenever possible:309310- Freeze the clock or inject a time source311- Fix the random seed312- Create state explicitly before each test and do not rely on someone else to clean up313- Avoid leftover shared database state314- Avoid dependence on execution order315- Do not call real third-party networks316- Do not use arbitrary sleeps or waits317318Waiting strategy:319320- Wait for a clear condition321- Wait for an element to become visible, text to appear, a request to finish, or state to be persisted322- Do not write “wait 2 seconds and see”323324### Step 9: Check whether the test is brittle325326After writing the test, ask:327328- If I refactor the internals without changing behavior, will this test fail for no good reason?329- If the execution order changes, will this test break?330- If the network or machine is slightly slower, will this test break?331- If the UI copy or DOM structure changes slightly, will this test trigger mass failures?332- If this test fails, can I know the rough cause within one minute?333334If the answers are poor, improve the test.335336---337338## Specific Rules by Test Type339340### A. Unit test best practices3413421. Prefer testing pure logic and boundary conditions.3432. Test the public API, not private methods.3443. Each test should protect one rule.3454. Use parameterized tests for similar input families.3465. Test error paths too, and assert error type or key message.3476. Name tests as “scenario + expected result.”3487. Do not turn the test into another complicated business program.3498. Avoid using real databases or networks in unit tests.350351#### Good naming style352353- `returns_discounted_price_for_vip_user`354- `rejects_empty_email`355- `keeps_original_order_when_scores_are_equal`356357### B. Integration test best practices3583591. Cover key collaboration paths, not every possible combination.3602. Prefer real assembly, mocking only external boundaries.3613. Manage the lifecycle of test data carefully.3624. For databases, use controlled schema setup, cleanup, transaction rollback, or temporary instances.3635. Assert side effects clearly for queues, caches, and file systems.3646. In API tests, verify status code, response body, persisted results, and permission constraints together.365366### C. UI and component test best practices3673681. Query elements from the user’s perspective, preferring role, label, and text.3692. Do not depend on class names, DOM hierarchy, or `nth-child` unless necessary.3703. Avoid testing only “it renders”; test real interaction and outcomes.3714. Assert user-visible state changes, not component internals.3725. After interactions, wait for a clear result instead of sleeping.3736. Accessible UI is usually easier to test reliably.374375#### Recommended query priority376377Prefer:378379- role380- label text381- placeholder text382- visible text383384Use only as a fallback:385386- test id387388### D. E2E best practices3893901. Keep them few and high value.3912. Protect only critical main flows, not every branch.3923. Every test must be independent and must not depend on earlier tests.3934. Manage login state, test accounts, and seed data explicitly.3945. Wait for system state, not fixed time.3956. Use stable selectors that align with user semantics.3967. Do not validate every detail in E2E.3978. Preserve enough diagnostic information on failure: logs, screenshots, traces, HAR files, and error responses.398399---400401## Flaky Test Handling Rules402403If a test sometimes passes and sometimes fails on the same code, investigate in this order:4044051. Is it using arbitrary sleep or wait?4062. Does it depend on execution order or shared state?4073. Does it depend on the real network or third-party services?4084. Is the assertion happening too early?4095. Is the selector too brittle?4106. Is there a problem with time, time zone, or randomness?4117. Is the scope too large, mixing several possible failure sources?412413Treatment principles:414415- Fix it first; do not normalize rerunning.416- If it cannot be fixed immediately, isolate it temporarily and record the reason.417- Do not tolerate flaky tests sitting on the main branch long term.418419---420421## Coverage Strategy422423Do not focus only on code coverage numbers. Care more about these forms of coverage:424425- Use-case coverage426- Risk coverage427- Boundary coverage428- Permission coverage429- Exception-path coverage430- Regression coverage431432Recommended priority:4334341. Core main flows4352. High-risk edges4363. Regression tests for historical bugs4374. Permission and security logic4385. Contracts likely to break during refactors439440---441442## Maintainability Rules443444### Tests should be DAMP, not excessively DRY445446Some duplication in tests is acceptable if it makes intent clearer.447448Prefer:449450- Clear readability451- Explicit data452- Independent scenarios453454Abstract carefully:455456- Extract helpers only when the repetition is truly stable and improves understanding457- Do not hide test data, test behavior, and assertions inside black-box helpers458459Rule of thumb:460461If the abstraction forces the reader to jump through many layers just to understand what the test does, the abstraction has probably gone too far.462463### Test failures should be diagnosable464465When an assertion fails, it should ideally show:466467- The expected value468- The actual value469- The current scenario470- The key inputs471472When needed, also provide:473474- Request and response snapshots475- Database state summaries476- Page screenshots477- Traces or logs478479---480481## Anti-Patterns482483Common bad smells:4844851. **Writing tests only for coverage numbers**4862. **Testing private implementation details**4873. **Using lots of fixed sleep or wait calls**4884. **Tests depending on one another**4895. **Sharing dirty data or shared account state**4906. **Too many actions and intentions inside a single test**4917. **Assertions that only check “exists” or “does not throw”**4928. **Too many E2E tests and too few unit or integration tests**4939. **Mocking everything until the test no longer reflects the real system**49410. **Over-abstracted helpers that hide test intent**49511. **Vague names such as `should work`**49612. **Fixing a bug without adding a regression test**49713. **Rerunning flaky tests instead of finding the root cause**498499---500501## Recommended Working Templates502503### Template 1: Writing tests for a new feature5045051. List the core use cases5062. Choose the test layer5073. Write the main success path first5084. Add high-risk boundary cases5095. Add exception paths5106. Run locally multiple times to check stability5117. Before merging, verify that failure messages are clear512513### Template 2: Writing regression tests for a bug fix5145151. Reproduce the bug first5162. Write a failing test first5173. Fix the code5184. Confirm the test turns green5195. Add nearby boundary cases to prevent the same class of issue from returning520521### Template 3: Adding tests to existing code5225231. Start from the clearest external contract5242. Cover the most critical success path first5253. Then add the most fragile boundaries5264. Avoid diving into private internals at the beginning5275. If the code is hard to test, record the design smell and refactor in small steps528529---530531## Expected Output532533When using this skill to produce tests, the default output should include:5345351. **Test strategy explanation**536 - Why this test layer was chosen537 - Which scenarios are covered538 - Which scenarios are intentionally not covered, and why5395402. **Test code**541 - Runnable as-is542 - Clearly structured543 - Clearly named5445453. **Stability notes**546 - How flakiness is avoided547 - How test data, time, randomness, and network dependencies are controlled5485494. **Follow-up suggestions**550 - Whether integration or E2E tests should be added later551 - Whether the design could be improved to make the code more testable552553---554555## Short Checklist556557Before submitting, quickly check:558559- Which business rule does this test protect?560- Does it test behavior or implementation details?561- Can it run independently?562- Does it rely on fixed sleep?563- Does it rely on shared state?564- If it fails, can the cause be located quickly?565- Is it worth maintaining long term?566567If you cannot answer two or more of these clearly, do not submit it yet.568569---570571## One-Sentence Principle572573> Write tests that provide real confidence. Prefer user behavior and system contracts, cover the highest-risk scenarios with the smallest sufficient test layer, and reject brittle, vague, and flaky tests.