Skip to content

Commit f84f8d8

Browse files
onboard: use offload collect for vitest duplicate name verification
Move the vitest duplicate check from Step 2 (manual npx vitest list) to new Step 5 (after offload.toml creation) using offload collect. The agent now iterates on offload collect until all duplicate space-separated test names are resolved. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4cddf31 commit f84f8d8

File tree

1 file changed

+53
-13
lines changed

1 file changed

+53
-13
lines changed

skills/offload-onboard/SKILL.md

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Investigate how the repository runs its tests:
1919
2. Look for existing CI workflows (`.github/workflows/`, `.gitlab-ci.yml`, etc.) to see how tests are currently invoked
2020
3. Look for test directories: `tests/`, `test/`, `**/test_*.py`, `**/*_test.go`, `src/**/tests/`, etc.
2121
4. Determine:
22-
- **Framework**: `pytest`, `cargo`, or `default` (generic)
22+
- **Framework**: `pytest`, `cargo`, `vitest`, or `default` (generic)
2323
- **Test paths**: Where tests live (e.g. `["tests/"]`, `["src/"]`)
2424
- **Python runner**: If pytest, determine if the project uses `uv`, `poetry`, `pip`, or plain `python`
2525
- **Extra args**: Any special invocation needed (e.g. `["run", "--group", "test"]` for uv with dependency groups)
@@ -176,7 +176,31 @@ Configuration reference for fields used above:
176176
- `retry_count`: Number of retries for failed tests (0 = no retries, 1 = catches transient failures)
177177
- `filters`: Filter string passed to the framework during discovery (e.g. `-m 'not slow'`)
178178

179-
### Step 5: Add JUnit ID Normalization (pytest only)
179+
### Step 5: Verify Vitest Test Discovery (vitest only)
180+
181+
**Skip this step if the framework is not `vitest`.**
182+
183+
Offload's vitest integration uses `--testNamePattern` to select specific tests for parallel execution. This flag matches tests by their **space-separated** describe/test chain — not by file path. When two tests in different files share the same space-separated name, Offload cannot distinguish them and **will error during discovery**, blocking all test execution.
184+
185+
Run `offload collect` to verify that test discovery works:
186+
187+
```bash
188+
offload collect
189+
```
190+
191+
If Offload reports **"Duplicate test names found (space-separated)"**, stop and present the duplicates to the user. Explain:
192+
193+
> Offload cannot run vitest tests that share the same space-separated name across different files. This is a requirement of Offload's `--testNamePattern`-based test selection — without unique names, Offload will error during test discovery and no tests will run.
194+
195+
Then ask: **"Would you like me to deduplicate these test names by making them more descriptive? This typically involves wrapping tests in uniquely named `describe()` blocks or renaming `test()`/`it()` calls to include more context."**
196+
197+
If the user agrees, rename the tests to make the space-separated names unique. Prefer wrapping in descriptive `describe()` blocks over renaming individual tests, as this preserves the existing test names while adding disambiguation.
198+
199+
After making changes, run `offload collect` again. **Repeat until `offload collect` succeeds with no duplicate name errors.**
200+
201+
If the user declines deduplication, **do not proceed with Offload onboarding** — inform them that Offload's vitest integration cannot function with duplicate test names and they will need to resolve this before onboarding can continue.
202+
203+
### Step 6: Add JUnit ID Normalization (pytest only)
180204

181205
**Skip this step if the framework is not `pytest`.**
182206

@@ -252,7 +276,7 @@ def _set_junit_test_id(request: pytest.FixtureRequest, record_xml_attribute) ->
252276

253277
Ensure imports (`os`, `pytest`) are not duplicated if the file already has them.
254278

255-
### Step 6: Create Local Invocation Script
279+
### Step 7: Create Local Invocation Script
256280

257281
Create `scripts/offload-tests.sh`:
258282

@@ -281,7 +305,7 @@ The `--copy-dir` flag tells Offload to bake the local directory into the sandbox
281305

282306
If the project uses a Makefile, justfile, or Taskfile instead of scripts/, add the invocation there instead to be consistent with existing practice.
283307

284-
### Step 7: Update .gitignore
308+
### Step 8: Update .gitignore
285309

286310
Append Offload artifacts to `.gitignore`:
287311

@@ -292,15 +316,31 @@ test-results/
292316

