Blog Post
What Is Regression Testing? A Guide for Teams That Ship UI
Last updated: September 24, 2026
Regression testing is re-running tests after a code change to confirm that features which already worked still work. A regression is anything that used to be right and now is not: a broken checkout, a button that shifted 8px, a label that lost its contrast. The goal is to catch those side effects before users do.
What Is Regression Testing?
Wikipedia defines regression testing as "re-running functional and non-functional tests to ensure that previously developed and tested software still performs as expected after a change." The change can be anything: a bug fix, a new feature, a dependency upgrade, a CSS refactor, or a config flag. If something that passed before fails now, that is a regression.
"Program maintenance requires far more system testing per statement written than any other programming. Theoretically, after each fix, one must run the entire batch of test cases previously run against the system to ensure that it has not been damaged in an obscure way." Fred Brooks, The Mythical Man-Month, p. 122
Two words in that quote matter for anyone who ships an interface: "non-functional" in the definition, and "obscure" in Brooks. Most regression suites cover function well. The obscure damage is usually visual, and it is usually the part nobody wrote a test for.
Regression Testing vs Retesting vs New Feature Testing
| Regression testing | Retesting | New feature testing | |
|---|---|---|---|
| Question | Did this change break anything that already worked? | Is the bug we fixed actually fixed? | Does the new thing work as specified? |
| Scope | Existing features near, or far from, the change | The one failing case | Only the new feature |
| Trigger | Any change: code, dependency, config, styles | A fix is deployed | A feature is ready for QA |
| Example | After a cart refactor, checkout and order history still work | The login test that failed on validation now passes | The new subscription flow works end to end |
Types of Regression Testing
Regression testing types are mostly about scope: how much of the suite you re-run for a given change. Pick the smallest scope that still covers what the change could plausibly touch.
- Unit regression: tests for the single function or module that changed, when the change is isolated.
- Partial regression: the changed module plus the modules that depend on it, when shared logic moved.
- Selective regression: a pre-chosen subset of critical, high-traffic, or fragile flows, on every pull request.
- Complete regression (retest all): the entire suite, before a major release, framework upgrade, or redesign.
- Progressive regression: existing tests plus new tests written for the change in the same sprint.
- Visual regression: screenshots diffed against approved baselines, after any change to styles, layout, fonts, or shared components.
The Four Kinds of Regression (and What Catches Each)
A more useful question for a team that ships UI is what kind of thing broke, because each kind needs a different check. A green functional suite says nothing about the other three.
| Regression | Example | What catches it | What misses it |
|---|---|---|---|
| Functional | Checkout button no longer submits the order | Unit, integration, and end-to-end tests (Playwright, Cypress, Selenium) | Nothing, if the flow has a test |
| Visual | A shared card component now clips its title on mobile | Screenshot diffing against a baseline (Playwright, Percy, Chromatic) | Functional tests: the element still exists and still clicks |
| Accessibility | A brand color update drops body text below 4.5:1 contrast | Automated WCAG checks (axe-core) re-run on every change | Functional tests, and visual diffs if the new color was approved |
| Design system | A hard-coded hex replaces a token, so dark mode breaks later | A token audit of the live page against your design tokens | Visual diffs: the hex renders identically today |
Accessibility is the kind most teams under-cover. The WebAIM Million 2026 report found detected WCAG failures on 95.9% of the top one million home pages, up from 94.8% in 2025, and an average of 56.1 errors per page, up 10.1% in a year. Low-contrast text alone appeared on 83.9% of pages. Those are regressions at web scale: the numbers had been improving for six years and then went backwards (WebAIM, 2026). For more on why a passing suite can still ship a broken page, see Why UIs Pass Every Test and Still Break in Production.
How to Do Regression Testing, Step by Step
- Define the regression suite: list the flows that must never break and the tests that cover them. Include visual and accessibility checks for your most-visited pages.
- Run impact analysis on the change: which modules, components, and pages depend on what changed? A shared button or a global stylesheet has a far larger blast radius than its diff suggests.
- Choose the scope: selective for everyday pull requests, partial when shared code moved, complete before a major release.
- Run automated checks in CI: functional tests, screenshot diffs, and automated accessibility rules on every pull request.
- Run a manual pass on what automation cannot judge: real devices, odd viewports, interactive states, and whether the page still matches the design.
- Fix, then retest: re-run the failing case and its neighbours. A fix is itself a change.
- Update the suite: add a test for every regression that escaped, and delete tests for features you retired.
How Much of the Suite Should You Re-Run?
Running everything on every change is the safest option and, past a certain size, the slowest. Meta reported that its predictive test selection system caught more than 99.9% of regressions while running about a third of all tests (Engineering at Meta). Most teams can get much of that benefit by tagging tests by area, running the tags that match the files changed, and running the full suite nightly. Selection works poorly for styles: a one-line change to a design token or global stylesheet can touch every page, so treat style changes as a trigger for a wide visual and accessibility pass.
Automated vs Manual Regression Testing
Automate anything repeatable with a clear pass or fail: flows, API contracts, screenshot diffs, and rule-based accessibility checks. Keep people on what automation cannot judge. Screenshot tools diff against an approved image, not the design; Playwright's docs say "On first execution, Playwright test will generate reference screenshots. Subsequent runs will compare against the reference" (Playwright). Redesign diffs get approved as a whole and hide real regressions. Hover, focus, error, empty, and loading states are often never captured. See Design QA vs Visual Regression Testing for the full comparison.
Regression Testing Tools by Layer
- Functional: Playwright, Cypress, Selenium.
- Visual: Playwright screenshots, Percy, Chromatic, Applitools.
- Accessibility: axe-core, WAVE, OverlayQA scheduled scans.
- Design fidelity: OverlayQA.
- Test management: Zephyr, TestRail.
For the screenshot layer, see Best Visual Regression Testing Tools in 2026.
How to Measure Your Regression Testing
- Escaped regressions: regressions found in production per release.
- Where escapes came from: functional, visual, accessibility, or design system.
- Suite run time: slow suites get skipped.
- Flaky rate: every flaky test teaches the team to ignore red.
Catch UI Regressions on the Live Page
OverlayQA covers the layers a functional suite leaves open. In the browser, it detects visual, accessibility, and design-token issues on any page, including localhost and staging, and compares the live build against your design. Scheduled scans re-run accessibility, contrast, and design token checks on the pages you watch, keep a baseline of every finding, and email you only when a scan finds something new or fixed.
Ready to catch the regressions your suite cannot see? Add OverlayQA to Chrome and detect visual, accessibility, and design-token regressions on your real build.
Frequently Asked Questions
What is regression testing in simple terms?
Regression testing means re-checking things that already worked after you change something. If you fix a bug in the cart and re-run the checkout, login, and order history tests to make sure they still pass, that is regression testing. Anything that used to work and now does not is called a regression.
What is the difference between regression testing and retesting?
Retesting confirms that one specific bug is fixed by re-running the test that failed. Regression testing confirms that the fix, or any other change, did not break something else. Retesting is narrow and targeted. Regression testing is broad and looks at everything the change could have affected.
When should you run regression tests?
Run regression tests after any change to code, dependencies, configuration, or styles: on every pull request for a selected subset, on a nightly schedule for the full suite, and before every major release. Style and design token changes deserve a wide visual and accessibility pass, because one line can affect every page.
Can regression testing be automated?
Most of it can. Functional flows, screenshot comparisons, and rule-based accessibility checks all run well in CI. What automation cannot judge is whether the approved baseline was correct to begin with, whether the page still matches the design, and states the tests never render, such as hover, focus, and error states. Those need a manual or design QA pass.
What is visual regression testing?
Visual regression testing captures screenshots of pages or components and compares them to previously approved baseline images, flagging any pixel difference for review. Tools include Playwright screenshot assertions, Percy, Chromatic, and Applitools. It catches layout and styling changes that functional tests pass over, but it cannot flag a problem that was already present in the baseline.