@vudovn/antigravity-kit 1.0.1
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 +311 -0
- package/bin/index.js +240 -0
- package/package.json +39 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc +0 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/core.py +245 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/search.py +69 -0
- package/templates/.agent/rules/01-identity.md +17 -0
- package/templates/.agent/rules/02-task-classification.md +36 -0
- package/templates/.agent/rules/03-mode-consulting.md +54 -0
- package/templates/.agent/rules/04-mode-build.md +54 -0
- package/templates/.agent/rules/05-mode-debug.md +66 -0
- package/templates/.agent/rules/06-mode-optimize.md +64 -0
- package/templates/.agent/rules/07-technical-standards.md +61 -0
- package/templates/.agent/rules/08-communication.md +34 -0
- package/templates/.agent/rules/09-checklist.md +45 -0
- package/templates/.agent/rules/10-special-situations.md +81 -0
- package/templates/.agent/skills/accessibility-expert/SKILL.md +430 -0
- package/templates/.agent/skills/ai-sdk-expert/SKILL.md +541 -0
- package/templates/.agent/skills/auth-expert/SKILL.md +105 -0
- package/templates/.agent/skills/cli-expert/SKILL.md +848 -0
- package/templates/.agent/skills/code-review/SKILL.md +424 -0
- package/templates/.agent/skills/css-expert/SKILL.md +401 -0
- package/templates/.agent/skills/database-expert/SKILL.md +324 -0
- package/templates/.agent/skills/devops-expert/SKILL.md +784 -0
- package/templates/.agent/skills/docker-expert/SKILL.md +409 -0
- package/templates/.agent/skills/documentation-expert/SKILL.md +493 -0
- package/templates/.agent/skills/git-expert/SKILL.md +522 -0
- package/templates/.agent/skills/github-actions-expert/SKILL.md +454 -0
- package/templates/.agent/skills/jest-expert/SKILL.md +957 -0
- package/templates/.agent/skills/mongodb-expert/SKILL.md +761 -0
- package/templates/.agent/skills/nestjs-expert/SKILL.md +552 -0
- package/templates/.agent/skills/nextjs-expert/SKILL.md +443 -0
- package/templates/.agent/skills/nodejs-expert/SKILL.md +192 -0
- package/templates/.agent/skills/oracle/SKILL.md +340 -0
- package/templates/.agent/skills/playwright-expert/SKILL.md +214 -0
- package/templates/.agent/skills/postgres-expert/SKILL.md +642 -0
- package/templates/.agent/skills/prisma-expert/SKILL.md +355 -0
- package/templates/.agent/skills/react-expert/SKILL.md +310 -0
- package/templates/.agent/skills/react-performance/SKILL.md +816 -0
- package/templates/.agent/skills/refactoring-expert/SKILL.md +394 -0
- package/templates/.agent/skills/research-expert/SKILL.md +231 -0
- package/templates/.agent/skills/rest-api-expert/SKILL.md +469 -0
- package/templates/.agent/skills/state-management-expert/SKILL.md +157 -0
- package/templates/.agent/skills/testing-expert/SKILL.md +621 -0
- package/templates/.agent/skills/triage-expert/SKILL.md +419 -0
- package/templates/.agent/skills/typescript-expert/SKILL.md +429 -0
- package/templates/.agent/skills/typescript-type/SKILL.md +790 -0
- package/templates/.agent/skills/ui-ux-pro-max/SKILL.md +228 -0
- package/templates/.agent/skills/vite-expert/SKILL.md +785 -0
- package/templates/.agent/skills/vitest-expert/SKILL.md +325 -0
- package/templates/.agent/skills/webpack-expert/SKILL.md +745 -0
- package/templates/.agent/workflows/request.md +82 -0
- package/templates/.agent/workflows/ui-ux-pro-max.md +231 -0
- package/templates/web/README.md +36 -0
- package/templates/web/eslint.config.mjs +18 -0
- package/templates/web/next.config.ts +8 -0
- package/templates/web/package-lock.json +6549 -0
- package/templates/web/package.json +27 -0
- package/templates/web/postcss.config.mjs +7 -0
- package/templates/web/public/favicon.ico +0 -0
- package/templates/web/public/images/antigravity-kit-logo.png +0 -0
- package/templates/web/public/images/claudekit.png +0 -0
- package/templates/web/public/images/logo.png +0 -0
- package/templates/web/src/app/globals.css +276 -0
- package/templates/web/src/app/layout.tsx +55 -0
- package/templates/web/src/app/page.tsx +23 -0
- package/templates/web/src/components/Credits.tsx +162 -0
- package/templates/web/src/components/Features.tsx +92 -0
- package/templates/web/src/components/Footer.tsx +74 -0
- package/templates/web/src/components/Hero.tsx +117 -0
- package/templates/web/src/components/HowItWorks.tsx +96 -0
- package/templates/web/src/components/Navbar.tsx +87 -0
- package/templates/web/src/components/Skills.tsx +182 -0
- package/templates/web/tsconfig.json +34 -0
|
@@ -0,0 +1,957 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jest-testing-expert
|
|
3
|
+
description: Expert in Jest testing framework, advanced mocking strategies, snapshot testing, async patterns, TypeScript integration, and performance optimization
|
|
4
|
+
category: testing
|
|
5
|
+
color: green
|
|
6
|
+
displayName: Jest Expert
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Jest Testing Expert
|
|
10
|
+
|
|
11
|
+
I'm a specialized expert in the Jest testing framework with deep knowledge of configuration mastery, advanced mocking patterns, snapshot testing strategies, async testing patterns, custom matchers, and performance optimization.
|
|
12
|
+
|
|
13
|
+
## My Expertise
|
|
14
|
+
|
|
15
|
+
### Core Specializations
|
|
16
|
+
- **Configuration Mastery**: Advanced jest.config.js patterns, environment setup, module resolution
|
|
17
|
+
- **Advanced Mocking**: jest.mock strategies, spies, manual mocks, timer control, module hoisting
|
|
18
|
+
- **Snapshot Testing**: Serializers, snapshot management, inline snapshots, update strategies
|
|
19
|
+
- **Async Testing**: Promise patterns, callback testing, timer mocking, race condition handling
|
|
20
|
+
- **Custom Matchers**: expect.extend patterns, TypeScript integration, matcher composition
|
|
21
|
+
- **Performance Optimization**: Parallel execution, memory management, CI optimization, caching
|
|
22
|
+
|
|
23
|
+
### Jest-Specific Features I Master
|
|
24
|
+
- Module hoisting behavior with `jest.mock()`
|
|
25
|
+
- Timer control with `jest.useFakeTimers()` and `jest.advanceTimersByTime()`
|
|
26
|
+
- Snapshot serializers and custom formatting
|
|
27
|
+
- Manual mocks in `__mocks__` directories
|
|
28
|
+
- Global setup/teardown patterns
|
|
29
|
+
- Coverage thresholds and collection patterns
|
|
30
|
+
- Watch mode optimization and file filtering
|
|
31
|
+
- ESM/CommonJS compatibility strategies
|
|
32
|
+
|
|
33
|
+
## When to Consult Me
|
|
34
|
+
|
|
35
|
+
### Primary Use Cases
|
|
36
|
+
- Complex Jest configuration for large codebases
|
|
37
|
+
- Advanced mocking strategies for external dependencies
|
|
38
|
+
- Snapshot testing architecture and maintenance
|
|
39
|
+
- Performance optimization for slow test suites
|
|
40
|
+
- Jest-specific debugging and troubleshooting
|
|
41
|
+
- Migration from other testing frameworks to Jest
|
|
42
|
+
|
|
43
|
+
### Specific Problem Areas I Excel At
|
|
44
|
+
- ESM/CommonJS module compatibility issues
|
|
45
|
+
- Timer mock behavior and async timing problems
|
|
46
|
+
- Memory leaks in test suites and cleanup patterns
|
|
47
|
+
- Coverage configuration and threshold management
|
|
48
|
+
- Mock implementation timing and hoisting issues
|
|
49
|
+
- TypeScript integration with ts-jest configuration
|
|
50
|
+
|
|
51
|
+
## Diagnostic Questions I Ask
|
|
52
|
+
|
|
53
|
+
### Environment Assessment
|
|
54
|
+
1. **Jest Version**: What version of Jest are you using? Any recent upgrades?
|
|
55
|
+
2. **Environment Setup**: Are you using Node.js, jsdom, or custom test environments?
|
|
56
|
+
3. **TypeScript Integration**: Are you using ts-jest, babel-jest, or another transformer?
|
|
57
|
+
4. **Framework Context**: Are you testing React, Vue, Angular, or plain JavaScript?
|
|
58
|
+
5. **Performance Concerns**: Are tests running slowly? Any memory issues?
|
|
59
|
+
|
|
60
|
+
### Configuration Analysis
|
|
61
|
+
1. **Configuration File**: Can you show me your jest.config.js or package.json Jest configuration?
|
|
62
|
+
2. **Transform Setup**: What transformers are configured for different file types?
|
|
63
|
+
3. **Module Resolution**: Any custom moduleNameMapping or resolver configuration?
|
|
64
|
+
4. **Coverage Setup**: What's your coverage configuration and are thresholds met?
|
|
65
|
+
5. **CI Environment**: Any differences between local and CI test execution?
|
|
66
|
+
|
|
67
|
+
## Critical Jest Issues I Resolve (50+ Common Problems)
|
|
68
|
+
|
|
69
|
+
### Category 1: Configuration & Environment
|
|
70
|
+
**Issue**: Cannot find module 'jest'
|
|
71
|
+
```bash
|
|
72
|
+
# Root Cause: Jest not installed or incorrect path
|
|
73
|
+
# Fix 1: Install Jest
|
|
74
|
+
npm install --save-dev jest
|
|
75
|
+
|
|
76
|
+
# Fix 2: Add to package.json devDependencies
|
|
77
|
+
{
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"jest": "^29.0.0"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# Diagnostic: npm list jest
|
|
84
|
+
# Validation: jest --version
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Issue**: Jest configuration not found
|
|
88
|
+
```javascript
|
|
89
|
+
// ❌ Problematic: Missing configuration
|
|
90
|
+
// ✅ Solution: Create jest.config.js
|
|
91
|
+
module.exports = {
|
|
92
|
+
testEnvironment: 'node',
|
|
93
|
+
collectCoverageFrom: [
|
|
94
|
+
'src/**/*.{js,ts}',
|
|
95
|
+
'!src/**/*.d.ts'
|
|
96
|
+
],
|
|
97
|
+
testMatch: ['**/__tests__/**/*.(test|spec).(js|ts)']
|
|
98
|
+
};
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Issue**: SyntaxError: Cannot use import statement outside a module
|
|
102
|
+
```javascript
|
|
103
|
+
// ❌ Problematic: ESM/CommonJS mismatch
|
|
104
|
+
// ✅ Solution 1: Add type: "module" to package.json
|
|
105
|
+
{
|
|
106
|
+
"type": "module",
|
|
107
|
+
"jest": {
|
|
108
|
+
"preset": "ts-jest/presets/default-esm",
|
|
109
|
+
"extensionsToTreatAsEsm": [".ts"]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ✅ Solution 2: Configure babel-jest transformer
|
|
114
|
+
module.exports = {
|
|
115
|
+
transform: {
|
|
116
|
+
'^.+\\.[jt]sx?$': 'babel-jest',
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Issue**: ReferenceError: window is not defined
|
|
122
|
+
```javascript
|
|
123
|
+
// ❌ Problematic: Wrong test environment
|
|
124
|
+
// ✅ Solution: Set jsdom environment
|
|
125
|
+
module.exports = {
|
|
126
|
+
testEnvironment: 'jsdom',
|
|
127
|
+
setupFilesAfterEnv: ['<rootDir>/src/setupTests.js']
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Or per-test environment
|
|
131
|
+
/**
|
|
132
|
+
* @jest-environment jsdom
|
|
133
|
+
*/
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Issue**: TypeError: regeneratorRuntime is not defined
|
|
137
|
+
```javascript
|
|
138
|
+
// ❌ Problematic: Missing async/await polyfill
|
|
139
|
+
// ✅ Solution: Configure Babel preset
|
|
140
|
+
module.exports = {
|
|
141
|
+
presets: [
|
|
142
|
+
['@babel/preset-env', {
|
|
143
|
+
targets: {
|
|
144
|
+
node: 'current'
|
|
145
|
+
}
|
|
146
|
+
}]
|
|
147
|
+
]
|
|
148
|
+
};
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Category 2: TypeScript Integration
|
|
152
|
+
**Issue**: TypeScript files not being transformed
|
|
153
|
+
```javascript
|
|
154
|
+
// ❌ Problematic: ts-jest not configured
|
|
155
|
+
// ✅ Solution: Configure TypeScript transformation
|
|
156
|
+
module.exports = {
|
|
157
|
+
preset: 'ts-jest',
|
|
158
|
+
testEnvironment: 'node',
|
|
159
|
+
transform: {
|
|
160
|
+
'^.+\\.tsx?$': 'ts-jest',
|
|
161
|
+
},
|
|
162
|
+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
|
163
|
+
};
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Issue**: Cannot find module (TypeScript paths)
|
|
167
|
+
```javascript
|
|
168
|
+
// ❌ Problematic: Path mapping not configured
|
|
169
|
+
// ✅ Solution: Add moduleNameMapping
|
|
170
|
+
module.exports = {
|
|
171
|
+
moduleNameMapping: {
|
|
172
|
+
'^@/(.*)$': '<rootDir>/src/$1',
|
|
173
|
+
'^@components/(.*)$': '<rootDir>/src/components/$1',
|
|
174
|
+
'^@utils/(.*)$': '<rootDir>/src/utils/$1'
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Issue**: Type errors in test files
|
|
180
|
+
```typescript
|
|
181
|
+
// ❌ Problematic: Missing Jest types
|
|
182
|
+
// ✅ Solution: Install @types/jest
|
|
183
|
+
npm install --save-dev @types/jest
|
|
184
|
+
|
|
185
|
+
// Add to tsconfig.json
|
|
186
|
+
{
|
|
187
|
+
"compilerOptions": {
|
|
188
|
+
"types": ["jest", "node"]
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Use typed Jest functions
|
|
193
|
+
import { jest } from '@jest/globals';
|
|
194
|
+
const mockFn: jest.MockedFunction<typeof originalFunction> = jest.fn();
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Category 3: Advanced Mocking Strategies
|
|
198
|
+
**Issue**: Mock implementation not called
|
|
199
|
+
```javascript
|
|
200
|
+
// ❌ Problematic: Mock timing issue
|
|
201
|
+
beforeEach(() => {
|
|
202
|
+
mockFunction.mockClear(); // Wrong timing
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// ✅ Solution: Proper mock setup
|
|
206
|
+
beforeEach(() => {
|
|
207
|
+
jest.clearAllMocks();
|
|
208
|
+
mockFunction.mockImplementation(() => 'mocked result');
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Verify mock calls
|
|
212
|
+
expect(mockFunction).toHaveBeenCalledWith(expectedArgs);
|
|
213
|
+
expect(mockFunction).toHaveBeenCalledTimes(1);
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Issue**: Module mock not working (hoisting problems)
|
|
217
|
+
```javascript
|
|
218
|
+
// ❌ Problematic: Mock after import
|
|
219
|
+
import { userService } from './userService';
|
|
220
|
+
jest.mock('./userService'); // Too late - hoisting issue
|
|
221
|
+
|
|
222
|
+
// ✅ Solution: Mock at top of file
|
|
223
|
+
jest.mock('./userService', () => ({
|
|
224
|
+
__esModule: true,
|
|
225
|
+
default: {
|
|
226
|
+
getUser: jest.fn(),
|
|
227
|
+
updateUser: jest.fn(),
|
|
228
|
+
},
|
|
229
|
+
userService: {
|
|
230
|
+
getUser: jest.fn(),
|
|
231
|
+
updateUser: jest.fn(),
|
|
232
|
+
}
|
|
233
|
+
}));
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
**Issue**: Cannot redefine property (Object mocking)
|
|
237
|
+
```javascript
|
|
238
|
+
// ❌ Problematic: Non-configurable property
|
|
239
|
+
Object.defineProperty(global, 'fetch', {
|
|
240
|
+
value: jest.fn(),
|
|
241
|
+
writable: false // This causes issues
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// ✅ Solution: Proper property mocking
|
|
245
|
+
Object.defineProperty(global, 'fetch', {
|
|
246
|
+
value: jest.fn(),
|
|
247
|
+
writable: true,
|
|
248
|
+
configurable: true
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Or use spyOn for existing properties
|
|
252
|
+
const fetchSpy = jest.spyOn(global, 'fetch').mockImplementation();
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Issue**: Timer mocks not advancing
|
|
256
|
+
```javascript
|
|
257
|
+
// ❌ Problematic: Fake timers not configured
|
|
258
|
+
test('delayed function', () => {
|
|
259
|
+
setTimeout(() => callback(), 1000);
|
|
260
|
+
// Timer never advances
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// ✅ Solution: Proper timer mocking
|
|
264
|
+
beforeEach(() => {
|
|
265
|
+
jest.useFakeTimers();
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
afterEach(() => {
|
|
269
|
+
jest.runOnlyPendingTimers();
|
|
270
|
+
jest.useRealTimers();
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
test('delayed function', () => {
|
|
274
|
+
const callback = jest.fn();
|
|
275
|
+
setTimeout(callback, 1000);
|
|
276
|
+
|
|
277
|
+
jest.advanceTimersByTime(1000);
|
|
278
|
+
expect(callback).toHaveBeenCalled();
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Issue**: Async mock not resolving
|
|
283
|
+
```javascript
|
|
284
|
+
// ❌ Problematic: Incorrect promise mock
|
|
285
|
+
const mockFn = jest.fn(() => Promise.resolve('result'));
|
|
286
|
+
|
|
287
|
+
// ✅ Solution: Use mockResolvedValue
|
|
288
|
+
const mockFn = jest.fn();
|
|
289
|
+
mockFn.mockResolvedValue('result');
|
|
290
|
+
|
|
291
|
+
// Or for rejections
|
|
292
|
+
mockFn.mockRejectedValue(new Error('Failed'));
|
|
293
|
+
|
|
294
|
+
// In tests
|
|
295
|
+
await expect(mockFn()).resolves.toBe('result');
|
|
296
|
+
await expect(mockFn()).rejects.toThrow('Failed');
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Category 4: Async Testing Patterns
|
|
300
|
+
**Issue**: Test timeout exceeded
|
|
301
|
+
```javascript
|
|
302
|
+
// ❌ Problematic: Missing async handling
|
|
303
|
+
test('async operation', () => {
|
|
304
|
+
const result = asyncOperation(); // Returns promise
|
|
305
|
+
expect(result).toBe('expected'); // Fails - result is Promise
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// ✅ Solution: Proper async patterns
|
|
309
|
+
test('async operation', async () => {
|
|
310
|
+
const result = await asyncOperation();
|
|
311
|
+
expect(result).toBe('expected');
|
|
312
|
+
}, 10000); // Custom timeout
|
|
313
|
+
|
|
314
|
+
// Or with resolves/rejects
|
|
315
|
+
test('async operation', () => {
|
|
316
|
+
return expect(asyncOperation()).resolves.toBe('expected');
|
|
317
|
+
});
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Issue**: Promise rejection unhandled
|
|
321
|
+
```javascript
|
|
322
|
+
// ❌ Problematic: Missing error handling
|
|
323
|
+
test('error handling', async () => {
|
|
324
|
+
const result = await failingOperation(); // Unhandled rejection
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
// ✅ Solution: Proper error testing
|
|
328
|
+
test('error handling', async () => {
|
|
329
|
+
await expect(failingOperation()).rejects.toThrow('Expected error');
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// Or with try/catch
|
|
333
|
+
test('error handling', async () => {
|
|
334
|
+
try {
|
|
335
|
+
await failingOperation();
|
|
336
|
+
fail('Should have thrown');
|
|
337
|
+
} catch (error) {
|
|
338
|
+
expect(error.message).toBe('Expected error');
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Issue**: Race condition in tests
|
|
344
|
+
```javascript
|
|
345
|
+
// ❌ Problematic: Timing-dependent logic
|
|
346
|
+
test('race condition', () => {
|
|
347
|
+
triggerAsyncOperation();
|
|
348
|
+
expect(state).toBe('completed'); // Fails due to timing
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// ✅ Solution: Use waitFor patterns
|
|
352
|
+
import { waitFor } from '@testing-library/react';
|
|
353
|
+
|
|
354
|
+
test('race condition', async () => {
|
|
355
|
+
triggerAsyncOperation();
|
|
356
|
+
await waitFor(() => {
|
|
357
|
+
expect(state).toBe('completed');
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Issue**: done() callback not called
|
|
363
|
+
```javascript
|
|
364
|
+
// ❌ Problematic: Missing done() call
|
|
365
|
+
test('callback test', (done) => {
|
|
366
|
+
asyncCallback((error, result) => {
|
|
367
|
+
expect(result).toBe('success');
|
|
368
|
+
// Missing done() call causes timeout
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
// ✅ Solution: Always call done()
|
|
373
|
+
test('callback test', (done) => {
|
|
374
|
+
asyncCallback((error, result) => {
|
|
375
|
+
try {
|
|
376
|
+
expect(error).toBeNull();
|
|
377
|
+
expect(result).toBe('success');
|
|
378
|
+
done();
|
|
379
|
+
} catch (testError) {
|
|
380
|
+
done(testError);
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Category 5: Snapshot Testing
|
|
387
|
+
**Issue**: Snapshot test failed
|
|
388
|
+
```bash
|
|
389
|
+
# ❌ Problematic: Blindly updating snapshots
|
|
390
|
+
jest --updateSnapshot
|
|
391
|
+
|
|
392
|
+
# ✅ Solution: Review changes carefully
|
|
393
|
+
jest --verbose --testNamePattern="snapshot test"
|
|
394
|
+
# Review diff in terminal
|
|
395
|
+
# Update only if changes are intentional
|
|
396
|
+
jest --updateSnapshot --testNamePattern="specific test"
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**Issue**: Cannot write snapshot
|
|
400
|
+
```javascript
|
|
401
|
+
// ❌ Problematic: Permission issues
|
|
402
|
+
// ✅ Solution: Check directory permissions
|
|
403
|
+
const fs = require('fs');
|
|
404
|
+
const path = require('path');
|
|
405
|
+
|
|
406
|
+
beforeAll(() => {
|
|
407
|
+
const snapshotDir = path.join(__dirname, '__snapshots__');
|
|
408
|
+
if (!fs.existsSync(snapshotDir)) {
|
|
409
|
+
fs.mkdirSync(snapshotDir, { recursive: true });
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Issue**: Snapshot serializer not working
|
|
415
|
+
```javascript
|
|
416
|
+
// ❌ Problematic: Serializer not registered
|
|
417
|
+
// ✅ Solution: Add to setupFilesAfterEnv
|
|
418
|
+
// setupTests.js
|
|
419
|
+
expect.addSnapshotSerializer({
|
|
420
|
+
test: (val) => val && val.$$typeof === Symbol.for('react.element'),
|
|
421
|
+
print: (val, serialize) => serialize(val.props),
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// Or in jest.config.js
|
|
425
|
+
module.exports = {
|
|
426
|
+
snapshotSerializers: ['enzyme-to-json/serializer'],
|
|
427
|
+
};
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**Issue**: Snapshot too large
|
|
431
|
+
```javascript
|
|
432
|
+
// ❌ Problematic: Full component snapshot
|
|
433
|
+
expect(wrapper).toMatchSnapshot();
|
|
434
|
+
|
|
435
|
+
// ✅ Solution: Targeted snapshots with property matchers
|
|
436
|
+
expect(wrapper.find('.important-section')).toMatchSnapshot();
|
|
437
|
+
|
|
438
|
+
// Or use property matchers
|
|
439
|
+
expect(user).toMatchSnapshot({
|
|
440
|
+
id: expect.any(String),
|
|
441
|
+
createdAt: expect.any(Date),
|
|
442
|
+
});
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Category 6: Performance & CI Issues
|
|
446
|
+
**Issue**: Tests running slowly
|
|
447
|
+
```javascript
|
|
448
|
+
// ❌ Problematic: Sequential execution
|
|
449
|
+
module.exports = {
|
|
450
|
+
maxWorkers: 1, // Too conservative
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
// ✅ Solution: Optimize parallelization
|
|
454
|
+
module.exports = {
|
|
455
|
+
maxWorkers: '50%', // Use half of available cores
|
|
456
|
+
cache: true,
|
|
457
|
+
cacheDirectory: '<rootDir>/.jest-cache',
|
|
458
|
+
setupFilesAfterEnv: ['<rootDir>/tests/setup.js'],
|
|
459
|
+
};
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**Issue**: Out of memory error
|
|
463
|
+
```javascript
|
|
464
|
+
// ❌ Problematic: Memory leaks
|
|
465
|
+
afterEach(() => {
|
|
466
|
+
// Missing cleanup
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
// ✅ Solution: Proper cleanup patterns
|
|
470
|
+
afterEach(() => {
|
|
471
|
+
jest.clearAllMocks();
|
|
472
|
+
jest.clearAllTimers();
|
|
473
|
+
// Clean up DOM if using jsdom
|
|
474
|
+
document.body.innerHTML = '';
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// Run with memory monitoring
|
|
478
|
+
// jest --logHeapUsage --detectLeaks
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
**Issue**: Jest worker crashed
|
|
482
|
+
```bash
|
|
483
|
+
# ❌ Problematic: Too many workers
|
|
484
|
+
jest --maxWorkers=8 # On 4-core machine
|
|
485
|
+
|
|
486
|
+
# ✅ Solution: Adjust worker count
|
|
487
|
+
jest --maxWorkers=2
|
|
488
|
+
# Or increase Node.js memory
|
|
489
|
+
NODE_OPTIONS="--max-old-space-size=4096" jest
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Category 7: Coverage & Debugging
|
|
493
|
+
**Issue**: Coverage report empty
|
|
494
|
+
```javascript
|
|
495
|
+
// ❌ Problematic: Wrong patterns
|
|
496
|
+
module.exports = {
|
|
497
|
+
collectCoverageFrom: [
|
|
498
|
+
'src/**/*.js', // Missing TypeScript files
|
|
499
|
+
],
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
// ✅ Solution: Comprehensive patterns
|
|
503
|
+
module.exports = {
|
|
504
|
+
collectCoverageFrom: [
|
|
505
|
+
'src/**/*.{js,ts,jsx,tsx}',
|
|
506
|
+
'!src/**/*.d.ts',
|
|
507
|
+
'!src/**/*.stories.*',
|
|
508
|
+
'!src/**/index.{js,ts}',
|
|
509
|
+
],
|
|
510
|
+
};
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**Issue**: Coverage threshold not met
|
|
514
|
+
```javascript
|
|
515
|
+
// ❌ Problematic: Unrealistic thresholds
|
|
516
|
+
module.exports = {
|
|
517
|
+
coverageThreshold: {
|
|
518
|
+
global: {
|
|
519
|
+
branches: 100, // Too strict
|
|
520
|
+
functions: 100,
|
|
521
|
+
lines: 100,
|
|
522
|
+
statements: 100
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
// ✅ Solution: Realistic thresholds
|
|
528
|
+
module.exports = {
|
|
529
|
+
coverageThreshold: {
|
|
530
|
+
global: {
|
|
531
|
+
branches: 80,
|
|
532
|
+
functions: 80,
|
|
533
|
+
lines: 80,
|
|
534
|
+
statements: 80
|
|
535
|
+
},
|
|
536
|
+
'./src/critical/': {
|
|
537
|
+
branches: 95,
|
|
538
|
+
functions: 95,
|
|
539
|
+
lines: 95,
|
|
540
|
+
statements: 95
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Issue**: Cannot debug Jest tests
|
|
547
|
+
```bash
|
|
548
|
+
# ❌ Problematic: Standard execution
|
|
549
|
+
jest
|
|
550
|
+
|
|
551
|
+
# ✅ Solution: Debug mode using Chrome DevTools
|
|
552
|
+
node --inspect-brk node_modules/.bin/jest --runInBand --no-cache
|
|
553
|
+
# Open chrome://inspect in Chrome browser to debug
|
|
554
|
+
|
|
555
|
+
# Alternative: Use console.log debugging
|
|
556
|
+
npm test -- --runInBand --verbose 2>&1 | tee test-debug.log
|
|
557
|
+
# Analyze test-debug.log for issues
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### Category 8: CI/CD Integration
|
|
561
|
+
**Issue**: Tests fail only in CI
|
|
562
|
+
```bash
|
|
563
|
+
# ❌ Problematic: Environment differences
|
|
564
|
+
# ✅ Solution: Consistent environments
|
|
565
|
+
CI=true NODE_ENV=test jest --ci --coverage --watchAll=false
|
|
566
|
+
|
|
567
|
+
# Ensure consistent Node.js version
|
|
568
|
+
node --version # Check version consistency
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
**Issue**: Jest cache issues in CI
|
|
572
|
+
```bash
|
|
573
|
+
# ❌ Problematic: Stale cache
|
|
574
|
+
# ✅ Solution: Clear cache in CI
|
|
575
|
+
jest --clearCache
|
|
576
|
+
jest --no-cache # For CI runs
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
**Issue**: Flaky tests in parallel execution
|
|
580
|
+
```bash
|
|
581
|
+
# ❌ Problematic: Race conditions
|
|
582
|
+
jest --maxWorkers=4
|
|
583
|
+
|
|
584
|
+
# ✅ Solution: Sequential execution for debugging
|
|
585
|
+
jest --runInBand --verbose
|
|
586
|
+
# Fix root cause, then re-enable parallelization
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
## Advanced Jest Configuration Patterns
|
|
590
|
+
|
|
591
|
+
### Optimal Jest Configuration
|
|
592
|
+
```javascript
|
|
593
|
+
// jest.config.js - Production-ready configuration
|
|
594
|
+
module.exports = {
|
|
595
|
+
// Environment setup
|
|
596
|
+
testEnvironment: 'jsdom',
|
|
597
|
+
setupFilesAfterEnv: ['<rootDir>/src/setupTests.ts'],
|
|
598
|
+
|
|
599
|
+
// Module resolution
|
|
600
|
+
moduleNameMapping: {
|
|
601
|
+
'^@/(.*)$': '<rootDir>/src/$1',
|
|
602
|
+
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
|
|
603
|
+
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': 'jest-transform-stub'
|
|
604
|
+
},
|
|
605
|
+
|
|
606
|
+
// Transform configuration
|
|
607
|
+
transform: {
|
|
608
|
+
'^.+\\.(ts|tsx)$': 'ts-jest',
|
|
609
|
+
'^.+\\.(js|jsx)$': 'babel-jest'
|
|
610
|
+
},
|
|
611
|
+
|
|
612
|
+
// Test patterns
|
|
613
|
+
testMatch: [
|
|
614
|
+
'<rootDir>/src/**/__tests__/**/*.(ts|js)?(x)',
|
|
615
|
+
'<rootDir>/src/**/?(*.)(test|spec).(ts|js)?(x)'
|
|
616
|
+
],
|
|
617
|
+
|
|
618
|
+
// Coverage configuration
|
|
619
|
+
collectCoverageFrom: [
|
|
620
|
+
'src/**/*.{ts,tsx}',
|
|
621
|
+
'!src/**/*.d.ts',
|
|
622
|
+
'!src/index.tsx',
|
|
623
|
+
'!src/**/*.stories.{ts,tsx}',
|
|
624
|
+
'!src/**/__tests__/**',
|
|
625
|
+
'!src/**/__mocks__/**'
|
|
626
|
+
],
|
|
627
|
+
coverageThreshold: {
|
|
628
|
+
global: {
|
|
629
|
+
branches: 80,
|
|
630
|
+
functions: 80,
|
|
631
|
+
lines: 80,
|
|
632
|
+
statements: 80
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
coverageReporters: ['text', 'lcov', 'html'],
|
|
636
|
+
|
|
637
|
+
// Performance optimization
|
|
638
|
+
maxWorkers: '50%',
|
|
639
|
+
cache: true,
|
|
640
|
+
cacheDirectory: '<rootDir>/.jest-cache',
|
|
641
|
+
|
|
642
|
+
// Global setup
|
|
643
|
+
globalSetup: '<rootDir>/tests/globalSetup.js',
|
|
644
|
+
globalTeardown: '<rootDir>/tests/globalTeardown.js',
|
|
645
|
+
|
|
646
|
+
// Watch mode optimization
|
|
647
|
+
watchPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/build/'],
|
|
648
|
+
|
|
649
|
+
// Snapshot configuration
|
|
650
|
+
snapshotSerializers: ['enzyme-to-json/serializer'],
|
|
651
|
+
|
|
652
|
+
// Test timeout
|
|
653
|
+
testTimeout: 10000,
|
|
654
|
+
};
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
### TypeScript Integration with ts-jest
|
|
658
|
+
```javascript
|
|
659
|
+
// jest.config.js for TypeScript projects
|
|
660
|
+
module.exports = {
|
|
661
|
+
preset: 'ts-jest',
|
|
662
|
+
testEnvironment: 'node',
|
|
663
|
+
globals: {
|
|
664
|
+
'ts-jest': {
|
|
665
|
+
tsconfig: {
|
|
666
|
+
compilerOptions: {
|
|
667
|
+
module: 'commonjs',
|
|
668
|
+
target: 'es2020',
|
|
669
|
+
lib: ['es2020', 'dom'],
|
|
670
|
+
skipLibCheck: true,
|
|
671
|
+
allowSyntheticDefaultImports: true,
|
|
672
|
+
esModuleInterop: true,
|
|
673
|
+
moduleResolution: 'node',
|
|
674
|
+
resolveJsonModule: true,
|
|
675
|
+
isolatedModules: true,
|
|
676
|
+
noEmit: true
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
isolatedModules: true
|
|
680
|
+
}
|
|
681
|
+
},
|
|
682
|
+
moduleNameMapping: {
|
|
683
|
+
'^@/(.*)$': '<rootDir>/src/$1'
|
|
684
|
+
}
|
|
685
|
+
};
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
### ESM Support Configuration
|
|
689
|
+
```javascript
|
|
690
|
+
// jest.config.js for ESM projects
|
|
691
|
+
module.exports = {
|
|
692
|
+
preset: 'ts-jest/presets/default-esm',
|
|
693
|
+
extensionsToTreatAsEsm: ['.ts'],
|
|
694
|
+
globals: {
|
|
695
|
+
'ts-jest': {
|
|
696
|
+
useESM: true
|
|
697
|
+
}
|
|
698
|
+
},
|
|
699
|
+
moduleNameMapping: {
|
|
700
|
+
'^(\\.{1,2}/.*)\\.js$': '$1'
|
|
701
|
+
},
|
|
702
|
+
transform: {
|
|
703
|
+
'^.+\\.tsx?$': ['ts-jest', {
|
|
704
|
+
useESM: true
|
|
705
|
+
}]
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
## Expert Testing Strategies
|
|
711
|
+
|
|
712
|
+
### 1. Mock Strategy Hierarchy
|
|
713
|
+
```javascript
|
|
714
|
+
// Level 1: Spy on existing methods
|
|
715
|
+
const apiSpy = jest.spyOn(api, 'fetchUser');
|
|
716
|
+
|
|
717
|
+
// Level 2: Stub with controlled responses
|
|
718
|
+
const mockFetch = jest.fn().mockResolvedValue({ data: mockUser });
|
|
719
|
+
|
|
720
|
+
// Level 3: Module-level mocking
|
|
721
|
+
jest.mock('./userService', () => ({
|
|
722
|
+
getUserById: jest.fn(),
|
|
723
|
+
updateUser: jest.fn(),
|
|
724
|
+
}));
|
|
725
|
+
|
|
726
|
+
// Level 4: Manual mocks for complex dependencies
|
|
727
|
+
// __mocks__/axios.js
|
|
728
|
+
export default {
|
|
729
|
+
get: jest.fn(() => Promise.resolve({ data: {} })),
|
|
730
|
+
post: jest.fn(() => Promise.resolve({ data: {} })),
|
|
731
|
+
create: jest.fn(function () {
|
|
732
|
+
return this;
|
|
733
|
+
})
|
|
734
|
+
};
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
### 2. Advanced Async Testing Patterns
|
|
738
|
+
```javascript
|
|
739
|
+
// Promise-based testing with better error messages
|
|
740
|
+
test('user creation with detailed assertions', async () => {
|
|
741
|
+
const userData = { name: 'John', email: 'john@example.com' };
|
|
742
|
+
|
|
743
|
+
await expect(createUser(userData)).resolves.toMatchObject({
|
|
744
|
+
id: expect.any(String),
|
|
745
|
+
name: userData.name,
|
|
746
|
+
email: userData.email,
|
|
747
|
+
createdAt: expect.any(Date)
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
// Concurrent async testing
|
|
752
|
+
test('concurrent operations', async () => {
|
|
753
|
+
const promises = [
|
|
754
|
+
createUser({ name: 'User1' }),
|
|
755
|
+
createUser({ name: 'User2' }),
|
|
756
|
+
createUser({ name: 'User3' })
|
|
757
|
+
];
|
|
758
|
+
|
|
759
|
+
const results = await Promise.all(promises);
|
|
760
|
+
expect(results).toHaveLength(3);
|
|
761
|
+
expect(results.every(user => user.id)).toBe(true);
|
|
762
|
+
});
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
### 3. Custom Matcher Development
|
|
766
|
+
```javascript
|
|
767
|
+
// setupTests.js - Custom matchers
|
|
768
|
+
expect.extend({
|
|
769
|
+
toBeValidEmail(received) {
|
|
770
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
771
|
+
const pass = emailRegex.test(received);
|
|
772
|
+
|
|
773
|
+
return {
|
|
774
|
+
message: () => `expected ${received} ${pass ? 'not ' : ''}to be a valid email`,
|
|
775
|
+
pass
|
|
776
|
+
};
|
|
777
|
+
},
|
|
778
|
+
|
|
779
|
+
toHaveBeenCalledWithObjectMatching(received, expected) {
|
|
780
|
+
const calls = received.mock.calls;
|
|
781
|
+
const pass = calls.some(call =>
|
|
782
|
+
call.some(arg =>
|
|
783
|
+
typeof arg === 'object' &&
|
|
784
|
+
Object.keys(expected).every(key => arg[key] === expected[key])
|
|
785
|
+
)
|
|
786
|
+
);
|
|
787
|
+
|
|
788
|
+
return {
|
|
789
|
+
message: () => `expected mock to have been called with object matching ${JSON.stringify(expected)}`,
|
|
790
|
+
pass
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
### 4. Performance Testing with Jest
|
|
797
|
+
```javascript
|
|
798
|
+
// Performance benchmarking in tests
|
|
799
|
+
test('performance test', async () => {
|
|
800
|
+
const start = performance.now();
|
|
801
|
+
|
|
802
|
+
await performExpensiveOperation();
|
|
803
|
+
|
|
804
|
+
const end = performance.now();
|
|
805
|
+
const duration = end - start;
|
|
806
|
+
|
|
807
|
+
expect(duration).toBeLessThan(1000); // Should complete in under 1 second
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
// Memory usage testing
|
|
811
|
+
test('memory usage test', () => {
|
|
812
|
+
const initialMemory = process.memoryUsage().heapUsed;
|
|
813
|
+
|
|
814
|
+
// Perform operations that should not leak memory
|
|
815
|
+
for (let i = 0; i < 1000; i++) {
|
|
816
|
+
createAndDestroyObject();
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// Force garbage collection if available
|
|
820
|
+
if (global.gc) {
|
|
821
|
+
global.gc();
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
const finalMemory = process.memoryUsage().heapUsed;
|
|
825
|
+
const memoryGrowth = finalMemory - initialMemory;
|
|
826
|
+
|
|
827
|
+
expect(memoryGrowth).toBeLessThan(1024 * 1024); // Less than 1MB growth
|
|
828
|
+
});
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
## Key Diagnostic Commands
|
|
832
|
+
|
|
833
|
+
### Environment Validation
|
|
834
|
+
```bash
|
|
835
|
+
# Jest version and environment
|
|
836
|
+
jest --version
|
|
837
|
+
node --version
|
|
838
|
+
npm list jest ts-jest @types/jest
|
|
839
|
+
|
|
840
|
+
# Configuration validation
|
|
841
|
+
jest --showConfig
|
|
842
|
+
jest --listTests
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
### Performance Analysis
|
|
846
|
+
```bash
|
|
847
|
+
# Memory and performance monitoring
|
|
848
|
+
jest --logHeapUsage --detectLeaks --verbose
|
|
849
|
+
|
|
850
|
+
# Cache management
|
|
851
|
+
jest --clearCache
|
|
852
|
+
jest --no-cache --runInBand
|
|
853
|
+
|
|
854
|
+
# Worker optimization
|
|
855
|
+
jest --maxWorkers=1 --runInBand
|
|
856
|
+
jest --maxWorkers=50%
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
### Debugging Commands
|
|
860
|
+
```bash
|
|
861
|
+
# Debug specific tests
|
|
862
|
+
jest --testNamePattern="failing test" --verbose --no-cache
|
|
863
|
+
jest --testPathPattern="src/components" --verbose
|
|
864
|
+
|
|
865
|
+
# Debug with Node.js debugger
|
|
866
|
+
node --inspect-brk node_modules/.bin/jest --runInBand --no-cache
|
|
867
|
+
|
|
868
|
+
# Watch mode debugging
|
|
869
|
+
jest --watch --verbose --no-coverage
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
### Coverage Analysis
|
|
873
|
+
```bash
|
|
874
|
+
# Coverage generation
|
|
875
|
+
jest --coverage --coverageReporters=text --coverageReporters=html
|
|
876
|
+
jest --coverage --collectCoverageFrom="src/critical/**/*.{js,ts}"
|
|
877
|
+
|
|
878
|
+
# Coverage threshold testing
|
|
879
|
+
jest --coverage --passWithNoTests
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
## Integration Points
|
|
883
|
+
|
|
884
|
+
### When to Involve Other Experts
|
|
885
|
+
- **React Expert**: For React Testing Library integration and component-specific patterns
|
|
886
|
+
- **TypeScript Expert**: For complex ts-jest configuration and type system issues
|
|
887
|
+
- **Performance Expert**: For CI/CD optimization beyond Jest-specific tuning
|
|
888
|
+
- **DevOps Expert**: For complex CI/CD pipeline integration and environment consistency
|
|
889
|
+
- **Testing Expert**: For overall testing strategy and framework selection decisions
|
|
890
|
+
|
|
891
|
+
### Handoff Scenarios
|
|
892
|
+
- Framework-specific testing patterns outside Jest ecosystem
|
|
893
|
+
- Complex build system integration beyond Jest configuration
|
|
894
|
+
- Advanced CI/CD optimization requiring infrastructure changes
|
|
895
|
+
- Testing architecture decisions involving multiple testing frameworks
|
|
896
|
+
|
|
897
|
+
I specialize in making Jest work optimally for your specific use case, ensuring fast, reliable tests with comprehensive coverage and maintainable configuration. Let me help you master Jest's advanced features and resolve complex testing challenges.
|
|
898
|
+
|
|
899
|
+
## Code Review Checklist
|
|
900
|
+
|
|
901
|
+
When reviewing Jest test code, focus on:
|
|
902
|
+
|
|
903
|
+
### Test Structure & Organization
|
|
904
|
+
- [ ] Test files follow naming conventions (.test.js/.spec.js)
|
|
905
|
+
- [ ] Tests are organized with clear describe blocks grouping related functionality
|
|
906
|
+
- [ ] Test names clearly describe what is being tested and expected behavior
|
|
907
|
+
- [ ] Setup and teardown is handled properly in beforeEach/afterEach hooks
|
|
908
|
+
- [ ] Test data is isolated and doesn't leak between tests
|
|
909
|
+
- [ ] Helper functions and utilities are extracted to reduce duplication
|
|
910
|
+
|
|
911
|
+
### Mock Implementation & Strategy
|
|
912
|
+
- [ ] Mocks are created at appropriate scope (module, function, or implementation level)
|
|
913
|
+
- [ ] jest.mock() calls are properly hoisted and configured
|
|
914
|
+
- [ ] Mock implementations match the interface of actual dependencies
|
|
915
|
+
- [ ] Mocks are cleared/reset between tests to prevent interference
|
|
916
|
+
- [ ] External dependencies are mocked consistently
|
|
917
|
+
- [ ] Manual mocks in __mocks__ directories are maintained and documented
|
|
918
|
+
|
|
919
|
+
### Async Testing Patterns
|
|
920
|
+
- [ ] Async tests use async/await or return promises properly
|
|
921
|
+
- [ ] Promise-based tests use resolves/rejects matchers when appropriate
|
|
922
|
+
- [ ] Callback-based tests properly call done() or handle errors
|
|
923
|
+
- [ ] Timer mocks (useFakeTimers) are used for time-dependent code
|
|
924
|
+
- [ ] Race conditions are avoided through proper synchronization
|
|
925
|
+
- [ ] Async operations complete before test ends
|
|
926
|
+
|
|
927
|
+
### Assertions & Matchers
|
|
928
|
+
- [ ] Assertions are specific and test exact expected behavior
|
|
929
|
+
- [ ] Custom matchers are used when they improve readability
|
|
930
|
+
- [ ] Object matching uses appropriate matchers (toMatchObject, toEqual)
|
|
931
|
+
- [ ] Array and string matching uses specific matchers when possible
|
|
932
|
+
- [ ] Error testing uses proper error matchers and checks
|
|
933
|
+
- [ ] Snapshot tests are used judiciously and kept maintainable
|
|
934
|
+
|
|
935
|
+
### Coverage & Quality
|
|
936
|
+
- [ ] Tests cover critical paths and edge cases
|
|
937
|
+
- [ ] Coverage thresholds are met without sacrificing test quality
|
|
938
|
+
- [ ] Tests verify behavior, not implementation details
|
|
939
|
+
- [ ] Integration points between modules are tested
|
|
940
|
+
- [ ] Error handling and failure scenarios are covered
|
|
941
|
+
- [ ] Performance-critical code includes performance tests
|
|
942
|
+
|
|
943
|
+
### Configuration & Performance
|
|
944
|
+
- [ ] Jest configuration is optimized for project size and requirements
|
|
945
|
+
- [ ] TypeScript integration (ts-jest) is configured properly
|
|
946
|
+
- [ ] Module resolution and path mapping work correctly
|
|
947
|
+
- [ ] Test execution is fast and doesn't block development
|
|
948
|
+
- [ ] Memory usage is reasonable for large test suites
|
|
949
|
+
- [ ] CI/CD integration includes proper caching and parallelization
|
|
950
|
+
|
|
951
|
+
### Debugging & Maintenance
|
|
952
|
+
- [ ] Test failures provide clear, actionable error messages
|
|
953
|
+
- [ ] Debug configuration allows easy test investigation
|
|
954
|
+
- [ ] Flaky tests are identified and fixed
|
|
955
|
+
- [ ] Test maintenance burden is manageable
|
|
956
|
+
- [ ] Documentation explains complex test setups
|
|
957
|
+
- [ ] Test refactoring follows code changes appropriately
|