Web app testing

What Is Regression Testing? Types, Examples and How to Automate It

QA Wolf
October 15, 2026
Key Takeaways
  • Regression testing re-runs tests on existing features after any change to catch things the change broke.
  • Run it on every deploy, not just before big releases, so each failure points to a small, recent change.
  • Automate your critical flows first (login, sign-up, payments) in an open framework like Playwright or Appium.
  • Add a test for every bug that escapes to production.
  • The recurring work decides whether a suite survives: investigating failures and maintaining tests cost more over time than writing them.

You fixed the checkout bug. Shipped it. Two days later, support tickets roll in: the coupon field stopped working. Nobody touched coupons. But the fix did.

Regression testing is re-running tests on features that already worked to make sure a new change didn't break them. Every code change, bug fix, dependency upgrade or config tweak can break something that used to work, and a regression suite is how you find out before your users do. Most teams automate it and run it on every pull request or deploy.

This guide covers what regression testing is, the main types, when to run it, how to build a regression suite that keeps up, and a working Playwright example.

Spending more time maintaining regression tests than writing features? See what it costs to run testing in-house with our in-house QA team calculator, or book a demo.

What is regression testing?

Regression testing checks that existing functionality still works after a change. A "regression" is a bug in something that used to work: a feature goes backward.

The tests themselves usually aren't new. A regression suite is the collection of tests you've built up for features that already shipped: login, sign-up, search, checkout, the flows your users rely on every day. When code changes, you run those tests again. If one fails, either the change broke something or the test needs updating, and someone has to figure out which.

A simple example: your team adds a new payment method. The new feature gets its own tests. Regression testing is re-running the tests for card payments, refunds, discount codes and order history, to make sure the new payment method didn't break them.

Why regression testing matters

Software is connected in ways nobody fully tracks. A change to a shared component, an API response, a database migration or a library upgrade can break a feature several layers away from the code you touched. Code review rarely catches that, because the reviewer is looking at the diff, not at everything the diff can affect.

The faster you ship, the more this matters. More deploys mean more chances to break something, and less time for anyone to click through the app by hand. In QA Wolf's data, teams with full end-to-end regression suites running on their deploys still found about 9 verified bugs for every 100 deploys in Q3 2026 (we tested over 50,000 deploys). Those bugs were caught in testing, before they reached users.

Regression testing vs. retesting and other test types

Regression testing gets confused with a few other kinds of testing. The difference is what each one is checking.

  • Retesting checks that a specific bug is fixed. Regression testing checks that the fix didn't break anything else. You usually do both: retest the bug, then run the regression suite.
  • Smoke testing is a quick check that a build works at all (the app loads, people can log in) before you spend time on deeper testing. A smoke suite is a small, fast subset of your regression suite.
  • Sanity testing is a narrow check on one area after a small change. It's a quick look, not a full regression run.
  • Functional testing checks that features do what the requirements say. Regression testing re-runs functional tests over time, after each change.
  • User acceptance testing (UAT) is when business users or customers confirm the software meets their needs before release. It's about whether you built the right thing; regression testing is about whether you broke something.

Types of regression testing

Teams usually pick one of these approaches, or mix them:

  • Retest all. Run the entire regression suite on every change. The most thorough option, and realistic only if the suite runs fast, which in practice means running tests in parallel.
  • Selective regression testing. Run only the tests related to the code that changed. Faster, but it depends on knowing what a change can affect, and that's exactly what tends to surprise you.
  • Prioritized regression testing. Run the most important tests first (checkout, login, anything tied to revenue or compliance) and the rest after, or less often.
  • Progressive regression testing. When requirements change, update and add tests as the product evolves, so the suite reflects how the app works today.
  • Partial regression testing. After a small, contained change, run the tests for the affected area plus the critical paths.

Most teams end up somewhere in between: a fast critical-path subset on every pull request, and the full suite on every deploy to staging.

When should you run regression tests?

  • On every deploy, ideally triggered automatically from your CI/CD pipeline. This catches problems while the change is still fresh and small.
  • After bug fixes, since a fix is a code change like any other.
  • After dependency, framework or infrastructure upgrades, which can break things without anyone touching your application code.
  • Before a major release, as a final full run.
  • After configuration and feature-flag changes, which change behavior without a code deploy.

If regression tests only run before a big release, every failure becomes an archaeology project: which of the last 40 changes broke this? Running on every deploy keeps the answer obvious.

How to do regression testing

  1. List your critical user flows. Start with what would hurt most if it broke: sign-up, login, payments, core workflows. That's your first regression suite.
  2. Automate the tests. Manual regression testing doesn't scale past a handful of flows or a slow release cadence. Write end-to-end tests in an open framework like Playwright or Appium so your team can read, run and own them.
  3. Run them in parallel on every deploy. A suite that takes two hours gets skipped. One that finishes in minutes runs every time.
  4. Investigate every failure quickly. A failed test is either a real bug or a test that needs updating. Somebody has to decide which, fast, or the failures pile up and people stop trusting the suite.
  5. Maintain the suite as the product changes. Update tests when features change on purpose, and remove tests for features that no longer exist.
  6. Add a test for every escaped bug. When a bug reaches production, write a test for it so it can't come back unnoticed.

