qa-automationlisted
Install: claude install-skill alex-macra/claude-codex-skills-assembly
# QA automation
## What "test" means here
- **Unit**: pure functions or single classes, no I/O, no network, no clock.
- **Integration**: real dependencies (db, fs, queue) inside the process. Mocks at the system boundary only.
- **E2E**: real running app, hit through its public interface (HTTP, browser, CLI). Covered in the `e2e-qa` skill.
Pick the cheapest level that catches the bug. Most coverage should be unit; a thin layer of integration; a few critical E2E flows. Inverted pyramid = slow, flaky CI.
## Writing a test
- Arrange / Act / Assert structure. One concept per test. If the test name needs "and," it's two tests.
- Test the behavior, not the implementation. "Renders the user's name" beats "calls `formatName()` once."
- Public API only. Don't reach into private state to assert.
- Names describe the scenario AND the expected outcome: `returns_400_when_email_missing`, not `test_email_validation`.
- Fixtures over `beforeEach` setup magic. Explicit data in the test body wins for readability when small.
## Mocks vs reals - the heuristic
- Database, filesystem, in-process queue: use the real thing (sqlite-in-memory, tmp dir, in-memory queue). Fast and faithful.
- HTTP to your own service: real, in a test harness.
- HTTP to a third party: stub at the boundary (`nock`, `respx`, `MSW`). Record real responses once; replay forever.
- Time: inject a clock or use `vi.useFakeTimers()` / `freezegun` / `time-machine`. Never `await sleep(100)` to "wait for" something.
- Randomness: