autotel-vitest 0.4.30 → 0.4.32
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/package.json +4 -3
- package/skills/autotel-vitest/SKILL.md +207 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel-vitest",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.32",
|
|
4
4
|
"description": "Vitest fixture for OpenTelemetry: one span per test so all instrumented code is filterable by test run",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -22,10 +22,11 @@
|
|
|
22
22
|
"files": [
|
|
23
23
|
"dist",
|
|
24
24
|
"src",
|
|
25
|
-
"README.md"
|
|
25
|
+
"README.md",
|
|
26
|
+
"skills"
|
|
26
27
|
],
|
|
27
28
|
"dependencies": {
|
|
28
|
-
"autotel": "
|
|
29
|
+
"autotel": "4.0.0"
|
|
29
30
|
},
|
|
30
31
|
"peerDependencies": {
|
|
31
32
|
"vitest": ">=4.1.8"
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: autotel-vitest
|
|
3
|
+
description: >
|
|
4
|
+
Use this skill when adding OpenTelemetry tracing to Vitest tests — gives each test a parent span so all instrumented code becomes filterable child spans in your OTLP backend.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# autotel-vitest
|
|
8
|
+
|
|
9
|
+
Vitest fixture that creates one OTel span per test so all `autotel`-instrumented code executed during a test automatically runs as child spans. Makes every test run filterable by trace ID in your OTLP backend (Jaeger, Honeycomb, Datadog, etc.).
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
### 1. Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add autotel autotel-vitest
|
|
17
|
+
pnpm add -D vitest
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 2. globalSetup.ts — call init() before tests run
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// globalSetup.ts
|
|
24
|
+
import { init } from 'autotel';
|
|
25
|
+
|
|
26
|
+
export default function globalSetup() {
|
|
27
|
+
init({
|
|
28
|
+
service: 'unit-tests',
|
|
29
|
+
endpoint: 'http://localhost:4318', // Your OTLP collector
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 3. vitest.config.ts — register globalSetup
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// vitest.config.ts
|
|
38
|
+
import { defineConfig } from 'vitest/config';
|
|
39
|
+
|
|
40
|
+
export default defineConfig({
|
|
41
|
+
test: {
|
|
42
|
+
globalSetup: './globalSetup.ts',
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 4. Import test from autotel-vitest
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { test, expect } from 'autotel-vitest';
|
|
51
|
+
|
|
52
|
+
test('creates user', async () => {
|
|
53
|
+
await userService.createUser({ email: 'test@example.com' });
|
|
54
|
+
// All trace()/span() calls in userService become child spans of this test
|
|
55
|
+
expect(true).toBe(true);
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The fixture is `auto: true` — every test gets a parent span automatically with no extra code.
|
|
60
|
+
|
|
61
|
+
## Configuration / Core Patterns
|
|
62
|
+
|
|
63
|
+
### Per-test span attributes
|
|
64
|
+
|
|
65
|
+
Each test span is named `test:${task.name}` and carries these attributes automatically:
|
|
66
|
+
|
|
67
|
+
- `test.name` — the test name string
|
|
68
|
+
- `test.file` — file path from `task.file.name`
|
|
69
|
+
- `test.suite` — suite name from `task.suite.name` (if in a describe block)
|
|
70
|
+
|
|
71
|
+
If a test throws, the span is marked `ERROR` and records the exception.
|
|
72
|
+
|
|
73
|
+
### Optional: OtelReporter (runner-process spans)
|
|
74
|
+
|
|
75
|
+
The fixture creates spans in the **worker** process. If you also want **runner-process** spans for test/suite timing (visible in your OTLP backend as a hierarchy), add the reporter:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// vitest.config.ts
|
|
79
|
+
import { defineConfig } from 'vitest/config';
|
|
80
|
+
|
|
81
|
+
export default defineConfig({
|
|
82
|
+
test: {
|
|
83
|
+
globalSetup: './globalSetup.ts',
|
|
84
|
+
reporters: ['default', 'autotel-vitest/reporter'],
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Reporter creates:
|
|
90
|
+
- `test:<name>` spans for each test case
|
|
91
|
+
- `suite:<name>` spans for each describe block
|
|
92
|
+
|
|
93
|
+
### Testing utilities (re-exported from autotel/testing)
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import {
|
|
97
|
+
test,
|
|
98
|
+
createTraceCollector,
|
|
99
|
+
assertTraceCreated,
|
|
100
|
+
assertTraceSucceeded,
|
|
101
|
+
assertTraceFailed,
|
|
102
|
+
assertNoErrors,
|
|
103
|
+
assertTraceDuration,
|
|
104
|
+
waitForTrace,
|
|
105
|
+
getTraceDuration,
|
|
106
|
+
createMockLogger,
|
|
107
|
+
} from 'autotel-vitest';
|
|
108
|
+
|
|
109
|
+
test('traces user creation', async () => {
|
|
110
|
+
const collector = createTraceCollector();
|
|
111
|
+
await userService.createUser({ email: 'test@example.com' });
|
|
112
|
+
assertTraceCreated(collector, 'user.createUser');
|
|
113
|
+
assertTraceSucceeded(collector, 'user.createUser');
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Trace context helpers (re-exported from autotel)
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { getTraceContext, resolveTraceUrl, isTracing, enrichWithTraceContext } from 'autotel-vitest';
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Cross-process tracing (test → HTTP server)
|
|
124
|
+
|
|
125
|
+
When the server runs in a separate process, inject the trace context into the HTTP request so both sides share the same trace ID:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { test } from 'autotel-vitest';
|
|
129
|
+
import { injectTraceContext, extractTraceContext } from 'autotel/http';
|
|
130
|
+
|
|
131
|
+
test('traces across HTTP', async () => {
|
|
132
|
+
const response = await fetch('http://localhost:3000/api/users', {
|
|
133
|
+
headers: injectTraceContext(), // adds traceparent header
|
|
134
|
+
});
|
|
135
|
+
// Server must call extractTraceContext(req.headers) and run in that context
|
|
136
|
+
// Both test span and server spans appear under the same trace ID in OTLP
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Common Mistakes
|
|
141
|
+
|
|
142
|
+
### HIGH — Importing test from vitest instead of autotel-vitest
|
|
143
|
+
|
|
144
|
+
Wrong:
|
|
145
|
+
```typescript
|
|
146
|
+
import { test } from 'vitest'; // base test — no OTel fixture
|
|
147
|
+
|
|
148
|
+
test('creates user', async () => {
|
|
149
|
+
await userService.createUser({ email: 'test@example.com' });
|
|
150
|
+
// No parent span — instrumented code spans are unlinked orphans
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Correct:
|
|
155
|
+
```typescript
|
|
156
|
+
import { test } from 'autotel-vitest'; // extended test with auto fixture
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Explanation: Only the extended `test` from `autotel-vitest` has the `_otelTestSpan` fixture registered. Using the base `vitest` `test` means no parent context is active and child spans appear as disconnected traces.
|
|
160
|
+
|
|
161
|
+
### HIGH — Not calling init() in globalSetup
|
|
162
|
+
|
|
163
|
+
Wrong:
|
|
164
|
+
```typescript
|
|
165
|
+
// vitest.config.ts — no globalSetup
|
|
166
|
+
// Spans are created but never exported (no tracer provider configured)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Correct:
|
|
170
|
+
```typescript
|
|
171
|
+
// globalSetup.ts
|
|
172
|
+
import { init } from 'autotel';
|
|
173
|
+
export default function globalSetup() {
|
|
174
|
+
init({ service: 'unit-tests', endpoint: 'http://localhost:4318' });
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Explanation: `init()` must run in `globalSetup` (not in a `beforeAll` or test file) so the provider is available before any worker process starts executing tests.
|
|
179
|
+
|
|
180
|
+
### MEDIUM — Adding the reporter without globalSetup
|
|
181
|
+
|
|
182
|
+
Wrong:
|
|
183
|
+
```typescript
|
|
184
|
+
// vitest.config.ts
|
|
185
|
+
export default defineConfig({
|
|
186
|
+
test: {
|
|
187
|
+
reporters: ['default', 'autotel-vitest/reporter'],
|
|
188
|
+
// No globalSetup — init() never called in the runner process
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Correct: Always pair the reporter with `globalSetup` that calls `init()`.
|
|
194
|
+
|
|
195
|
+
Explanation: The reporter runs in the Vitest runner process and calls `getTracer()`. If `init()` was never called, there is no configured tracer provider and spans silently go nowhere.
|
|
196
|
+
|
|
197
|
+
### MEDIUM — Calling describe/beforeEach from vitest directly when using autotel-vitest
|
|
198
|
+
|
|
199
|
+
These are safe to mix — `autotel-vitest` re-exports `describe`, `beforeEach`, `afterEach`, `beforeAll`, `afterAll` directly from `vitest`, so you can import everything from one place:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { test, expect, describe, beforeEach } from 'autotel-vitest';
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Version
|
|
206
|
+
|
|
207
|
+
Targets autotel-vitest v0.4.4. Requires `vitest >=4.1.0` (peer), `autotel` (peer). The fixture uses `auto: true` (Vitest 4+ fixture API).
|