claude-mpm 5.4.59__py3-none-any.whl → 5.4.62__py3-none-any.whl
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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +5 -0
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +8 -0
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- {claude_mpm-5.4.59.dist-info → claude_mpm-5.4.62.dist-info}/METADATA +1 -1
- {claude_mpm-5.4.59.dist-info → claude_mpm-5.4.62.dist-info}/RECORD +127 -10
- {claude_mpm-5.4.59.dist-info → claude_mpm-5.4.62.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.59.dist-info → claude_mpm-5.4.62.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.59.dist-info → claude_mpm-5.4.62.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.59.dist-info → claude_mpm-5.4.62.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.59.dist-info → claude_mpm-5.4.62.dist-info}/top_level.txt +0 -0
claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md
ADDED
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
# Completeness Anti-Patterns
|
|
2
|
+
|
|
3
|
+
Anti-patterns related to incomplete testing practices: partial mocks that hide structural dependencies, and treating tests as optional afterthoughts instead of integral parts of implementation.
|
|
4
|
+
|
|
5
|
+
## Anti-Pattern 4: Incomplete Mocks
|
|
6
|
+
|
|
7
|
+
**The violation:**
|
|
8
|
+
```typescript
|
|
9
|
+
// ❌ BAD: Partial mock - only fields you think you need
|
|
10
|
+
const mockResponse = {
|
|
11
|
+
status: 'success',
|
|
12
|
+
data: { userId: '123', name: 'Alice' }
|
|
13
|
+
// Missing: metadata that downstream code uses
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// Later: breaks when code accesses response.metadata.requestId
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Why this is wrong:**
|
|
20
|
+
- **Partial mocks hide structural assumptions** - You only mocked fields you know about
|
|
21
|
+
- **Downstream code may depend on fields you didn't include** - Silent failures
|
|
22
|
+
- **Tests pass but integration fails** - Mock incomplete, real API complete
|
|
23
|
+
- **False confidence** - Test proves nothing about real behavior
|
|
24
|
+
- **Breaking changes go undetected** - API changes don't fail tests
|
|
25
|
+
|
|
26
|
+
**The Iron Rule:** Mock the COMPLETE data structure as it exists in reality, not just fields your immediate test uses.
|
|
27
|
+
|
|
28
|
+
**Real-world impact:**
|
|
29
|
+
```typescript
|
|
30
|
+
// Your test (incomplete mock)
|
|
31
|
+
const mockUser = { id: '123', name: 'Alice' };
|
|
32
|
+
// Passes ✅
|
|
33
|
+
|
|
34
|
+
// Production code elsewhere
|
|
35
|
+
function getUserTimezone(user) {
|
|
36
|
+
return user.profile.timezone; // undefined - breaks in production!
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Complete Mock Strategy
|
|
41
|
+
|
|
42
|
+
**The fix:**
|
|
43
|
+
```typescript
|
|
44
|
+
// ✅ GOOD: Mirror real API completeness
|
|
45
|
+
const mockResponse = {
|
|
46
|
+
status: 'success',
|
|
47
|
+
data: {
|
|
48
|
+
userId: '123',
|
|
49
|
+
name: 'Alice',
|
|
50
|
+
email: 'alice@example.com',
|
|
51
|
+
profile: {
|
|
52
|
+
timezone: 'America/New_York',
|
|
53
|
+
locale: 'en-US',
|
|
54
|
+
avatar: 'https://...'
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
metadata: {
|
|
58
|
+
requestId: 'req-789',
|
|
59
|
+
timestamp: 1234567890,
|
|
60
|
+
version: 'v2'
|
|
61
|
+
}
|
|
62
|
+
// All fields real API returns
|
|
63
|
+
};
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### How to Create Complete Mocks
|
|
67
|
+
|
|
68
|
+
**Step 1: Reference real API documentation**
|
|
69
|
+
```typescript
|
|
70
|
+
// ❌ BAD - mocking from memory
|
|
71
|
+
const mock = { id: 1, name: 'test' };
|
|
72
|
+
|
|
73
|
+
// ✅ GOOD - reference API docs
|
|
74
|
+
// From API docs: GET /api/users/:id returns:
|
|
75
|
+
// {
|
|
76
|
+
// id: number,
|
|
77
|
+
// name: string,
|
|
78
|
+
// email: string,
|
|
79
|
+
// createdAt: ISO8601,
|
|
80
|
+
// profile: { ... },
|
|
81
|
+
// permissions: string[]
|
|
82
|
+
// }
|
|
83
|
+
|
|
84
|
+
const mock = {
|
|
85
|
+
id: 1,
|
|
86
|
+
name: 'test',
|
|
87
|
+
email: 'test@example.com',
|
|
88
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
89
|
+
profile: { /* complete profile */ },
|
|
90
|
+
permissions: ['read', 'write']
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Step 2: Use TypeScript types**
|
|
95
|
+
```typescript
|
|
96
|
+
// ✅ TypeScript ensures completeness
|
|
97
|
+
interface User {
|
|
98
|
+
id: string;
|
|
99
|
+
name: string;
|
|
100
|
+
email: string;
|
|
101
|
+
profile: UserProfile;
|
|
102
|
+
metadata: UserMetadata;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// TypeScript error if incomplete
|
|
106
|
+
const mockUser: User = {
|
|
107
|
+
id: '123',
|
|
108
|
+
name: 'Alice'
|
|
109
|
+
// Error: Missing email, profile, metadata
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Must be complete
|
|
113
|
+
const mockUser: User = {
|
|
114
|
+
id: '123',
|
|
115
|
+
name: 'Alice',
|
|
116
|
+
email: 'alice@example.com',
|
|
117
|
+
profile: { timezone: 'UTC', locale: 'en' },
|
|
118
|
+
metadata: { createdAt: '2024-01-01T00:00:00Z' }
|
|
119
|
+
};
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Step 3: Extract mock factories**
|
|
123
|
+
```typescript
|
|
124
|
+
// ✅ Reusable complete mocks
|
|
125
|
+
// test-utils/factories/user.ts
|
|
126
|
+
export function createMockUser(overrides?: Partial<User>): User {
|
|
127
|
+
return {
|
|
128
|
+
id: '123',
|
|
129
|
+
name: 'Test User',
|
|
130
|
+
email: 'test@example.com',
|
|
131
|
+
profile: {
|
|
132
|
+
timezone: 'UTC',
|
|
133
|
+
locale: 'en-US',
|
|
134
|
+
avatar: null
|
|
135
|
+
},
|
|
136
|
+
metadata: {
|
|
137
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
138
|
+
updatedAt: '2024-01-01T00:00:00Z',
|
|
139
|
+
version: 1
|
|
140
|
+
},
|
|
141
|
+
permissions: ['read'],
|
|
142
|
+
...overrides // Allow customization
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Usage
|
|
147
|
+
const user = createMockUser({ name: 'Alice' });
|
|
148
|
+
// All fields present, name overridden
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Detecting Incomplete Mocks
|
|
152
|
+
|
|
153
|
+
**Red flags:**
|
|
154
|
+
- Creating mocks without referencing API docs
|
|
155
|
+
- TypeScript `any` or `Partial<T>` for mocks
|
|
156
|
+
- Different tests have different mock shapes for same type
|
|
157
|
+
- Mock has fewer fields than real API
|
|
158
|
+
- Comments like "add fields as needed"
|
|
159
|
+
|
|
160
|
+
**Gate Function:**
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
BEFORE creating mock responses:
|
|
164
|
+
Check: "What fields does the real API response contain?"
|
|
165
|
+
|
|
166
|
+
Actions:
|
|
167
|
+
1. Open API documentation or OpenAPI spec
|
|
168
|
+
2. List ALL fields in response
|
|
169
|
+
3. Include ALL fields in mock (use TypeScript types)
|
|
170
|
+
4. Verify mock matches real response schema completely
|
|
171
|
+
|
|
172
|
+
Critical:
|
|
173
|
+
If you're creating a mock, you must understand the ENTIRE structure
|
|
174
|
+
Partial mocks fail silently when code depends on omitted fields
|
|
175
|
+
|
|
176
|
+
If uncertain:
|
|
177
|
+
- Include all documented fields
|
|
178
|
+
- Use TypeScript interfaces to enforce completeness
|
|
179
|
+
- Create factory functions for reusable complete mocks
|
|
180
|
+
|
|
181
|
+
Red flags:
|
|
182
|
+
- "I'll add more fields later"
|
|
183
|
+
- "Just mocking what I need"
|
|
184
|
+
- Creating mock from memory
|
|
185
|
+
- Different mock shapes for same entity
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Common Incomplete Mock Scenarios
|
|
189
|
+
|
|
190
|
+
**Scenario 1: Nested objects**
|
|
191
|
+
```typescript
|
|
192
|
+
// ❌ BAD - incomplete nesting
|
|
193
|
+
const mockUser = {
|
|
194
|
+
id: '123',
|
|
195
|
+
profile: { name: 'Alice' } // Missing profile.timezone, profile.locale
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
// ✅ GOOD - complete nesting
|
|
199
|
+
const mockUser = {
|
|
200
|
+
id: '123',
|
|
201
|
+
profile: {
|
|
202
|
+
name: 'Alice',
|
|
203
|
+
timezone: 'UTC',
|
|
204
|
+
locale: 'en-US',
|
|
205
|
+
avatar: null,
|
|
206
|
+
bio: null
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Scenario 2: Arrays**
|
|
212
|
+
```typescript
|
|
213
|
+
// ❌ BAD - empty array when real data has items
|
|
214
|
+
const mockResponse = {
|
|
215
|
+
users: [] // Real API always has pagination metadata
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// ✅ GOOD - realistic array with metadata
|
|
219
|
+
const mockResponse = {
|
|
220
|
+
users: [
|
|
221
|
+
{ id: '1', name: 'Alice', /* complete user */ },
|
|
222
|
+
{ id: '2', name: 'Bob', /* complete user */ }
|
|
223
|
+
],
|
|
224
|
+
pagination: {
|
|
225
|
+
total: 2,
|
|
226
|
+
page: 1,
|
|
227
|
+
perPage: 10,
|
|
228
|
+
hasNext: false
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Scenario 3: Optional fields**
|
|
234
|
+
```typescript
|
|
235
|
+
// ❌ BAD - omitting optional fields
|
|
236
|
+
const mockUser = {
|
|
237
|
+
id: '123',
|
|
238
|
+
name: 'Alice'
|
|
239
|
+
// Omitted optional fields - downstream code may check them
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// ✅ GOOD - include optional fields (as null/undefined)
|
|
243
|
+
const mockUser = {
|
|
244
|
+
id: '123',
|
|
245
|
+
name: 'Alice',
|
|
246
|
+
bio: null, // Optional field explicitly null
|
|
247
|
+
website: undefined, // Optional field explicitly undefined
|
|
248
|
+
avatar: null
|
|
249
|
+
};
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Mock Completeness Levels
|
|
253
|
+
|
|
254
|
+
**Level 1: Minimal (AVOID)**
|
|
255
|
+
```typescript
|
|
256
|
+
// Only immediate test needs
|
|
257
|
+
const mock = { id: '123' };
|
|
258
|
+
// Risk: High - downstream code breaks
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Level 2: Partial (RISKY)**
|
|
262
|
+
```typescript
|
|
263
|
+
// Common fields included
|
|
264
|
+
const mock = { id: '123', name: 'Alice', email: 'alice@example.com' };
|
|
265
|
+
// Risk: Medium - missing nested/optional fields
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Level 3: Complete (REQUIRED)**
|
|
269
|
+
```typescript
|
|
270
|
+
// All fields from API spec
|
|
271
|
+
const mock = {
|
|
272
|
+
id: '123',
|
|
273
|
+
name: 'Alice',
|
|
274
|
+
email: 'alice@example.com',
|
|
275
|
+
profile: { /* complete */ },
|
|
276
|
+
metadata: { /* complete */ },
|
|
277
|
+
permissions: ['read']
|
|
278
|
+
};
|
|
279
|
+
// Risk: Low - matches real API
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Level 4: Factory-based (BEST)**
|
|
283
|
+
```typescript
|
|
284
|
+
// Reusable factory with defaults
|
|
285
|
+
const mock = createMockUser({ name: 'Alice' });
|
|
286
|
+
// Risk: Minimal - centralized, typed, complete
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Anti-Pattern 5: Integration Tests as Afterthought
|
|
290
|
+
|
|
291
|
+
**The violation:**
|
|
292
|
+
```
|
|
293
|
+
✅ Implementation complete
|
|
294
|
+
❌ No tests written
|
|
295
|
+
"Ready for testing"
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Why this is wrong:**
|
|
299
|
+
- Testing is part of implementation, not optional follow-up
|
|
300
|
+
- TDD would have caught this
|
|
301
|
+
- Can't claim complete without tests
|
|
302
|
+
- Tests written after code are biased toward existing implementation
|
|
303
|
+
- Missing tests = incomplete feature
|
|
304
|
+
- Technical debt from day one
|
|
305
|
+
|
|
306
|
+
**The fix:**
|
|
307
|
+
```
|
|
308
|
+
TDD cycle:
|
|
309
|
+
1. Write failing test
|
|
310
|
+
2. Watch it fail (verify)
|
|
311
|
+
3. Write minimal code to pass
|
|
312
|
+
4. Watch it pass (verify)
|
|
313
|
+
5. Refactor
|
|
314
|
+
6. THEN claim complete
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Why Tests Must Come First
|
|
318
|
+
|
|
319
|
+
**Tests-after problems:**
|
|
320
|
+
|
|
321
|
+
1. **Implementation bias**
|
|
322
|
+
- Tests confirm what code does, not what it should do
|
|
323
|
+
- Bugs baked into tests
|
|
324
|
+
- Missing edge cases
|
|
325
|
+
|
|
326
|
+
2. **Design issues**
|
|
327
|
+
- Code hard to test (not designed for testability)
|
|
328
|
+
- Tight coupling discovered too late
|
|
329
|
+
- Refactoring required to make testable
|
|
330
|
+
|
|
331
|
+
3. **Coverage gaps**
|
|
332
|
+
- Temptation to skip "hard to test" paths
|
|
333
|
+
- Error handling overlooked
|
|
334
|
+
- Edge cases ignored
|
|
335
|
+
|
|
336
|
+
4. **False completion**
|
|
337
|
+
- Feature seems done but untested
|
|
338
|
+
- Integration issues discovered late
|
|
339
|
+
- Delayed feedback loop
|
|
340
|
+
|
|
341
|
+
**Tests-first benefits:**
|
|
342
|
+
|
|
343
|
+
1. **Design driver**
|
|
344
|
+
- Forces testable design upfront
|
|
345
|
+
- Identifies coupling before writing code
|
|
346
|
+
- API designed from consumer perspective
|
|
347
|
+
|
|
348
|
+
2. **Verification**
|
|
349
|
+
- Confirms implementation matches requirements
|
|
350
|
+
- Catches bugs immediately
|
|
351
|
+
- Documents expected behavior
|
|
352
|
+
|
|
353
|
+
3. **Confidence**
|
|
354
|
+
- Safe refactoring
|
|
355
|
+
- Regression prevention
|
|
356
|
+
- Living documentation
|
|
357
|
+
|
|
358
|
+
### Integration Testing Strategy
|
|
359
|
+
|
|
360
|
+
**When to write integration tests:**
|
|
361
|
+
|
|
362
|
+
- **Before implementation** (TDD approach)
|
|
363
|
+
```typescript
|
|
364
|
+
// 1. Write failing integration test
|
|
365
|
+
test('user registration flow', async () => {
|
|
366
|
+
const response = await api.post('/register', userData);
|
|
367
|
+
expect(response.status).toBe(201);
|
|
368
|
+
expect(response.body.user).toMatchObject(userData);
|
|
369
|
+
});
|
|
370
|
+
// Test fails - endpoint doesn't exist
|
|
371
|
+
|
|
372
|
+
// 2. Implement endpoint
|
|
373
|
+
// 3. Test passes
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
- **Alongside unit tests** (test pyramid)
|
|
377
|
+
- Unit tests: Fast, isolated, many
|
|
378
|
+
- Integration tests: Realistic, end-to-end, fewer
|
|
379
|
+
- Both written before/during implementation
|
|
380
|
+
|
|
381
|
+
**Types of integration tests:**
|
|
382
|
+
|
|
383
|
+
1. **API integration tests**
|
|
384
|
+
```typescript
|
|
385
|
+
test('POST /api/users creates user', async () => {
|
|
386
|
+
const response = await request(app)
|
|
387
|
+
.post('/api/users')
|
|
388
|
+
.send({ name: 'Alice', email: 'alice@example.com' });
|
|
389
|
+
|
|
390
|
+
expect(response.status).toBe(201);
|
|
391
|
+
expect(response.body).toMatchObject({
|
|
392
|
+
id: expect.any(String),
|
|
393
|
+
name: 'Alice',
|
|
394
|
+
email: 'alice@example.com'
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
// Verify database
|
|
398
|
+
const user = await db.users.findById(response.body.id);
|
|
399
|
+
expect(user).toBeDefined();
|
|
400
|
+
});
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
2. **Database integration tests**
|
|
404
|
+
```typescript
|
|
405
|
+
test('user repository saves and retrieves users', async () => {
|
|
406
|
+
const user = await userRepo.create({
|
|
407
|
+
name: 'Alice',
|
|
408
|
+
email: 'alice@example.com'
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
const retrieved = await userRepo.findById(user.id);
|
|
412
|
+
expect(retrieved).toEqual(user);
|
|
413
|
+
});
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
3. **Component integration tests**
|
|
417
|
+
```typescript
|
|
418
|
+
test('UserForm submits to API', async () => {
|
|
419
|
+
render(<UserForm />);
|
|
420
|
+
|
|
421
|
+
fireEvent.change(screen.getByLabelText('Name'), {
|
|
422
|
+
target: { value: 'Alice' }
|
|
423
|
+
});
|
|
424
|
+
fireEvent.click(screen.getByText('Submit'));
|
|
425
|
+
|
|
426
|
+
await waitFor(() => {
|
|
427
|
+
expect(mockApi.post).toHaveBeenCalledWith('/users', {
|
|
428
|
+
name: 'Alice'
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
});
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Test Completeness Checklist
|
|
435
|
+
|
|
436
|
+
**Before claiming implementation complete:**
|
|
437
|
+
|
|
438
|
+
```
|
|
439
|
+
□ Unit tests written and passing
|
|
440
|
+
- All public functions tested
|
|
441
|
+
- Edge cases covered
|
|
442
|
+
- Error conditions tested
|
|
443
|
+
|
|
444
|
+
□ Integration tests written and passing
|
|
445
|
+
- End-to-end flows tested
|
|
446
|
+
- External dependencies tested
|
|
447
|
+
- Error handling tested
|
|
448
|
+
|
|
449
|
+
□ Test coverage meets threshold (e.g., 80%)
|
|
450
|
+
- Line coverage
|
|
451
|
+
- Branch coverage
|
|
452
|
+
- Critical paths covered
|
|
453
|
+
|
|
454
|
+
□ Tests run in CI/CD pipeline
|
|
455
|
+
- Automated on commits
|
|
456
|
+
- Blocks merge if failing
|
|
457
|
+
|
|
458
|
+
□ Tests document behavior
|
|
459
|
+
- Clear test names
|
|
460
|
+
- Meaningful assertions
|
|
461
|
+
- Edge cases explained
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Gate Function
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
BEFORE claiming implementation complete:
|
|
468
|
+
Ask: "Are tests written?"
|
|
469
|
+
|
|
470
|
+
IF no:
|
|
471
|
+
STOP - Not complete
|
|
472
|
+
Write tests before continuing
|
|
473
|
+
|
|
474
|
+
Ask: "Do tests cover all requirements?"
|
|
475
|
+
|
|
476
|
+
IF no:
|
|
477
|
+
STOP - Incomplete testing
|
|
478
|
+
Add missing test cases
|
|
479
|
+
|
|
480
|
+
Ask: "Did I follow TDD (test-first)?"
|
|
481
|
+
|
|
482
|
+
IF no:
|
|
483
|
+
WARNING - Consider rewriting with TDD
|
|
484
|
+
Tests may be implementation-biased
|
|
485
|
+
|
|
486
|
+
Ask: "Do integration tests pass?"
|
|
487
|
+
|
|
488
|
+
IF no:
|
|
489
|
+
STOP - Not ready for integration
|
|
490
|
+
Fix integration issues
|
|
491
|
+
|
|
492
|
+
Definition of "complete":
|
|
493
|
+
✅ Unit tests written and passing
|
|
494
|
+
✅ Integration tests written and passing
|
|
495
|
+
✅ Coverage meets threshold
|
|
496
|
+
✅ Tests run in CI/CD
|
|
497
|
+
✅ All requirements verified
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Recovery: Adding Tests After Implementation
|
|
501
|
+
|
|
502
|
+
**If tests weren't written first (damage control):**
|
|
503
|
+
|
|
504
|
+
1. **Stop adding features** - Don't dig deeper hole
|
|
505
|
+
2. **Write tests for existing code** - Start with critical paths
|
|
506
|
+
3. **Refactor for testability** - Decouple as needed
|
|
507
|
+
4. **Adopt TDD going forward** - Prevent future occurrence
|
|
508
|
+
|
|
509
|
+
**Prioritization:**
|
|
510
|
+
- **High priority:** Critical business logic, security, data integrity
|
|
511
|
+
- **Medium priority:** Common user flows, API endpoints
|
|
512
|
+
- **Low priority:** UI styling, configuration, one-off scripts
|
|
513
|
+
|
|
514
|
+
**Approach:**
|
|
515
|
+
```typescript
|
|
516
|
+
// 1. Write characterization tests (document current behavior)
|
|
517
|
+
test('current behavior: user registration', async () => {
|
|
518
|
+
const result = await registerUser(userData);
|
|
519
|
+
// Document what currently happens
|
|
520
|
+
expect(result).toMatchSnapshot();
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
// 2. Add specific behavior tests
|
|
524
|
+
test('user registration validates email', async () => {
|
|
525
|
+
await expect(registerUser({ email: 'invalid' }))
|
|
526
|
+
.rejects.toThrow('Invalid email');
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
// 3. Refactor safely with test coverage
|
|
530
|
+
// Now can refactor with confidence
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
## Prevention Through TDD
|
|
534
|
+
|
|
535
|
+
**How TDD prevents completeness anti-patterns:**
|
|
536
|
+
|
|
537
|
+
1. **Incomplete mocks**
|
|
538
|
+
- Writing test first forces understanding of data structures
|
|
539
|
+
- Failing test shows what fields are needed
|
|
540
|
+
- Implementation reveals missing mock fields immediately
|
|
541
|
+
|
|
542
|
+
2. **Tests as afterthought**
|
|
543
|
+
- TDD makes tests part of implementation process
|
|
544
|
+
- Can't write implementation without test
|
|
545
|
+
- Test-first is the workflow, not optional step
|
|
546
|
+
|
|
547
|
+
**TDD workflow enforces:**
|
|
548
|
+
- Complete understanding of requirements (to write test)
|
|
549
|
+
- Complete data structures (test fails if incomplete)
|
|
550
|
+
- Complete coverage (tests drive implementation)
|
|
551
|
+
|
|
552
|
+
See [test-driven-development skill](../../test-driven-development/) for complete TDD workflow.
|
|
553
|
+
|
|
554
|
+
## Real-World Impact
|
|
555
|
+
|
|
556
|
+
**Incomplete mocks:**
|
|
557
|
+
- Tests pass, production breaks
|
|
558
|
+
- Integration issues discovered late
|
|
559
|
+
- False confidence in test suite
|
|
560
|
+
- Difficult debugging (mock ≠ reality)
|
|
561
|
+
|
|
562
|
+
**Tests as afterthought:**
|
|
563
|
+
- Bugs escape to production
|
|
564
|
+
- Implementation hard to test (design issues)
|
|
565
|
+
- Coverage gaps
|
|
566
|
+
- Technical debt from day one
|
|
567
|
+
|
|
568
|
+
**With complete approach:**
|
|
569
|
+
- Tests catch integration issues early
|
|
570
|
+
- High confidence in test suite
|
|
571
|
+
- Testable design from start
|
|
572
|
+
- Complete feature = tested feature
|