You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .github/instructions/testing-workflow.instructions.md
+25-22Lines changed: 25 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -55,7 +55,7 @@ When implementing tests as an AI agent, choose between two main types:
55
55
56
56
### Primary Tool: `runTests`
57
57
58
-
Use the `runTests` tool to execute tests programmatically:
58
+
Use the `runTests` tool to execute tests programmatically rather than terminal commands for better integration and result parsing:
59
59
60
60
```typescript
61
61
// Run specific test files
@@ -80,7 +80,7 @@ await runTests({
80
80
81
81
### Compilation Requirements
82
82
83
-
Before running tests, ensure compilation:
83
+
Before running tests, ensure compilation. Always start compilation with `npm run watch-tests` before test execution to ensure TypeScript files are built. Recompile after making import/export changes before running tests, as stubs won't work if they're applied to old compiled JavaScript that doesn't have the updated imports:
84
84
85
85
```typescript
86
86
// Start watch mode for auto-compilation
@@ -100,7 +100,7 @@ await run_in_terminal({
100
100
101
101
### Alternative: Terminal Execution
102
102
103
-
For targeted test runs when `runTests` tool is unavailable:
103
+
For targeted test runs when `runTests` tool is unavailable. Note: When a targeted test run yields 0 tests, first verify the compiled JS exists under `out/test` (rootDir is `src`); absence almost always means the test file sits outside `src` or compilation hasn't run yet:
104
104
105
105
```typescript
106
106
// Run specific test suite
@@ -145,6 +145,8 @@ if (error.includes('AssertionError')) {
145
145
146
146
### Systematic Failure Analysis
147
147
148
+
Fix test issues iteratively - run tests, analyze failures, apply fixes, repeat until passing. When unit tests fail with VS Code API errors like `TypeError: X is not a constructor` or `Cannot read properties of undefined (reading 'Y')`, check if VS Code APIs are properly mocked in `/src/test/unittests.ts` - add missing APIs following the existing pattern.
Create minimal mock objects with only required methods and use TypeScript type assertions (e.g., `mockApi as PythonEnvironmentApi`) to satisfy interface requirements instead of implementing all interface methods when only specific methods are needed for the test. Simplify mock setup by only mocking methods actually used in tests and use `as unknown as Type` for TypeScript compatibility.
// Call the function first to get a promise, then use setTimeout to emit mock events,
505
+
// then await the promise - this ensures proper timing of mock setup versus function execution
506
+
507
+
// Cannot stub internal function calls within the same module after import - stub external
508
+
// dependencies instead (e.g., stub childProcessApis.spawnProcess rather than trying to stub
509
+
// helpers.isUvInstalled when testing helpers.shouldUseUv) because intra-module calls use
510
+
// direct references, not module exports
493
511
```
494
512
495
513
## 🧪 Step 7: Test Categories and Patterns
@@ -499,6 +517,7 @@ envConfig.inspect
499
517
- Test different setting combinations
500
518
- Test setting precedence (workspace > user > default)
501
519
- Test configuration errors and recovery
520
+
- Always use dynamic path construction with Node.js `path` module when testing functions that resolve paths against workspace folders to ensure cross-platform compatibility
502
521
503
522
### Data Flow Tests
504
523
@@ -543,31 +562,15 @@ envConfig.inspect
543
562
544
563
1.**Read test files** - Check structure and mock setup
3.**Apply improvements** - Use patterns below. When reviewing existing tests, focus on behavior rather than implementation details in test names and assertions
547
566
4.**Verify** - Ensure tests still pass
548
567
549
568
### Common Fixes
550
569
551
570
- Over-complex mocks → Minimal mocks with only needed methods
552
571
- Brittle assertions → Behavior-focused with error messages
553
-
- Vague test names → Clear scenario descriptions
572
+
- Vague test names → Clear scenario descriptions (transform "should return X when Y" into "should [expected behavior] when [scenario context]")
554
573
- Missing structure → Mock → Run → Assert pattern
574
+
- Untestable Node.js APIs → Create proxy abstraction functions (use function overloads to preserve intelligent typing while making functions mockable)
555
575
556
576
## 🧠 Agent Learnings
557
-
558
-
- Always use dynamic path construction with Node.js `path` module when testing functions that resolve paths against workspace folders to ensure cross-platform compatibility (1)
559
-
- Use `runTests` tool for programmatic test execution rather than terminal commands for better integration and result parsing (1)
560
-
- Mock wrapper functions (e.g., `workspaceApis.getConfiguration()`) instead of VS Code APIs directly to avoid stubbing issues (2)
561
-
- Start compilation with `npm run watch-tests` before test execution to ensure TypeScript files are built (1)
562
-
- Use `sinon.match()` patterns for resilient assertions that don't break on minor output changes (2)
563
-
- Fix test issues iteratively - run tests, analyze failures, apply fixes, repeat until passing (1)
564
-
- When fixing mock environment creation, use `null` to truly omit properties rather than `undefined` (1)
565
-
- Always recompile TypeScript after making import/export changes before running tests, as stubs won't work if they're applied to old compiled JavaScript that doesn't have the updated imports (2)
566
-
- Create proxy abstraction functions for Node.js APIs like `cp.spawn` to enable clean testing - use function overloads to preserve Node.js's intelligent typing while making the functions mockable (1)
567
-
- When a targeted test run yields 0 tests, first verify the compiled JS exists under `out/test` (rootDir is `src`); absence almost always means the test file sits outside `src` or compilation hasn't run yet (1)
568
-
- When unit tests fail with VS Code API errors like `TypeError: X is not a constructor` or `Cannot read properties of undefined (reading 'Y')`, check if VS Code APIs are properly mocked in `/src/test/unittests.ts` - add missing Task-related APIs (`Task`, `TaskScope`, `ShellExecution`, `TaskRevealKind`, `TaskPanelKind`) and namespace mocks (`tasks`) following the existing pattern of `mockedVSCode.X = vscodeMocks.vscMockExtHostedTypes.X` (1)
569
-
- Create minimal mock objects with only required methods and use TypeScript type assertions (e.g., mockApi as PythonEnvironmentApi) to satisfy interface requirements instead of implementing all interface methods when only specific methods are needed for the test (1)
570
-
- When reviewing existing tests, focus on behavior rather than implementation details in test names and assertions - transform "should return X when Y" into "should [expected behavior] when [scenario context]" (1)
571
-
- Simplify mock setup by only mocking methods actually used in tests and use `as unknown as Type` for TypeScript compatibility (1)
572
-
- When testing async functions that use child processes, call the function first to get a promise, then use setTimeout to emit mock events, then await the promise - this ensures proper timing of mock setup versus function execution (1)
573
-
- Cannot stub internal function calls within the same module after import - stub external dependencies instead (e.g., stub `childProcessApis.spawnProcess` rather than trying to stub `helpers.isUvInstalled` when testing `helpers.shouldUseUv`) because intra-module calls use direct references, not module exports (1)
0 commit comments