| name | test |
| description | Runs project test suite with coverage, auto-detects framework (pytest, vitest, jest, flutter, go, cargo, phpunit). Triggers: run tests, test suite, coverage report. |
| effort | medium |
| disable-model-invocation | true |
| argument-hint | [file or pattern] |
| allowed-tools | Bash, Read, Grep |
| hooks | {"PostToolUse":[{"matcher":"Bash","hooks":[{"type":"command","command":"echo 'Reminder: check test coverage meets threshold (>70%)'"}]}]} |
Test Runner
$ARGUMENTS
Run tests based on detected project type.
Project context
- Project config: !
cat package.json 2>/dev/null || cat pyproject.toml 2>/dev/null || cat pubspec.yaml 2>/dev/null || echo "unknown"
Auto-Detection
Run the bundled script to detect test framework:
python3 ${CLAUDE_SKILL_DIR}/scripts/detect-runner.py .
| File Found | Runner | Command |
|---|
pyproject.toml / setup.py | pytest | pytest --cov=src --cov-report=term-missing tests/ |
package.json (vitest) | vitest | npx vitest run --coverage |
package.json (jest) | jest | npx jest --coverage |
pubspec.yaml | flutter test | flutter test --coverage |
go.mod | go test | go test -cover ./... |
Cargo.toml | cargo test | cargo test |
composer.json | phpunit | ./vendor/bin/phpunit --coverage-text |
Usage
/test # Run all tests
/test path/to/test_file # Run specific test file
/test -k "test_name" # Run tests matching pattern
/test --coverage # Run with coverage report
Common Options by Runner
Python (pytest)
pytest tests/
pytest tests/unit/test_example.py
pytest -k "test_search"
pytest --lf
pytest -v
JavaScript/TypeScript (vitest/jest)
npx vitest run
npx vitest run src/utils.test.ts
npx vitest run --reporter=verbose
npx jest --testPathPattern=utils
PHP (phpunit)
./vendor/bin/phpunit
./vendor/bin/phpunit tests/Unit/ExampleTest.php
./vendor/bin/phpunit --filter testName
Flutter/Dart
flutter test
flutter test test/widget_test.dart
dart test --name="pattern"
Go
go test ./...
go test ./pkg/utils/
go test -run TestName ./...
go test -v ./...
Coverage Targets
- Overall: >70%
- Core modules: >80%
- New code: 100% (for PRs)
Test Structure Convention
tests/ # or test/, spec/, __tests__/
āāā unit/ # Fast, isolated tests
āāā integration/ # Tests with external dependencies
āāā e2e/ # End-to-end tests
Rules
- MUST detect the framework automatically via
detect-runner.py ā do not assume
- NEVER modify tests to make them pass
- CRITICAL: coverage reporting must use the project's configured tool (
--cov=src, --coverage, etc.) ā do not invent flags
- MANDATORY: when a test fails, report the failure exactly; do not paraphrase
Gotchas
pytest --cov=src inflates coverage when tests/ lives under src/ ā test files count toward covered lines. Either move tests/ out, or use --cov=src --cov-branch --cov-report=term-missing with an explicit [tool.coverage.run] omit = ["tests/*"] in pyproject.toml.
go test ./... runs packages in parallel by default; a test depending on shared global state may pass alone and fail in the suite. If flakiness appears only under ./..., suspect shared state, not a bug in the test.
flutter test without an emulator falls back to the headless "null platform" ā widget tests that require a render surface are silently skipped. CI without a display must add flutter test --platform vm or a virtual framebuffer.
vitest run and jest interpret glob patterns differently: *.test.ts in vitest matches filenames, in jest matches paths. Passing the same CLI arg to both produces different test sets ā use the framework-native config file when possible.
pytest --lf (last-failed) silently runs all tests if there is no cache from a prior run. First-time runs in CI therefore ignore --lf and re-run everything, which can hide "only failed tests" bugs in local runs.
When NOT to Use
- To write new tests test-first ā use
/tdd
- To author test design patterns ā use
/testing-patterns (knowledge skill)
- To debug a failing test ā use
/debug after /test surfaces the failure
- For performance/load testing ā use dedicated tooling, not
/test