Skip to main content
DoneThat

AI Adoption GuideSoftwareTest

Risk-Based Test Prioritization

ML predicts which test subsets cover highest defect risk for a given diff, cutting CI runtime, using tools like Launchable or Sealights.

Software processDiscoverDesignBuildTestReleaseAdoptSupportRetire

By Don, DoneThat’s AI coach · updated

What risk-based test prioritization solves

Full regression suites grow faster than merge volume. A QA lead choosing the CI subset for each change faces a familiar tradeoff: run everything and wait, or cut the suite and accept blind spots. Risk-based test prioritization uses historical failures, coverage linkage, and the current diff to rank which tests are most likely to catch a defect for that change. The goal is not to invent new tests. It is to order and select from the suite you already trust so pipeline time drops without turning the gate into a coin flip.

Tools in this space (for example Launchable or Sealights) typically consume change metadata and prior execution history, then emit a ranked list or a recommended subset for the job. The model proposes; the pipeline still enforces pass/fail against whatever subset you authorize. That separation matters: prediction quality improves over time, but release accountability stays with QA and engineering, not with the ranking service.

How the ranking usually works

Most systems combine three signals. First, the diff: which files, packages, or services changed, and how those map to tests via coverage, call graphs, or historical co-change. Second, failure history: which tests have recently failed, for which kinds of changes, and with what severity. Third, suite economics: duration, flakiness, and dependency cost, so a long flaky test is not preferred over a short, stable one with similar predictive value unless the risk signal is strong.

The output is usually a prioritized order (run highest-risk tests first) and optionally a cut line (stop after N minutes or after a risk budget). Early failure still fails the job; the win is that expensive low-signal tests move later or off the default path for that change type. Nightly or pre-release jobs can still run the full suite so the model’s training data and your confidence in skipped paths do not drift silently.

When the diff is empty, unreadable, or the test-history store is unavailable, the system should emit an empty recommendation rather than a guessed subset. An empty output is safer than a confident wrong list: the pipeline can fall back to a known-safe policy (full suite, last known good subset, or a manual QA selection) instead of shipping under a fabricated risk score.

Where a QA lead applies it in the workflow

Use prioritization on pull-request and merge-train jobs where wall-clock cost is high and change locality is usually clear. Keep fuller suites on release candidates, hotfixes that touch shared infrastructure, and areas where coverage mapping is weak (generated code, infrastructure-as-code, or cross-service contracts that your linkage does not model well).

A practical operating model looks like this:

  1. Ingest the change set and the suite’s recent results into the prioritizer.
  2. Receive a ranked subset (or an empty result if inputs are incomplete).
  3. Apply your gate policy: which risk tiers must run, which may be deferred, and what constitutes a hard fail.
  4. Record what ran, what was deferred, and whether deferred failures later appeared in fuller jobs, so you can audit the model against reality.

Related techniques sit nearby. Adversarial input generation stresses edge cases the historical suite may never have seen. Autonomous end-to-end agents explore flows that static rankings cannot invent. Flaky-test root-cause work cleans the signal the prioritizer depends on. Prioritization does not replace those practices; it allocates scarce CI minutes among the tests you already maintain.

Human-in-the-loop: who owns the gate

The model ranks tests. QA still owns the gate. That means a human-defined policy decides whether the ranked list is advisory, auto-applied under caps, or blocked until a lead confirms the cut for high-risk paths. Ownership shows up in three places: the allowlist of suites that may be shortened, the fallback when output is empty, and the review of miss rates when a deferred test later fails on main.

Do not treat a vendor’s “recommended subset” as an automatic merge criterion without a written policy. Define which change classes always require a broader suite (auth, payments, data migrations, security-sensitive modules). Define who can raise or lower the risk budget. Define how long a deferred failure can remain invisible before you widen the default subset again. The ranking service optimizes for predicted defect coverage per minute; your gate optimizes for acceptable release risk. Those objectives overlap but are not identical.

When stakeholders ask for “just skip the slow tests,” answer with the gate rule, not with model confidence alone. Confidence scores help triage; they do not absolve the team of a missed production defect that a deferred test would have caught.

Inputs, empty outputs, and failure modes

Minimum inputs are a parseable diff (or equivalent change list) and enough recent test history to score candidates. Useful additions include coverage or dependency maps, flake annotations, and ownership metadata so high-risk areas can force inclusion regardless of model rank. If either the diff or the history feed is missing, corrupt, or older than your freshness threshold, return empty output and take the fallback path. Guessing from stale averages recreates the blind spots you were trying to shrink.

Watch for these failure modes:

  • Cold start. New tests and new modules lack history; force-include them until enough runs exist.
  • Flake pollution. Unstable tests inflate or deflate risk; pair prioritization with flake quarantine and root-cause work.
  • Mapping gaps. Diffs that do not map to tests (config-only, feature flags, multi-repo contracts) need explicit rules, not silent omission.
  • Training on the wrong job. Ranking trained only on green mainline misses PR-specific failure patterns; keep feedback loops tied to the same job types you optimize.
  • Silent full-suite abandonment. If every job uses aggressive subsets and nightly full runs are skipped, both product risk and model quality degrade together.

Measure success with operational metrics you already trust: median CI duration for prioritized jobs, time-to-first-failure, rate of empty recommendations, and deferred-test failures discovered in fuller suites. Avoid inventing percentage claims without your own baselines. Compare policies side by side on the same stream of changes before you widen auto-apply.

Is this worth automating for you?

Whether this pays back depends on how much time it takes your team today. Most teams estimate that from memory, and the estimate is usually wrong in one direction or the other. This one is rated high effort to implement, so the baseline matters more than usual.

DoneThat reconstructs where the time actually went, with no timers to forget, so you can measure the baseline before committing to a project and check the gain afterward.

Measure the baseline first