Files
Klaus Zimmermann 30a5b0bb11 Add spin test, a pytest wrapper with a --ci switch for test/run_test.py (#198649)
Adds `spin test`, the last tier-1 command from #164469.

## What it does

```
spin test test/test_nn.py -k Linear -x   # pytest, arguments passed through
spin test --ci -i test_nn test_torch     # test/run_test.py, as CI runs it
spin test                                # this command's help
spin test --ci                           # the runner's help, which lists the suites
```

`spin test ARGS` runs `pytest ARGS` from the repository root, the day-to-day invocation CONTRIBUTING recommends; `pytest.ini` and `test/conftest.py` apply as usual. `spin test --ci ARGS` runs `python test/run_test.py ARGS` instead: suite selection by name, sharding, the distributed and cpp_extension handlers, the CI pytest plugins. That also reproduces a CI invocation locally.

The command adds no options beyond `--ci`. Both runners own their option surface already; a third one here would only drift from them.

## Design notes

- The pytest branch runs the `pytest` entry point next to the interpreter, not `python -m pytest`: `-m` puts the current directory first on `sys.path`, so from the repository root the checkout would shadow a non-editable `spin install`. This way both install kinds work.
- Both runners import torch while collecting, and `run_test.py` needs it even for `--help`. Rather than paying an `import torch` up front on every run, the command probes torch only after a non-zero exit, from outside the checkout, and replaces the traceback with a pointer at `spin develop` / `spin install` if the probe fails. Otherwise the runner's exit code passes through untouched.

## Tests

Added to the existing spin test file, `test/spincli/test_spin.py`, which runs in the regular test shards. Unit tests drive `spin test` with the runner, the torch probe and the pytest lookup mocked and assert on the command line and the failure reporting. CLI tests run the real `python -m spin`: every command registered in `[tool.spin.commands]` is listed and answers `--help`, and `spin test` collects a test file through pytest against the torch under test and passes a failing exit code through.

## Verification

- Editable build: `spin test test/test_utils.py -k TestCppExtensionUtils` runs 6 tests; a failing test exits 1 with no hint; `--lf` and `-x` pass through; `--ci -i test_utils --dry-run` lists and `--ci -i test_utils -k TestCppExtensionUtils` runs the same 6 through the runner.
- Non-editable install (CPU wheel in a fresh venv, cwd at the repository root): `python -m pytest` fails to import torch because the checkout shadows site-packages; `spin test` runs the installed torch.
- No torch: both paths stop with the `spin develop` hint.
- `spin lint` clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Pull Request resolved: https://github.com/pytorch/pytorch/pull/198649
Approved by: https://github.com/atalman
2026-10-01 11:52:27 +00:00
..