Skip to content

Commit a59a51f

Browse files
authored
chore: add agent skills for unit and API e2e tests (CM-968) (#4402)
Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
1 parent 1c20cc5 commit a59a51f

4 files changed

Lines changed: 165 additions & 0 deletions

File tree

.claude/rules/skill-guidance.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ This project has guided skills for common workflows. **Proactively suggest the r
1818
| `/scaffold-snowflake-connector` | Add a new Snowflake-connector data source or integration |
1919
| `/packages-worker-setup` | First-time setup of packages-db and github-repos-enricher for a new engineer |
2020
| `/packages-worker-add-entrypoint` | Scaffold a new sibling worker inside packages_worker (npm, OSV, scorecard, etc.) |
21+
| `/write-unit-tests` | Add or improve Vitest unit tests for business logic, DAL, or server modules |
22+
| `/write-api-e2e-tests` | Add or change Public API e2e / smoke / contract tests |
2123

2224
## Trigger Phrases
2325

@@ -57,3 +59,14 @@ This project has guided skills for common workflows. **Proactively suggest the r
5759
- "Add a new packages worker", "scaffold a sibling worker", "new entry point in packages_worker"
5860
- "Add npm ingestion", "add OSV worker", "add scorecard runner"
5961
- Any request to create a new `src/bin/*.ts` worker inside `packages_worker`
62+
63+
**`/write-unit-tests`** — match any of these intents:
64+
- "Write unit tests", "add a unit test", "cover this with Vitest"
65+
- "Test this function", "add DAL tests", "unit test for affiliations/merges/inference"
66+
- Any request for focused server/unit test coverage (not HTTP/API contract tests)
67+
- Not for `packages_worker` (excluded from `pnpm test:server` for now)
68+
69+
**`/write-api-e2e-tests`** — match any of these intents:
70+
- "Write API e2e tests", "add smoke tests", "Public API contract tests"
71+
- "Cover this endpoint end-to-end", "API regression test"
72+
- Any request for HTTP/API e2e coverage of Public API behaviour
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
name: write-api-e2e-tests
3+
description: >
4+
Write API end-to-end tests. Use when adding or changing API endpoints, or when
5+
the user asks for API e2e, smoke, or contract tests.
6+
allowed-tools: Bash, Read, Glob, Grep, Edit, Write, AskUserQuestion
7+
---
8+
9+
# Write API end-to-end tests
10+
11+
Write or extend API end-to-end tests.
12+
13+
## When to use
14+
15+
- New or changed API endpoints.
16+
- User asks for API e2e, smoke, or contract tests.
17+
- Critical API behaviour needs regression coverage.
18+
19+
## When not to use
20+
21+
- Domain or SQL correctness → use `write-unit-tests`.
22+
- Temporal, OpenSearch, or other eventual side effects outside the documented API e2e scope.
23+
- Creating a new testing framework or suite style.
24+
25+
## Source of truth
26+
27+
Read before writing. Follow these ADRs and existing suite structure; do not
28+
invent a parallel testing style.
29+
30+
- [ADR-0012](../../../docs/adr/0012-api-e2e-test-architecture.md) — runtime, isolation, supported surfaces, scope, and assertions.
31+
- [ADR-0013](../../../docs/adr/0013-api-e2e-test-suite-design.md) — suite organisation, helpers, and conventions.
32+
33+
Current default entrypoint:
34+
35+
- `.github/scripts/public-api-e2e-tests.sh`
36+
37+
## Workflow
38+
39+
1. Identify the API surface. Default to Public API unless the user specifies otherwise.
40+
2. Read ADR-0012 and ADR-0013.
41+
3. Add or extend the appropriate suite and register it if required.
42+
4. Run the affected suite locally and fix failures until green.
43+
5. If required fixtures cannot be created through the API, prefer testing supported scenarios and explain any coverage gaps instead of seeding the database directly.
44+
6. Suggest production testability improvements only when they make the API easier to test, and ask before changing production code.
45+
46+
## Run
47+
48+
Export the environment variables required by the suite entrypoint.
49+
50+
```bash
51+
bash .github/scripts/public-api-e2e-tests.sh
52+
```
53+
54+
Refer to ADR-0012 and the suite entrypoint for environment setup, reset behaviour,
55+
and local development workflows.
56+
57+
## Guardrails
58+
59+
- Keep tests focused on observable API behaviour.
60+
61+
## Output
62+
63+
- Suites and cases added
64+
- How to re-run
65+
- Coverage gaps, if any
66+
- Optional testability suggestions
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
name: write-unit-tests
3+
description: >
4+
Write focused Vitest unit tests. Use when adding or improving unit tests for
5+
business logic, data access, common services, or other server modules.
6+
allowed-tools: Bash, Read, Glob, Grep, Edit, Write, AskUserQuestion
7+
---
8+
9+
# Write unit tests
10+
11+
Write focused unit tests that follow the project's testing conventions.
12+
13+
## When to use
14+
15+
- User asks to add or improve unit tests.
16+
- A change touches high-blast-radius logic (affiliations, merges, identity resolution, timelines, inference).
17+
- A PR needs confidence in a pure or Postgres-backed function.
18+
19+
## When not to use
20+
21+
- Public or HTTP contract coverage → use `write-api-e2e-tests`.
22+
- `packages_worker` (excluded from `pnpm test:server` for now; own vitest/packages-db).
23+
- Temporal, Redis, or OpenSearch fixtures (not available yet).
24+
- Broad "increase coverage %" requests without a clear unit under test.
25+
26+
## Source of truth
27+
28+
Read before writing. Follow these ADRs; do not invent a parallel testing style.
29+
30+
- [ADR-0008](../../../docs/adr/0008-how-we-write-unit-tests.md) — scenarios, `describe` grouping, assertions, mocking, and shared setup.
31+
- [ADR-0007](../../../docs/adr/0007-test-factory-primitives-and-defaults.md) — factories and defaults.
32+
33+
## Workflow
34+
35+
1. Identify the unit under test (one function or decision path). Colocate tests as `<file>.test.ts`.
36+
2. Read ADR-0007 and ADR-0008. Skim the nearest existing test in the same area if one exists.
37+
3. Compose fixtures using `@crowd/test-kit` (`withQx` for Postgres-backed tests; factories and opt-in defaults per ADR-0007).
38+
4. Write focused scenarios following ADR-0008 (grouping, naming, assertions, and mocking).
39+
5. Run the affected tests and fix failures until green.
40+
6. If production code is difficult to test, suggest a small testability seam and ask before changing production code.
41+
42+
## Run
43+
44+
Start the test database when needed:
45+
46+
```bash
47+
./scripts/cli scaffold up-test
48+
```
49+
50+
Run a focused test file:
51+
52+
```bash
53+
pnpm test:server -- path/to/file.test.ts
54+
```
55+
56+
Optional:
57+
58+
```bash
59+
pnpm test:changed
60+
pnpm test:watch -- path/to/file.test.ts
61+
```
62+
63+
## Guardrails
64+
65+
- Prefer critical behaviours over trivial getters, setters, and thin wrappers.
66+
- Keep production behaviour unchanged unless the user explicitly asks for a testability improvement.
67+
68+
## Output
69+
70+
- Scenarios covered
71+
- How to re-run
72+
- Optional testability suggestions

docs/adr/0008-how-we-write-unit-tests.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ reuse is real.
2525
- Setup should make that story obvious (concrete labels, dates, relationships).
2626
- Do not combine unrelated behaviors in a single test.
2727
- Prefer fewer tests that fail clearly over many that pass for the wrong reason.
28+
- When a file covers more than one function, group cases with
29+
`describe('<functionName>', …)` and put named scenarios inside.
2830

2931
### Assertions
3032

@@ -33,6 +35,18 @@ reuse is real.
3335
- Avoid loose probes (`some`, `greaterThan`, optional finds) unless the claim
3436
truly is approximate.
3537

38+
### Mocking
39+
40+
- Do not mock the data-access layer or the unit under test. Postgres-backed
41+
tests use a real test database and factories; query behavior is part of what
42+
we ship.
43+
- Reach for mocks only at external network boundaries where the real dependency
44+
would hurt reliability or speed (outbound HTTP, LLM clients, Slack/email
45+
senders, Auth0 JWKS in end-to-end tests).
46+
- Control non-determinism in-process when needed (e.g. fake timers for “now”).
47+
- If a test seems to need a mock outside that list, the unit is often too large:
48+
extract the pure part, unit-test it, and let the outer path stay real.
49+
3650
### What to share
3751

3852
| Layer | Where | Belongs |

0 commit comments

Comments
 (0)