Defer implementation until requirements stabilize and token budget allows. When ready: no Cucumber/QA ceremony; NestJS Swagger (decorators + exported swagger.json) is the live API contract; Jest specs (unit + HTTP) are AI-generated and maintained via scaffold scripts, agent rules, and a route-coverage gate. Vault openapi.yaml stays planning only.
Implementation tracker: [[Projects/anabatic-project-manager/backlog/p2-ai-first-testing-harness|p2 — AI-first testing harness]].
| Concept | Decision |
|---|---|
| BDD | Behavior naming in Jest (describe Given/When/Then, it.each tables). No .feature files, no QA-owned Gherkin workflow. |
| OpenAPI source of truth | Nest @nestjs/swagger → /api/docs/swagger.json (or build-time export). Project Manager/docs/openapi/openapi.yaml = planning / product notes only; optional manual sync from Nest export, not CI gate. |
| Who writes tests | AI on every feature (Cursor rule + templates). Human reviews diffs. |
| Who runs tests | Developer + CI + agent loop (npm run test:ai). |
| QA team | Not a gate in v1. Postman optional later from same swagger export. |
BDD without QA: Good practice when it means behavior-focused automated tests. Poor when it means Cucumber workshops and living .feature files the team does not use.
@nestjs/testing + supertest configured in package.json.*.spec.ts under src/ → npm run test exits “No tests found”.test/app.e2e-spec.ts (Hello World) — fails (path aliases, no real route).@ApiOperation, @ApiProperty + example).openapi:export).test:routes fails if a swagger path has no corresponding test manifest entry.*.util.ts, serializers, DTO/class-validator rules.customers.util.spec.ts next to customers.util.ts.it.each tables; behavior titles.*.controller.ts.customers.http.spec.ts (or customers.controller.spec.ts).TestingModule + supertest; mock AuthService, repos, FCM adapter.describe('POST /customers (createCustomer)', () => {
describe('Given valid body', () => {
it('When posted Then returns 201 and customer shape', async () => { /* ... */ });
});
});
POST /projects, migration-sensitive flows.@integration, runInBand, test DB or Testcontainers.swagger.json after build or via script.test/manifest/routes.json — AI updates when adding routes.test:routes — untested paths fail unless whitelisted (/api/docs, health, etc.).| Script | Purpose |
|---|---|
openapi:export | Write test/fixtures/swagger.json from Nest document |
test:unit | Jest *.spec.ts (exclude *.http.spec.ts) |
test:http | Jest *.http.spec.ts |
test:ai | test:unit && test:http — single agent command |
test:integration | Jest @integration only |
test:scaffold | node scripts/scaffold-spec.js <ControllerName> |
test:routes | Swagger paths ↔ manifest coverage |
After changing controllers/services:
npm run test:scaffold -- <ControllerName> if new controller.@ApiProperty examples.npm run test:ai until green.npm run test:routes until green.Document in repo: docs/testing/AI-TESTING.md and/or .cursor/rules/testing.mdc in backend-pms-dev.
*.util.spec.ts + *.http.spec.ts.describe('<METHOD> <path>', …); prefer @ApiOperation({ operationId: 'createCustomer' }).test/fixtures/<module>.json from decorator examples.test/support/mock-auth.module.ts — never real SSO in tests.@integration only when necessary.Already in src/main.ts: /api/docs, swagger.json in dev/staging.
For every new public route:
@ApiOperation, @ApiResponse (success + relevant errors).@ApiProperty / @ApiPropertyOptional with example on DTOs.api prefix + URI version v1.AI generates supertest payloads from decorators, not vault YAML.
| Drop | Reason |
|---|---|
Cucumber / .feature | No QA workflow; AI maintains Jest |
Vault openapi.yaml as CI gate | Planning doc; Nest is runtime truth |
| Postman as required process | Optional export from swagger.json |
| Thick BDD step libraries | Logic stays in src/ |
moduleNameMapper for src/... imports.test/app.e2e-spec.ts.test/support/create-test-app.ts, mock auth, mock repos.openapi:export, test:ai, agent rules.customers.util.spec.ts + customers.http.spec.ts as AI template.test/manifest/routes.json + test:routes.POST /projects tagged @integration.swagger.json?customers vs projects as first template?| Contract portal (today) | PMS (planned) | |
|---|---|---|
| Style | Example-driven Jest unit tests | Jest unit + HTTP behavior specs |
| Stakeholders | Devs | AI + dev review |
| DB in tests | Heavy mocks | Mocks default; rare real DB |
| Fit | SLA calculation complexity | Nested aggregate writes, multi-schema |
Project Manager/backend-pms-dev/Project Manager/docs/openapi/openapi.yaml/api/docs on running app