cfsa-antigravity 2.0.0 → 2.2.0
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 +14 -0
- package/package.json +1 -1
- package/template/.agent/instructions/commands.md +8 -32
- package/template/.agent/instructions/example.md +21 -0
- package/template/.agent/instructions/patterns.md +3 -3
- package/template/.agent/instructions/tech-stack.md +71 -23
- package/template/.agent/instructions/workflow.md +12 -1
- package/template/.agent/rules/completion-checklist.md +6 -0
- package/template/.agent/rules/security-first.md +3 -3
- package/template/.agent/rules/vertical-slices.md +1 -1
- package/template/.agent/skill-library/MANIFEST.md +6 -0
- package/template/.agent/skill-library/stack/devops/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/stack/devops/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/api-versioning/SKILL.md +44 -298
- package/template/.agent/skills/api-versioning/references/typescript.md +157 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +13 -13
- package/template/.agent/skills/bootstrap-agents/SKILL.md +151 -152
- package/template/.agent/skills/clean-code/SKILL.md +64 -118
- package/template/.agent/skills/clean-code/references/typescript.md +126 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +93 -317
- package/template/.agent/skills/database-schema-design/references/relational.md +228 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +62 -557
- package/template/.agent/skills/error-handling-patterns/references/go.md +162 -0
- package/template/.agent/skills/error-handling-patterns/references/python.md +262 -0
- package/template/.agent/skills/error-handling-patterns/references/rust.md +112 -0
- package/template/.agent/skills/error-handling-patterns/references/typescript.md +178 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +322 -224
- package/template/.agent/skills/logging-best-practices/SKILL.md +108 -767
- package/template/.agent/skills/logging-best-practices/references/go.md +49 -0
- package/template/.agent/skills/logging-best-practices/references/python.md +52 -0
- package/template/.agent/skills/logging-best-practices/references/typescript.md +215 -0
- package/template/.agent/skills/migration-management/SKILL.md +127 -311
- package/template/.agent/skills/migration-management/references/relational.md +214 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +34 -43
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +1 -1
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +2 -2
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +1 -1
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +2 -1
- package/template/.agent/skills/prd-templates/SKILL.md +23 -6
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +2 -2
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +2 -2
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +2 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +1 -1
- package/template/.agent/skills/prd-templates/references/fractal-cx-template.md +58 -0
- package/template/.agent/skills/prd-templates/references/fractal-feature-template.md +93 -0
- package/template/.agent/skills/prd-templates/references/fractal-node-index-template.md +55 -0
- package/template/.agent/skills/prd-templates/references/ideation-crosscut-template.md +26 -47
- package/template/.agent/skills/prd-templates/references/ideation-index-template.md +47 -31
- package/template/.agent/skills/prd-templates/references/operational-templates.md +1 -1
- package/template/.agent/skills/prd-templates/references/placeholder-workflow-mapping.md +50 -21
- package/template/.agent/skills/prd-templates/references/skill-loading-protocol.md +32 -0
- package/template/.agent/skills/prd-templates/references/slice-completion-gates.md +29 -0
- package/template/.agent/skills/prd-templates/references/spec-coverage-sweep.md +3 -3
- package/template/.agent/skills/prd-templates/references/tdd-testing-policy.md +39 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +8 -8
- package/template/.agent/skills/regex-patterns/SKILL.md +122 -540
- package/template/.agent/skills/regex-patterns/references/go.md +44 -0
- package/template/.agent/skills/regex-patterns/references/javascript.md +63 -0
- package/template/.agent/skills/regex-patterns/references/python.md +77 -0
- package/template/.agent/skills/regex-patterns/references/rust.md +43 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +1 -1
- package/template/.agent/skills/session-continuity/SKILL.md +11 -9
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +2 -2
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +1 -1
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +1 -1
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +1 -1
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +57 -78
- package/template/.agent/skills/session-continuity/protocols/11-parallel-synthesis.md +1 -1
- package/template/.agent/skills/spec-writing/SKILL.md +1 -1
- package/template/.agent/skills/tdd-workflow/SKILL.md +94 -317
- package/template/.agent/skills/tdd-workflow/references/typescript.md +231 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +74 -687
- package/template/.agent/skills/testing-strategist/references/typescript.md +328 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +62 -154
- package/template/.agent/skills/workflow-automation/references/inngest.md +88 -0
- package/template/.agent/skills/workflow-automation/references/temporal.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +85 -143
- package/template/.agent/workflows/bootstrap-agents-provision.md +90 -107
- package/template/.agent/workflows/create-prd-architecture.md +23 -16
- package/template/.agent/workflows/create-prd-compile.md +11 -12
- package/template/.agent/workflows/create-prd-design-system.md +1 -1
- package/template/.agent/workflows/create-prd-security.md +9 -11
- package/template/.agent/workflows/create-prd-stack.md +10 -4
- package/template/.agent/workflows/create-prd.md +9 -9
- package/template/.agent/workflows/decompose-architecture-structure.md +4 -6
- package/template/.agent/workflows/decompose-architecture-validate.md +18 -1
- package/template/.agent/workflows/decompose-architecture.md +18 -3
- package/template/.agent/workflows/evolve-contract.md +11 -11
- package/template/.agent/workflows/evolve-feature-classify.md +14 -6
- package/template/.agent/workflows/ideate-discover.md +72 -107
- package/template/.agent/workflows/ideate-extract.md +84 -63
- package/template/.agent/workflows/ideate-validate.md +26 -22
- package/template/.agent/workflows/ideate.md +9 -9
- package/template/.agent/workflows/implement-slice-setup.md +25 -23
- package/template/.agent/workflows/implement-slice-tdd.md +73 -89
- package/template/.agent/workflows/implement-slice.md +4 -4
- package/template/.agent/workflows/plan-phase-preflight.md +6 -2
- package/template/.agent/workflows/plan-phase-write.md +6 -8
- package/template/.agent/workflows/remediate-pipeline-assess.md +2 -1
- package/template/.agent/workflows/resolve-ambiguity.md +2 -2
- package/template/.agent/workflows/update-architecture-map.md +22 -5
- package/template/.agent/workflows/validate-phase-quality.md +155 -0
- package/template/.agent/workflows/validate-phase-readiness.md +167 -0
- package/template/.agent/workflows/validate-phase.md +19 -157
- package/template/.agent/workflows/verify-infrastructure.md +10 -10
- package/template/.agent/workflows/write-architecture-spec-design.md +23 -14
- package/template/.agent/workflows/write-be-spec-classify.md +25 -21
- package/template/.agent/workflows/write-be-spec.md +1 -1
- package/template/.agent/workflows/write-fe-spec-classify.md +6 -12
- package/template/.agent/workflows/write-fe-spec-write.md +1 -1
- package/template/AGENTS.md +6 -2
- package/template/GEMINI.md +5 -3
- package/template/docs/README.md +10 -10
- package/template/docs/kit-architecture.md +126 -33
- package/template/docs/plans/ideation/README.md +8 -3
- package/template/.agent/skills/prd-templates/references/ideation-domain-template.md +0 -55
|
@@ -5,7 +5,7 @@ description: Use this skill when writing new features, fixing bugs, or refactori
|
|
|
5
5
|
|
|
6
6
|
# Test-Driven Development Workflow
|
|
7
7
|
|
|
8
|
-
This skill ensures all code development follows TDD principles with comprehensive test coverage.
|
|
8
|
+
This skill ensures all code development follows TDD principles with comprehensive test coverage. It is stack-agnostic — after reading the methodology below, read the language reference matching your surface's Languages column.
|
|
9
9
|
|
|
10
10
|
## When to Activate
|
|
11
11
|
|
|
@@ -15,6 +15,17 @@ This skill ensures all code development follows TDD principles with comprehensiv
|
|
|
15
15
|
- Adding API endpoints
|
|
16
16
|
- Creating new components
|
|
17
17
|
|
|
18
|
+
## Stack-Specific References
|
|
19
|
+
|
|
20
|
+
After reading the methodology below, read the reference matching your surface's Languages column in the surface stack map (`.agent/instructions/tech-stack.md`):
|
|
21
|
+
|
|
22
|
+
| Language | Reference |
|
|
23
|
+
|----------|-----------|
|
|
24
|
+
| TypeScript / JavaScript | `references/typescript.md` |
|
|
25
|
+
| Python | `references/python.md` |
|
|
26
|
+
| Go | `references/go.md` |
|
|
27
|
+
| Rust | `references/rust.md` |
|
|
28
|
+
|
|
18
29
|
## Core Principles
|
|
19
30
|
|
|
20
31
|
### 1. Tests BEFORE Code
|
|
@@ -28,23 +39,11 @@ ALWAYS write tests first, then implement code to make tests pass.
|
|
|
28
39
|
|
|
29
40
|
### 3. Test Types
|
|
30
41
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
#### Integration Tests
|
|
38
|
-
- API endpoints
|
|
39
|
-
- Database operations
|
|
40
|
-
- Service interactions
|
|
41
|
-
- External API calls
|
|
42
|
-
|
|
43
|
-
#### E2E Tests (Playwright)
|
|
44
|
-
- Critical user flows
|
|
45
|
-
- Complete workflows
|
|
46
|
-
- Browser automation
|
|
47
|
-
- UI interactions
|
|
42
|
+
| Type | Scope | What to Test | Speed |
|
|
43
|
+
|------|-------|-------------|-------|
|
|
44
|
+
| **Unit** | Individual functions, pure logic, utilities | Input/output, edge cases, error paths | < 50ms each |
|
|
45
|
+
| **Integration** | API endpoints, DB operations, service interactions | Request/response, validation, error handling | < 500ms each |
|
|
46
|
+
| **E2E** | Full user flows, browser automation | Critical paths, complete workflows, UI interactions | < 30s each |
|
|
48
47
|
|
|
49
48
|
## TDD Workflow Steps
|
|
50
49
|
|
|
@@ -58,49 +57,24 @@ so that I can find relevant markets even without exact keywords.
|
|
|
58
57
|
```
|
|
59
58
|
|
|
60
59
|
### Step 2: Generate Test Cases
|
|
61
|
-
For each user journey,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
it('handles empty query gracefully', async () => {
|
|
70
|
-
// Test edge case
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it('falls back to substring search when Redis unavailable', async () => {
|
|
74
|
-
// Test fallback behavior
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it('sorts results by similarity score', async () => {
|
|
78
|
-
// Test sorting logic
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
```
|
|
60
|
+
For each user journey, identify test cases covering:
|
|
61
|
+
- **Happy path** — expected input produces expected output
|
|
62
|
+
- **Edge cases** — empty input, boundary values, large input
|
|
63
|
+
- **Error paths** — invalid input, service failures, timeouts
|
|
64
|
+
- **Fallback behavior** — what happens when dependencies fail
|
|
65
|
+
|
|
66
|
+
Write these as test stubs that describe the behavior but don't implement yet. See language references for syntax.
|
|
82
67
|
|
|
83
68
|
### Step 3: Run Tests (They Should Fail)
|
|
84
|
-
|
|
85
|
-
npm test
|
|
86
|
-
# Tests should fail - we haven't implemented yet
|
|
87
|
-
```
|
|
69
|
+
Run the test suite. All new tests should fail — this is the **Red** phase. If any pass before you've written implementation, your test isn't testing what you think it is.
|
|
88
70
|
|
|
89
71
|
### Step 4: Implement Code
|
|
90
|
-
Write minimal code to make tests pass
|
|
72
|
+
Write **minimal** code to make tests pass. Don't over-engineer. Don't add features the tests don't require.
|
|
91
73
|
|
|
92
|
-
|
|
93
|
-
// Implementation guided by tests
|
|
94
|
-
export async function searchMarkets(query: string) {
|
|
95
|
-
// Implementation here
|
|
96
|
-
}
|
|
97
|
-
```
|
|
74
|
+
> **"Minimal" means correct, not shallow.** The implementation must be production-grade — proper error handling, type safety, input validation. "Minimal" means don't add features beyond what the tests verify, not "write the least amount of code possible regardless of quality."
|
|
98
75
|
|
|
99
|
-
### Step 5: Run Tests Again
|
|
100
|
-
|
|
101
|
-
npm test
|
|
102
|
-
# Tests should now pass
|
|
103
|
-
```
|
|
76
|
+
### Step 5: Run Tests Again (They Should Pass)
|
|
77
|
+
Run the test suite. All tests should now pass — this is the **Green** phase.
|
|
104
78
|
|
|
105
79
|
### Step 6: Refactor
|
|
106
80
|
Improve code quality while keeping tests green:
|
|
@@ -108,299 +82,102 @@ Improve code quality while keeping tests green:
|
|
|
108
82
|
- Improve naming
|
|
109
83
|
- Optimize performance
|
|
110
84
|
- Enhance readability
|
|
85
|
+
- Extract abstractions
|
|
111
86
|
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
npm run test:coverage
|
|
115
|
-
# Verify 80%+ coverage achieved
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## Testing Patterns
|
|
119
|
-
|
|
120
|
-
### Unit Test Pattern (Jest/Vitest)
|
|
121
|
-
```typescript
|
|
122
|
-
import { render, screen, fireEvent } from '@testing-library/react'
|
|
123
|
-
import { Button } from './Button'
|
|
124
|
-
|
|
125
|
-
describe('Button Component', () => {
|
|
126
|
-
it('renders with correct text', () => {
|
|
127
|
-
render(<Button>Click me</Button>)
|
|
128
|
-
expect(screen.getByText('Click me')).toBeInTheDocument()
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
it('calls onClick when clicked', () => {
|
|
132
|
-
const handleClick = jest.fn()
|
|
133
|
-
render(<Button onClick={handleClick}>Click</Button>)
|
|
134
|
-
|
|
135
|
-
fireEvent.click(screen.getByRole('button'))
|
|
136
|
-
|
|
137
|
-
expect(handleClick).toHaveBeenCalledTimes(1)
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
it('is disabled when disabled prop is true', () => {
|
|
141
|
-
render(<Button disabled>Click</Button>)
|
|
142
|
-
expect(screen.getByRole('button')).toBeDisabled()
|
|
143
|
-
})
|
|
144
|
-
})
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### API Integration Test Pattern
|
|
148
|
-
```typescript
|
|
149
|
-
import { NextRequest } from 'next/server'
|
|
150
|
-
import { GET } from './route'
|
|
151
|
-
|
|
152
|
-
describe('GET /api/markets', () => {
|
|
153
|
-
it('returns markets successfully', async () => {
|
|
154
|
-
const request = new NextRequest('http://localhost/api/markets')
|
|
155
|
-
const response = await GET(request)
|
|
156
|
-
const data = await response.json()
|
|
157
|
-
|
|
158
|
-
expect(response.status).toBe(200)
|
|
159
|
-
expect(data.success).toBe(true)
|
|
160
|
-
expect(Array.isArray(data.data)).toBe(true)
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
it('validates query parameters', async () => {
|
|
164
|
-
const request = new NextRequest('http://localhost/api/markets?limit=invalid')
|
|
165
|
-
const response = await GET(request)
|
|
166
|
-
|
|
167
|
-
expect(response.status).toBe(400)
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
it('handles database errors gracefully', async () => {
|
|
171
|
-
// Mock database failure
|
|
172
|
-
const request = new NextRequest('http://localhost/api/markets')
|
|
173
|
-
// Test error handling
|
|
174
|
-
})
|
|
175
|
-
})
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### E2E Test Pattern (Playwright)
|
|
179
|
-
```typescript
|
|
180
|
-
import { test, expect } from '@playwright/test'
|
|
181
|
-
|
|
182
|
-
test('user can search and filter markets', async ({ page }) => {
|
|
183
|
-
// Navigate to markets page
|
|
184
|
-
await page.goto('/')
|
|
185
|
-
await page.click('a[href="/markets"]')
|
|
186
|
-
|
|
187
|
-
// Verify page loaded
|
|
188
|
-
await expect(page.locator('h1')).toContainText('Markets')
|
|
189
|
-
|
|
190
|
-
// Search for markets
|
|
191
|
-
await page.fill('input[placeholder="Search markets"]', 'election')
|
|
192
|
-
|
|
193
|
-
// Wait for debounce and results
|
|
194
|
-
await page.waitForTimeout(600)
|
|
87
|
+
Run tests after every refactor to ensure nothing breaks.
|
|
195
88
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
await expect(results).toHaveCount(5, { timeout: 5000 })
|
|
199
|
-
|
|
200
|
-
// Verify results contain search term
|
|
201
|
-
const firstResult = results.first()
|
|
202
|
-
await expect(firstResult).toContainText('election', { ignoreCase: true })
|
|
203
|
-
|
|
204
|
-
// Filter by status
|
|
205
|
-
await page.click('button:has-text("Active")')
|
|
206
|
-
|
|
207
|
-
// Verify filtered results
|
|
208
|
-
await expect(results).toHaveCount(3)
|
|
209
|
-
})
|
|
210
|
-
|
|
211
|
-
test('user can create a new market', async ({ page }) => {
|
|
212
|
-
// Login first
|
|
213
|
-
await page.goto('/creator-dashboard')
|
|
214
|
-
|
|
215
|
-
// Fill market creation form
|
|
216
|
-
await page.fill('input[name="name"]', 'Test Market')
|
|
217
|
-
await page.fill('textarea[name="description"]', 'Test description')
|
|
218
|
-
await page.fill('input[name="endDate"]', '2025-12-31')
|
|
219
|
-
|
|
220
|
-
// Submit form
|
|
221
|
-
await page.click('button[type="submit"]')
|
|
222
|
-
|
|
223
|
-
// Verify success message
|
|
224
|
-
await expect(page.locator('text=Market created successfully')).toBeVisible()
|
|
225
|
-
|
|
226
|
-
// Verify redirect to market page
|
|
227
|
-
await expect(page).toHaveURL(/\/markets\/test-market/)
|
|
228
|
-
})
|
|
229
|
-
```
|
|
89
|
+
### Step 7: Verify Coverage
|
|
90
|
+
Run coverage report. Verify 80%+ coverage achieved. Identify untested paths and add tests as needed.
|
|
230
91
|
|
|
231
92
|
## Test File Organization
|
|
232
93
|
|
|
233
|
-
|
|
234
|
-
src/
|
|
235
|
-
├── components/
|
|
236
|
-
│ ├── Button/
|
|
237
|
-
│ │ ├── Button.tsx
|
|
238
|
-
│ │ ├── Button.test.tsx # Unit tests
|
|
239
|
-
│ │ └── Button.stories.tsx # Storybook
|
|
240
|
-
│ └── MarketCard/
|
|
241
|
-
│ ├── MarketCard.tsx
|
|
242
|
-
│ └── MarketCard.test.tsx
|
|
243
|
-
├── app/
|
|
244
|
-
│ └── api/
|
|
245
|
-
│ └── markets/
|
|
246
|
-
│ ├── route.ts
|
|
247
|
-
│ └── route.test.ts # Integration tests
|
|
248
|
-
└── e2e/
|
|
249
|
-
├── markets.spec.ts # E2E tests
|
|
250
|
-
├── trading.spec.ts
|
|
251
|
-
└── auth.spec.ts
|
|
252
|
-
```
|
|
94
|
+
Tests live next to their source files:
|
|
253
95
|
|
|
254
|
-
## Mocking External Services
|
|
255
|
-
|
|
256
|
-
### Supabase Mock
|
|
257
|
-
```typescript
|
|
258
|
-
jest.mock('@/lib/supabase', () => ({
|
|
259
|
-
supabase: {
|
|
260
|
-
from: jest.fn(() => ({
|
|
261
|
-
select: jest.fn(() => ({
|
|
262
|
-
eq: jest.fn(() => Promise.resolve({
|
|
263
|
-
data: [{ id: 1, name: 'Test Market' }],
|
|
264
|
-
error: null
|
|
265
|
-
}))
|
|
266
|
-
}))
|
|
267
|
-
}))
|
|
268
|
-
}
|
|
269
|
-
}))
|
|
270
96
|
```
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
jest.mock('@/lib/redis', () => ({
|
|
275
|
-
searchMarketsByVector: jest.fn(() => Promise.resolve([
|
|
276
|
-
{ slug: 'test-market', similarity_score: 0.95 }
|
|
277
|
-
])),
|
|
278
|
-
checkRedisHealth: jest.fn(() => Promise.resolve({ connected: true }))
|
|
279
|
-
}))
|
|
97
|
+
source-file.ext → source-file.test.ext (unit tests)
|
|
98
|
+
route-handler.ext → route-handler.test.ext (integration tests)
|
|
99
|
+
e2e/ → feature-name.e2e.ext (E2E tests)
|
|
280
100
|
```
|
|
281
101
|
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
jest.mock('@/lib/openai', () => ({
|
|
285
|
-
generateEmbedding: jest.fn(() => Promise.resolve(
|
|
286
|
-
new Array(1536).fill(0.1) // Mock 1536-dim embedding
|
|
287
|
-
))
|
|
288
|
-
}))
|
|
289
|
-
```
|
|
102
|
+
## Mocking Strategy
|
|
290
103
|
|
|
291
|
-
|
|
104
|
+
### When to Mock
|
|
105
|
+
- External services (APIs, databases, caches) — always in unit tests
|
|
106
|
+
- Time-dependent operations (dates, timers)
|
|
107
|
+
- Non-deterministic operations (random, UUIDs)
|
|
292
108
|
|
|
293
|
-
###
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
109
|
+
### When NOT to Mock
|
|
110
|
+
- The module under test (circular logic)
|
|
111
|
+
- Pure functions (just test them directly)
|
|
112
|
+
- Everything in integration tests (that's the point)
|
|
297
113
|
|
|
298
|
-
###
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
"global": {
|
|
304
|
-
"branches": 80,
|
|
305
|
-
"functions": 80,
|
|
306
|
-
"lines": 80,
|
|
307
|
-
"statements": 80
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
```
|
|
114
|
+
### Anti-Mock-Abuse Rules
|
|
115
|
+
1. **Never mock what you own** — if you wrote the module, test it directly
|
|
116
|
+
2. **One mock = one boundary** — only mock at the boundary between your code and external systems
|
|
117
|
+
3. **Verify mock interactions** — assert that mocked dependencies were called with correct arguments
|
|
118
|
+
4. **Mock return values, not internals** — mock the return value of a dependency, not its internal implementation
|
|
313
119
|
|
|
314
|
-
##
|
|
120
|
+
## Assertion Depth Rules
|
|
315
121
|
|
|
316
|
-
### ❌
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
expect(
|
|
320
|
-
```
|
|
122
|
+
### ❌ Shallow Assertions (BANNED)
|
|
123
|
+
- `expect(result).toBeDefined()` — proves nothing about correctness
|
|
124
|
+
- `expect(result).toBeTruthy()` — empty arrays are truthy
|
|
125
|
+
- `expect(response.status).toBe(200)` alone — doesn't verify response body
|
|
321
126
|
|
|
322
|
-
### ✅
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
127
|
+
### ✅ Deep Assertions (REQUIRED)
|
|
128
|
+
- Assert on specific field values, not just existence
|
|
129
|
+
- Assert on array lengths AND contents
|
|
130
|
+
- Assert on error messages AND error codes
|
|
131
|
+
- Assert on side effects (was the database actually updated?)
|
|
327
132
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
```
|
|
133
|
+
Every test must assert:
|
|
134
|
+
1. **The correct output** — specific values, not just types
|
|
135
|
+
2. **The correct side effects** — what changed in the system
|
|
136
|
+
3. **The correct error behavior** — specific error type and message
|
|
333
137
|
|
|
334
|
-
|
|
335
|
-
```typescript
|
|
336
|
-
// Resilient to changes
|
|
337
|
-
await page.click('button:has-text("Submit")')
|
|
338
|
-
await page.click('[data-testid="submit-button"]')
|
|
339
|
-
```
|
|
138
|
+
## Common Testing Mistakes
|
|
340
139
|
|
|
341
|
-
###
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
test('creates user', () => { /* ... */ })
|
|
345
|
-
test('updates same user', () => { /* depends on previous test */ })
|
|
346
|
-
```
|
|
140
|
+
### Testing Implementation Details
|
|
141
|
+
❌ Don't test internal state, private methods, or how code achieves the result.
|
|
142
|
+
✅ Test what the user/caller observes — return values, rendered output, API responses.
|
|
347
143
|
|
|
348
|
-
###
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
test('creates user', () => {
|
|
352
|
-
const user = createTestUser()
|
|
353
|
-
// Test logic
|
|
354
|
-
})
|
|
355
|
-
|
|
356
|
-
test('updates user', () => {
|
|
357
|
-
const user = createTestUser()
|
|
358
|
-
// Update logic
|
|
359
|
-
})
|
|
360
|
-
```
|
|
144
|
+
### Brittle Selectors (E2E)
|
|
145
|
+
❌ CSS class selectors, nth-child, layout-dependent selectors.
|
|
146
|
+
✅ Semantic selectors: roles, labels, test IDs, visible text.
|
|
361
147
|
|
|
362
|
-
|
|
148
|
+
### Test Coupling
|
|
149
|
+
❌ Tests that depend on execution order or shared state from previous tests.
|
|
150
|
+
✅ Each test creates its own data and cleans up after itself.
|
|
363
151
|
|
|
364
|
-
###
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
# Tests run automatically on file changes
|
|
368
|
-
```
|
|
152
|
+
### Testing the Framework
|
|
153
|
+
❌ Testing that React renders a component, or that Express routes requests.
|
|
154
|
+
✅ Testing YOUR logic — the behavior your code adds on top of the framework.
|
|
369
155
|
|
|
370
|
-
|
|
371
|
-
```bash
|
|
372
|
-
# Runs before every commit
|
|
373
|
-
npm test && npm run lint
|
|
374
|
-
```
|
|
156
|
+
## Continuous Testing
|
|
375
157
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
- name: Run Tests
|
|
380
|
-
run: npm test -- --coverage
|
|
381
|
-
- name: Upload Coverage
|
|
382
|
-
uses: codecov/codecov-action@v3
|
|
383
|
-
```
|
|
158
|
+
- **Watch mode during development** — tests re-run on file changes
|
|
159
|
+
- **Pre-commit hooks** — tests must pass before commits
|
|
160
|
+
- **CI/CD pipeline** — full test suite runs on every push
|
|
384
161
|
|
|
385
162
|
## Best Practices
|
|
386
163
|
|
|
387
|
-
1. **Write Tests First**
|
|
388
|
-
2. **One
|
|
389
|
-
3. **Descriptive Test Names**
|
|
390
|
-
4. **Arrange-Act-Assert**
|
|
391
|
-
5. **Mock
|
|
392
|
-
6. **Test Edge Cases**
|
|
393
|
-
7. **Test Error Paths**
|
|
394
|
-
8. **Keep Tests Fast**
|
|
395
|
-
9. **Clean Up After Tests**
|
|
396
|
-
10. **Review Coverage Reports**
|
|
164
|
+
1. **Write Tests First** — Always TDD: Red → Green → Refactor
|
|
165
|
+
2. **One Behavior Per Test** — Focus each test on a single behavior
|
|
166
|
+
3. **Descriptive Test Names** — Test name should explain what behavior is verified
|
|
167
|
+
4. **Arrange-Act-Assert** — Clear three-part test structure
|
|
168
|
+
5. **Mock at Boundaries** — Only mock external dependencies
|
|
169
|
+
6. **Test Edge Cases** — Null, empty, boundary values, large inputs
|
|
170
|
+
7. **Test Error Paths** — Not just happy paths
|
|
171
|
+
8. **Keep Tests Fast** — Unit tests < 50ms each
|
|
172
|
+
9. **Clean Up After Tests** — No persistent side effects
|
|
173
|
+
10. **Review Coverage Reports** — Identify and close gaps
|
|
397
174
|
|
|
398
175
|
## Success Metrics
|
|
399
176
|
|
|
400
177
|
- 80%+ code coverage achieved
|
|
401
178
|
- All tests passing (green)
|
|
402
|
-
- No skipped or disabled tests
|
|
403
|
-
- Fast test execution (< 30s for unit
|
|
179
|
+
- No skipped or disabled tests without `BOUNDARY:` tracking
|
|
180
|
+
- Fast test execution (< 30s for unit suite)
|
|
404
181
|
- E2E tests cover critical user flows
|
|
405
182
|
- Tests catch bugs before production
|
|
406
183
|
|