Duvaxa

DevOps & Cloud · Test impact selection

TestScope

Run the tests that matter.

Every pull request runs the tests its change can affect, each with a stated reason, and the full suite whenever a change is too broad to trust.

QA leads and engineering managers with slow CITeams paying for CI minutesMonorepos with several languages
test-select · example
$ test-select pick --base origin/main --timings junit.xml
5 of 8 test files, 54s of 209s (74% less)
imports tests/test_orders.py (imports shop/pricing.py via shop/cart.py -> shop/orders.py)
imports web/src/cart.test.ts (imports web/src/format.ts via web/src/cart.ts)
No test reaches: shop/coupons.py
Run:
npx jest --runTestsByPath web/src/cart.test.ts web/src/format.test.ts
pytest tests/test_cart.py tests/test_orders.py tests/test_pricing.py
Real run on the built-in demo repository. Links made at runtime (reflection, config, data files) need coverage data or a run-all rule.
LanguagesPython, JS/TS, Go, Java, Ruby, C#
Runners8, from pytest to Gradle
Runs onYour laptop, server or CI
SafetyMeasured miss rate

The problem

Every pull request runs the whole suite: 30 minutes of waiting for a one-line change, a growing CI bill, and developers who start skipping or re-running tests.

What it does

01

Follows the change to the tests: coverage per line (coverage.py test contexts or a map file from any tool), the import graph, and naming conventions

02

Python, JavaScript and TypeScript, Go, Java and Kotlin, Ruby and C#, including monorepos

03

One command per runner: pytest, Jest, Vitest, Go, Maven, Gradle, RSpec and dotnet test

04

Runs everything when a change can affect any test (dependencies, test config, fixtures, build files) and says which file caused it

05

Lists changed files no test reaches instead of skipping them silently

06

Shows the time saved from a full run's JUnit XML

07

check: measures whether the selection would have caught the failures of a real full run

08

why: which tests reach a file, and through which imports

09

Works before you push, on uncommitted changes

How it works

  1. Run it on a few recent pull requests and compare with full runs
  2. Add it to CI, keeping a full run on the main branch
  3. Check the miss rate monthly and tune the rules

Works with

pytestJestVitestGo testMavenGradleRSpecdotnet testcoverage.pyGitHub Actions

Runs in your CI

GitHub Actions workflow step
- run: test-select pick --base origin/$BASE --format cmd > run-tests.sh
- run: sh run-tests.sh
Licensed customers get the action or command-line tool installed in their own organisation; it runs on your runners, so your code and plans never leave them. The command-line tools run in GitLab CI the same way.

Your data

  • Reads your repository and coverage files locally; nothing is uploaded.
  • Every selected test carries a reason you can inspect.
  • check replays real failures to show how often the selection would have missed one.

Who it's for

QA leads and engineering managers with slow CITeams paying for CI minutesMonorepos with several languages

Questions

What if it misses a test?

Changes to dependencies, fixtures and test configuration run everything, unreached files are listed rather than skipped, and you can add your own run-all paths.

Do we need coverage data?

No. Imports and naming conventions work on their own; coverage makes the selection more precise.

Related

Often used with TestScope

See TestScope on your own data

A 30-minute call. We run the product on your export, repository or document and walk you through the results.

Book a demo