Files
upstream-atomic-crm/.claude/rules/testing.md
upstream-mirror 93ecc1a6f8
Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
snapshot of https://github.com/marmelab/atomic-crm.git (main, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:48:50 +05:00

79 lines
2.9 KiB
Markdown

---
paths: []
---
# Testing
## Minimum coverage: 80%
New code paths without tests are a blocking issue in code review. But coverage is a
FLOOR, not a target: never write a test just to reach the number (that is what produces
filler tests). Pertinence outranks the percentage.
## Pertinence: test behavior, not implementation
- Assert user-observable behavior / rendered output (Testing Library principle: "the more
your tests resemble the way the software is used, the more confidence they give"). Never
assert internal state, props, private methods, or merely that a mock was called.
- Weight toward integration for this React app (the Testing Trophy): a component with its
real collaborators over many shallow unit tests. Never test the framework or a third-party
library.
- Delete a test ONLY for lack of intrinsic value (cannot name a realistic bug it would catch,
tautological, implementation-detail, snapshot-only, redundant with a better test), NEVER
because "the code works now" or to cap the count: a passing test exists to guard FUTURE
regressions. Shrink the suite by CONSOLIDATING redundancy, not by deleting coverage.
- Forbidden (blocking in review): asserting a mock returns its configured value; a snapshot
as the primary assertion; reading component state / props / internals; a test written only
to raise the coverage number.
## TDD orientation: acceptance-test-driven
- Derive each test from the ticket's `acceptance_criteria`; every test should map to a
criterion or a user-visible behavior. A test with no traceable criterion is filler.
- Enforce the OUTCOME (behavior tests present and green), not literal red-green ordering
(unverifiable when one agent writes both the test and the code).
## Test structure — AAA pattern
Prefer Arrange-Act-Assert for all tests:
test('calculates similarity correctly', () => {
// Arrange
const input = buildInput()
// Act
const result = compute(input)
// Assert
expect(result).toBe(expected)
})
## Test naming
Use descriptive names that explain the behavior under test:
- returns empty array when no items match the query
- throws error when required field is missing
- falls back to default value when API is unavailable
Avoid: test1, testFoo, should work.
## Test isolation
Each test must be independent — no shared mutable state.
No test should depend on the execution order of other tests.
Reset mocks and fixtures in beforeEach, not globally.
## E2E shape (Playwright)
import { test, expect } from '@playwright/test'
test('ticket list loads', async ({ page }) => {
await page.goto('/tickets')
await expect(page.locator('h1')).toBeVisible()
})
Never use timeout-based assertions (waitForTimeout).
Always prefer deterministic waits: waitForResponse, waitForSelector,
expect(locator).toBeVisible(). Flaky tests must be quarantined with
test.fixme() and a tracking reference before merge.