The Tesults web app is designed for desktop browsers. Sign up and configure your project on a laptop or desktop. Use the iOS app or Android app to view results on the go.

How to Group Failing Tests by Root Cause

Why a flat list of failures is the wrong thing to triage, and how grouping failures by their underlying cause turns twenty red tests into a few real problems

blog-title-image

When a test run comes back with twenty failures, the number of failures is rarely the number of problems. Several tests often fail for the same underlying reason, one service that went down, one null pointer, one environment issue, so twenty red tests can be four actual causes. The mistake is triaging the flat list one test at a time, which means investigating the same root cause repeatedly and losing the shape of what actually broke. Grouping failures by root cause fixes this: instead of a list of failed tests you get a short list of causes, each with the failures it explains. This post covers why the flat list is the wrong unit to work from, and how grouping by cause turns a wall of red into a handful of real problems.

Why is a flat list of failures the wrong thing to triage?

A list of failing tests treats every failure as independent, and they usually are not. When a shared dependency breaks, every test that touches it fails, so one cause produces many red tests. Triaging that list top to bottom, you investigate the first failure, then the second, and slowly realise the third, fourth, and fifth are the same thing you already found. The list makes you rediscover one cause several times.

It also hides the scale of each problem. Twenty failures might be one large cause affecting fifteen tests and three small ones affecting the rest, but the flat list gives every failure equal weight, so you cannot see that fixing one thing clears most of the board. The unit you want to work from is not the failing test, it is the cause, and the list gives you the wrong unit.

What does grouping by root cause look like?

Grouping by root cause means the failures are clustered by why they failed rather than listed by which test failed. Instead of twenty rows, you see a few named causes, each with the failures it accounts for. A cluster might be a crash on load, another a null pointer exception, another a device or service being unavailable, and the failures are sorted underneath the cause that explains them.

That immediately changes what you do. You can see how many distinct problems you actually have, which cause is responsible for the most failures, and therefore what to fix first for the biggest reduction in red. A run that looked like twenty separate fires becomes, say, four problems of different sizes, which is a workload you can reason about and prioritise rather than a list you grind through.

How does Tesults group failures automatically?

Doing this by hand, reading each failure's error and message and mentally bucketing them, is exactly the tedious part, and it is what Tesults automates. Its Failure Analysis reads the failures in a run and groups them into clusters by likely root cause, naming each cluster and showing how many failures fall under it. The view leads with a plain summary, for example that the failures are grouped into four clusters, one due to crashes on load, one due to null pointer exceptions, one due to a device being unavailable, and one with unspecified reasons, and then presents each cause as its own group with the failures beneath it.

Failure Analysis grouping test failures into named root cause clusters with a count under each

Failure Analysis grouping test expanded detail

The result is that a run with several failures arrives already sorted into causes rather than as a flat list you have to cluster yourself. You open the analysis and the question has shifted from what failed to what caused the failures, which is the question you actually needed answered. Where a cause is clear from the failure it is named specifically; where it is not, those failures are grouped as unspecified rather than forced into a category, so the grouping stays honest about what can and cannot be inferred.

How does this fit with flaky tests?

Grouping by cause and detecting flakiness answer two different questions about a failure, and you want both. Root cause grouping asks, of the failures in this run, what caused them and how many share a cause. Flaky detection asks, across many runs, whether a given test's result is stable or just alternates. A failure that groups under a real cause and is not flaky is a genuine problem to fix; a failure that keeps appearing but is flagged as flaky across runs is noise to stabilise rather than a root cause to chase. Using them together, you group this run's failures by cause to know what to work on, and check each against its history to know whether it is real.

Failure Analysis grouping test expanded detail

Failure Analysis grouping test expanded detail

Flaky detection is covered in how to detect and handle flaky tests.

The number of failing tests is not the number of problems, and treating it as one means investigating the same causes over and over and losing the sense of which problem is biggest. Grouping failures by root cause turns a flat list into a short set of named causes with the failures each one explains, so you can see how many real problems there are and fix the largest first. Having that grouping computed for you, rather than clustering a wall of red by hand, is the difference between triaging failures and reading an answer. The analysis views described here are documented under supplemental analysis.

Test automation reporting and failure intelligence

Consolidated test reporting for engineering teams. Store, track, and understand test results across every run and system.

Latest Posts

How to Group Failing Tests by Root Cause
How to Group Failing Tests by Root Cause
Why a flat list of failures is the wrong thing to triage, and how grouping failures by their underlying cause turns twenty red tests into a few real problems
How to Share Test Results With Your Team
How to Share Test Results With Your Team
Why screenshotting results into chat does not scale, and how to give a whole team live access to test results with roles, notifications, and one shared dashboard
How to Detect Test Regressions Between Builds
How to Detect Test Regressions Between Builds
How to find exactly which tests newly failed from one build to the next, instead of comparing two runs by eye, and tell a real regression from a flake
Why Do Flaky Tests Only Fail in CI
Why Do Flaky Tests Only Fail in CI
The CI conditions that turn a test flaky when it never flakes locally, and how to confirm a CI-only failure is flakiness rather than a real bug
Why Do Tests Pass on Retry but Fail the First Time
Why Do Tests Pass on Retry but Fail the First Time
What a test passing on retry is really telling you, why automatic retries hide flakiness rather than fix it, and how to see the pattern across runs
Why Cypress Tests Pass Locally but Fail in CI
Why Cypress Tests Pass Locally but Fail in CI
The environment differences that cause Cypress failures in CI, and how to tell a real bug from an environment flake
How to Track Test Pass Rate Over Time
How to Track Test Pass Rate Over Time
Why a single run cannot tell you if your test suite is getting healthier or worse, and how to track pass rate as a trend across runs so you can see the direction
How to Report WebdriverIO Test Results to a Dashboard
How to Report WebdriverIO Test Results to a Dashboard
Send WebdriverIO results somewhere durable and team-visible using the Tesults service, with the wdio.conf.js setup, enhanced reporting, and parallel run consolidation
How to Report Cypress Test Results to a Dashboard
How to Report Cypress Test Results to a Dashboard
Send Cypress results somewhere durable and team-visible using the Cypress Module API, with screenshots and videos attached and runs consolidated across CI
Why Playwright Tests Pass Locally but Fail in CI
Why Playwright Tests Pass Locally but Fail in CI
The real reasons Playwright tests go green on your machine and red in CI, how to debug each one, and how to tell a genuine failure from an environment flake
How to Detect and Handle Flaky Tests
How to Detect and Handle Flaky Tests
What makes a test flaky, how to detect flaky tests automatically instead of by memory, and how to handle them without disabling coverage
How to Report Vitest Test Results to a Dashboard
How to Report Vitest Test Results to a Dashboard
Send Vitest results somewhere durable and team-visible, with the setup details specific to Vitest, so multiple test jobs consolidate into one history you can act on