A regression test example in Playwright

Here's a small regression suite for a cart's discount code. It checks that a valid code lowers the total and an invalid one doesn't, so a future change to pricing or checkout can't break discounts silently. The tag lets CI run just the regression suite with npx playwright test --grep @regression.

import { test, expect } from '@playwright/test';

test.describe('cart discounts', {
  tag: '@regression',
}, () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/cart');
  });

  test('a valid code lowers the total', async ({
    page,
  }) => {
    await page
      .getByLabel('Discount code')
      .fill('SAVE10');
    await page
      .getByRole('button', { name: 'Apply' })
      .click();

    await expect(page.getByRole('alert'))
      .toHaveText('Code applied');
    await expect(page.getByTestId('total'))
      .toHaveText('$90.00');
  });

  test('an invalid code is ignored', async ({
    page,
  }) => {
    await page
      .getByLabel('Discount code')
      .fill('NOTACODE');
    await page
      .getByRole('button', { name: 'Apply' })
      .click();

    await expect(page.getByRole('alert'))
      .toHaveText('Invalid code');
    await expect(page.getByTestId('total'))
      .toHaveText('$100.00');
  });
});

Notice the second test. Regression suites need to check that things that shouldn't change didn't, not just that the happy path works.

Manual vs. automated regression testing

Manual regression testing means a person clicks through the app after each change, usually from a checklist. It works for a small app with infrequent releases, and for exploratory checks a script can't do. But it's slow, it gets skipped under deadline pressure, and people miss things on the fortieth run of the same checklist.

Automated regression testing runs the same checks in code, as often as you want. It's the only option that keeps up when you deploy several times a day. The catch is that automated tests are software too: someone has to write them, run them, investigate failures and keep them working as the product changes.

Why regression suites break down (and what it costs)

Writing the tests is the easy part. The recurring work is what sinks most regression suites. In QA Wolf's analysis of 3.5 million tests across more than 100 apps, investigating a test failure took about 17 minutes, fixing a broken test about 45 and reporting a bug about 30, and those costs come back every time you ship (how billing models shape the total cost of ownership in QA).

Without ongoing maintenance, tests decay fast: about half of end-to-end tests need to be modified or removed within six weeks (what happens when teams keep maintenance in-house). Then flaky tests creep in, developers start re-running failures until they pass, and the suite stops being a signal anyone trusts.

So the real question isn't whether to regression test. It's who keeps the suite running and trustworthy as you ship more.

How QA Wolf handles regression testing

This is the part where we talk about ourselves. QA Wolf builds, runs and maintains your end-to-end regression suite so it keeps up with how fast you ship.

  • Coverage in weeks. Our AI agents map your app's critical flows and write production-grade Playwright and Appium tests. Teams reach 80%+ automated end-to-end coverage in weeks.
  • Runs on every deploy, in minutes. Tests run 100% in parallel, triggered from your CI/CD pipeline, so the full suite runs every time, not just before big releases.
  • Only verified bugs reach you. When a test fails, a QA engineer investigates and reproduces it. You get a bug report with steps, logs and a recording, not a pile of raw failures.
  • Maintenance is on us. We guarantee zero flakes, with failures investigated and tests maintained within 24 hours.
  • You own the tests. They're open-source Playwright and Appium code you can read, run and export.

You pay for outcomes, not hours, so running the full suite on every deploy doesn't raise the bill. For example, Salesloft runs 2,000 automated tests, with 300+ executing in parallel on every PR, and saves more than $750K a year in QA engineering.

The bottom line

Regression testing is how you keep shipping without breaking what already works. Start with your critical flows, automate them, run them on every deploy and add a test for every bug that escapes. Then make sure someone owns the recurring work of investigating failures and maintaining tests, because that's where regression suites live or die.

Frequently Asked Questions

What is meant by regression testing?

Regression testing means re-running tests on features that already worked after a code change, to make sure the change didn't break them. A "regression" is a bug in something that used to work.

What is regression testing used to test?

It tests existing functionality: the flows users already rely on, like login, search and checkout. It catches side effects of new features, bug fixes, dependency upgrades and configuration changes.

What's the difference between regression testing and retesting?

Retesting checks that a specific bug is fixed. Regression testing checks that the fix, or any other change, didn't break something else. Teams usually retest the bug and then run the regression suite.

What's the difference between regression testing and UAT?

User acceptance testing (UAT) is when business users or customers confirm the software does what they need before release. Regression testing checks that changes didn't break existing features. UAT asks whether you built the right thing; regression testing asks whether you broke something.

How often should you run regression tests?

Ideally on every deploy, triggered from your CI/CD pipeline, plus a full run before major releases. Running often keeps each failure tied to a small, recent change.

Can regression testing be automated?

Yes, and most teams automate it. Automated end-to-end tests in a framework like Playwright or Appium can run the full suite in parallel on every deploy. The ongoing work is investigating failures and maintaining tests as the product changes.

Try the AI testing platform that makes QA 12x faster.