@boopkit/cap-testing 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Agent skills plus a minimal Jest + ts-jest scaffold. The scaffold is intentional
|
|
|
12
12
|
|
|
13
13
|
Copied into your project on install:
|
|
14
14
|
|
|
15
|
-
- `jest.config.js` — ts-jest preset, Node test environment, test matcher at `tests/**/*.test.ts`
|
|
15
|
+
- `jest.config.js` — ts-jest preset, Node test environment, test matcher at `tests/**/*.test.ts`, and the worker settings the suite runs under (`maxWorkers: 4`, `workerIdleMemoryLimit: '500MB'`). Those two spread test files across a pool of worker processes Jest recycles as they grow, so a long suite's memory stays bounded instead of climbing until it dies. They live in the config rather than in the `test` script so that focused runs — `npx jest tests/foo.test.ts` — inherit them too. Because files now run concurrently, tests must namespace whatever they create; drop `maxWorkers` to 1 if a suite is not isolation-safe yet.
|
|
16
16
|
- `tsconfig.test.json` — extends your project tsconfig and includes `tests/`
|
|
17
17
|
- `tests/app.test.ts` — a starter test asserting the Express app boots and has body parsing wired
|
|
18
18
|
|
|
@@ -20,7 +20,7 @@ Copied into your project on install:
|
|
|
20
20
|
|
|
21
21
|
| Script | Command |
|
|
22
22
|
|--------|---------|
|
|
23
|
-
| `test` | `jest
|
|
23
|
+
| `test` | `jest` |
|
|
24
24
|
| `test:watch` | `jest --watch` |
|
|
25
25
|
|
|
26
26
|
### Skills installed
|
|
@@ -48,7 +48,7 @@ Copied into `skills/` on install:
|
|
|
48
48
|
Run the suite:
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
npm test # full suite
|
|
51
|
+
npm test # full suite
|
|
52
52
|
npm run test:watch # watch mode
|
|
53
53
|
```
|
|
54
54
|
|
package/capability.json
CHANGED
package/package.json
CHANGED
package/scaffold/jest.config.js
CHANGED
|
@@ -6,4 +6,28 @@ module.exports = {
|
|
|
6
6
|
transform: {
|
|
7
7
|
'^.+\\.ts$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }],
|
|
8
8
|
},
|
|
9
|
+
|
|
10
|
+
// Run test files across a small pool of worker processes that Jest recycles.
|
|
11
|
+
//
|
|
12
|
+
// `workerIdleMemoryLimit` is the load-bearing setting and it is easy to drop
|
|
13
|
+
// by accident. Without it Jest runs every file in its own main process — never
|
|
14
|
+
// recycling it — whenever `maxWorkers <= 1`, and that process's heap grows for
|
|
15
|
+
// the whole run until a long suite dies of it. Setting a memory limit is what
|
|
16
|
+
// overrides that decision: it forces real workers and gives Jest a threshold at
|
|
17
|
+
// which to replace one. `maxWorkers` on its own does not do this, and neither
|
|
18
|
+
// did the `--runInBand` this replaced — that flag asks for exactly the
|
|
19
|
+
// un-recycled main process described above.
|
|
20
|
+
//
|
|
21
|
+
// The limit is compared against V8 `heapUsed`, not RSS, and is checked between
|
|
22
|
+
// test files. Budget for real memory use somewhat above `maxWorkers` times this
|
|
23
|
+
// number, and note that a single file exceeding it is not caught mid-flight.
|
|
24
|
+
//
|
|
25
|
+
// Four workers is a deliberate middle setting; six is comfortable on a developer
|
|
26
|
+
// machine with memory to spare. The constraint on raising it is not the machine,
|
|
27
|
+
// it is your tests: files now run CONCURRENTLY, so anything sharing a database,
|
|
28
|
+
// a fixture directory, or a well-known key with another test file will collide.
|
|
29
|
+
// Namespace what each test creates. Drop to `maxWorkers: 1` if a suite is not
|
|
30
|
+
// isolation-safe yet — that still gets you the recycling, just without overlap.
|
|
31
|
+
maxWorkers: 4,
|
|
32
|
+
workerIdleMemoryLimit: '500MB',
|
|
9
33
|
};
|
|
@@ -12,7 +12,7 @@ Red → Green → Refactor. Document "before" and "after" states.
|
|
|
12
12
|
2. **Green**: Implement the minimum change. Add any additional tests.
|
|
13
13
|
3. **Verify**: Re-run all tests from steps 1-2. Type-checking alone is **not sufficient** — functional tests must pass. Check for regressions in related functionality. Verify from the user's perspective — don't just test internal state. For example, if the feature writes files the user interacts with, verify those files exist and are correct.
|
|
14
14
|
|
|
15
|
-
Test tools: `npm
|
|
15
|
+
Test tools: `npm test` for the whole suite, `npx jest <path>` for a focused run. Go through `npm test` rather than the runner binary when you want the suite — the script and `jest.config.js` together carry the settings the suite is tuned for, including how many files run at once and how much memory a worker may hold before Jest replaces it, and a bare runner invocation drops whatever lives only in the script. The general testing skill explains why those settings matter and which of them is load-bearing. If the project defines its own test commands beyond these, its `package.json` is the authority. For UI changes, coordinate manual browser testing.
|
|
16
16
|
|
|
17
17
|
## Picking the right test shape
|
|
18
18
|
|
|
@@ -58,6 +58,30 @@ A skip carrying neither a ticket reference nor a `SKIP-OK:` reason is a conventi
|
|
|
58
58
|
|
|
59
59
|
---
|
|
60
60
|
|
|
61
|
+
## Which tests to run, and when
|
|
62
|
+
|
|
63
|
+
**The rule.** A change runs the focused tests for what it touched, plus the project's whole-program static check. The full suite runs once per branch, on the work that completes it. The `boop-project-mgmt-beads-planning` skill carries the canonical wording to put on issues; this section is the reasoning behind it, and the two have to keep agreeing.
|
|
64
|
+
|
|
65
|
+
**Why the whole suite is the wrong tool mid-change.** The problem is localization, first and foremost. Break a shared dependency and the suite reports it as a cascade of failures in tests that never mention the thing you changed, and you are then reading a wall of red to reconstruct a fact the type-checker would have told you outright, naming a file and a line. A static check plus a search for callers answers "does everything that uses this still hold?" both faster and more precisely than the suite does.
|
|
66
|
+
|
|
67
|
+
Second, it is slower than the focused run, though see the caution below about how much weight that carries.
|
|
68
|
+
|
|
69
|
+
Third, a suite already red for an unrelated reason gives you nothing to compare against, so mid-change runs on a red tree get retried and re-read rather than acted on.
|
|
70
|
+
|
|
71
|
+
**Do not rest the rule on the suite being slow.** A suite's wall-clock time is a property of how the runner is invoked as much as of the tests themselves, and it can fall by an order of magnitude on a single configuration change — running the files in a recyclable worker pool rather than in one long-lived process is the common case. A rule argued from "the suite takes tens of minutes" quietly expires the day somebody fixes the runner, and then it reads as superstition. Argue it from instrument fit, which does not expire.
|
|
72
|
+
|
|
73
|
+
**What we have not measured.** Nobody has measured how often a focused-tests-only run misses a break that the full suite would have caught, weighed against the time the narrow runs save. Until somebody does, this rule rests on the shippable-unit argument and on instrument fit, and on nothing else. That is worth stating plainly rather than dressing up.
|
|
74
|
+
|
|
75
|
+
### Go through the project's test script, not a bare runner invocation
|
|
76
|
+
|
|
77
|
+
Run the suite the way the project defines it — `npm test` — rather than reaching past it to the runner binary. The script and the runner's config file together carry the settings the suite is tuned for: how many files run at once, and how much memory a worker may hold before the runner replaces it. A bare `npx jest` picks up the config file but drops anything that lives only in the script.
|
|
78
|
+
|
|
79
|
+
Those settings are not decoration. With Jest specifically, `--maxWorkers=1` **does nothing on its own** — Jest runs every file in its own main process, and never recycles it, whenever `maxWorkers <= 1`. Setting `workerIdleMemoryLimit` is what forces a real worker process and gives Jest a threshold at which to replace it; it is the load-bearing setting, and a long suite that grows its heap until it dies is what its absence looks like. Anyone "simplifying" the two settings down to the worker cap has restored the bug.
|
|
80
|
+
|
|
81
|
+
Keep those settings in the runner's config file rather than in the `test` script, so that the focused runs this section asks for inherit them too. `boop add testing` scaffolds them that way, at four workers and a 500MB per-worker ceiling.
|
|
82
|
+
|
|
83
|
+
**A worker pool makes test isolation a requirement, not a nicety.** More than one worker means test *files* run at the same time, in separate processes, against the same backing services. Anything two files share and do not namespace — a table one of them truncates in setup, a fixture directory, a well-known key or account id — is now a race, and it surfaces as a suite that passes alone and fails in a full run. That is the same symptom the shared-dev-database section below describes, reached by a different route, and it invites the same wrong fix of weakening the assertion that caught it. Namespace what each test creates. Where a suite is not isolation-safe yet, set `maxWorkers: 1`: that keeps the recycling, which is the part that fixes the memory, and gives up only the overlap.
|
|
84
|
+
|
|
61
85
|
## Integration tests never touch the shared dev database
|
|
62
86
|
|
|
63
87
|
A test or migration that needs a real database must not run against the checkout's inherited connection string.
|
|
@@ -197,4 +221,4 @@ When code produces a schema or structure that is validated by an external system
|
|
|
197
221
|
## References
|
|
198
222
|
|
|
199
223
|
- [development.skill.md](development.skill.md) — Light TDD Flow, completion criteria
|
|
200
|
-
- [jest.config.js](
|
|
224
|
+
- [jest.config.js](../../jest.config.js) — Jest configuration, at the project root this capability installs it to
|
|
@@ -20,6 +20,8 @@ npx jest tests/services/foo --no-coverage # Pattern match
|
|
|
20
20
|
npx jest tests/services/foo.test.ts -t "handles replay" # By test name
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
The focused forms are safe to reach for: the concurrency and per-worker memory settings live in `jest.config.js`, not in the `test` script, so `npx jest <path>` runs under the same settings the full suite does. Which of these you should be running on a given piece of work is a separate question — see "Which tests to run, and when" in the parent skill.
|
|
24
|
+
|
|
23
25
|
**Prerequisites**: integration tests run against the project's real backing services rather than mocks, so whatever the app talks to at runtime — the database first of all — has to be reachable from the machine running the tests. Which services those are depends on the capabilities the project has installed; its README and environment template are the authority.
|
|
24
26
|
|
|
25
27
|
## Test File Layout
|