293317
NOTE: `.offload-image-cache` should be checked in to git — it tracks the base image ID and speeds up subsequent runs. Do not confuse `.gitignore` (which controls what git tracks) with `.dockerignore` (which controls what gets copied into the sandbox image). The `.dockerignore` is only created if needed during troubleshooting — see the Troubleshooting section.
294318

295-
### Step 8: Run Offload Locally and Verify
319+
### Step 9: Run Offload Locally and Verify
296320

297321
Install offload if not already present:
298322

299323
```bash
300324
cargo install offload@0.5.0
301325
```
302326

303-
Run the tests using the invocation script from Step 6:
327+
Run the tests using the invocation script from Step 7:
328+
329+
**First, verify test discovery with `offload collect`:**
330+
331+
```bash
332+
offload collect
333+
```
334+
335+
This runs test discovery locally without creating sandboxes or executing tests. Fix any errors until `offload collect` succeeds and lists the expected tests. Common issues:
336+
337+
1. **"No tests discovered"**: Check that `paths` in `offload.toml` points to the correct test directories and the framework command is correct.
338+
2. **"Duplicate test names found"** (vitest): Duplicate space-separated test names exist. Return to Step 5 and resolve them.
339+
3. **Discovery command failed**: The framework tool (`pytest`, `cargo nextest`, `npx vitest`) is not installed or not on PATH.
340+
341+
Do not proceed to execution until `offload collect` lists the expected tests.
342+
343+
**Then, run the full test suite:**
304344

305345
```bash
306346
./scripts/offload-tests.sh
@@ -315,7 +355,7 @@ Run the tests using the invocation script from Step 6:
315355

316356
Do not proceed to optimization until all tests pass.
317357

318-
### Step 9: Optimize Parallelism
358+
### Step 10: Optimize Parallelism
319359

320360
Run a simple linear search over `max_parallel` to minimize total runtime:
321361

@@ -328,11 +368,11 @@ The optimal `max_parallel` depends on the number of test files and per-test dura
328368

329369
Report the results as a table to the user and set the optimal values in `offload.toml`.
330370

331-
### Step 10: Update Agent/Project Instructions (if desired)
371+
### Step 11: Update Agent/Project Instructions (if desired)
332372

333373
**First, ask the user:** "Would you like to configure Offload as the default test runner for AI agents working in this repository? This requires agents to have access to Modal API credentials."
334374

335-
**If the user declines**, skip this step entirely and proceed to Step 11.
375+
**If the user declines**, skip this step entirely and proceed to Step 12.
336376

337377
**If the user agrees**, ensure that future AI agents working in this repository know to use Offload for running tests:
338378

@@ -365,9 +405,9 @@ Report the results as a table to the user and set the optimal values in `offload
365405

366406
6. Preserve the existing tone and formatting of the file. If it uses a digraph, bullet lists, or a specific heading style, match that style. Do not restructure or reformat existing content.
367407

368-
### Step 11: Set Up CI Job (if desired)
408+
### Step 12: Set Up CI Job (if desired)
369409

370-
Ask the user if they want to set up a CI job to run Offload tests automatically on push/PR. If they decline, skip Steps 11 and 12.
410+
Ask the user if they want to set up a CI job to run Offload tests automatically on push/PR. If they decline, skip Steps 12 and 13.
371411

372412
If they want CI, detect the CI system from the repository:
373413
- `.github/workflows/` → GitHub Actions
@@ -444,7 +484,7 @@ jobs:
444484

445485
For other CI systems, adapt the same pattern: install Offload + Modal CLI, set Modal secrets as env vars, run `offload run`.
446486

447-
### Step 12: Configure CI Secrets
487+
### Step 13: Configure CI Secrets
448488

449489
Tell the user they need to add two repository secrets:
450490
- `MODAL_TOKEN_ID`: Their Modal API token ID
@@ -505,7 +545,7 @@ node_modules
505545
|------|---------|
506546
| `.devcontainer/Dockerfile` (or existing) | Base image for Modal sandboxes |
507547
| `.dockerignore` | (If needed) Exclude local artifacts from sandbox — see Troubleshooting |
508-
| `conftest.py` | (pytest only) JUnit ID normalization hook — see Step 5 |
548+
| `conftest.py` | (pytest only) JUnit ID normalization hook — see Step 6 |
509549
| `offload.toml` | Offload configuration |
510550
| `scripts/offload-tests.sh` (or Makefile target) | Local invocation convenience |
511551
| `.gitignore` | Exclude Offload artifacts |

0 commit comments

Comments
 (0)