Quick answer: Regression testing in software testing means re-running existing tests after a code change to confirm that features which already worked still work. It runs after bug fixes, new features, configuration or dependency updates, and before every release. Small teams start manually; most teams automate the stable, high-value part of the suite with tools like Playwright, Selenium or Cypress and run it in CI.
Every tester has seen this happen: a developer fixes the discount calculation on the cart page, the fix passes retesting, the build goes live — and the next morning the invoice PDF shows the wrong total. Nobody touched the invoice code. But the invoice reused the same price helper the developer changed. That is a regression: something that used to work and is now broken because of a change somewhere else.
Regression testing in software testing is the discipline that catches these side effects before users do. This guide is written for manual testers, freshers and QA engineers who want more than a textbook definition. You will learn the types, how to select and prioritise test cases, which regression testing software to use, and how to build an automated regression suite in Playwright with JavaScript that runs every night on its own.
Who this is for
- Manual testers who run regression cycles by hand and want to understand what to automate first
- Freshers preparing for QA interviews where "regression vs retesting" is a guaranteed question
- QA engineers who need a practical, CI-ready regression setup in Playwright
What Is Regression Testing? (Definition + Simple Example)
Regression testing is a type of software testing that re-executes previously passed test cases after a change, to verify that the change has not broken existing functionality. The word "regression" means going backwards — the software regresses to a worse state than before.
A simple example from an Indian e-commerce or fintech app:
- Change: The team adds UPI AutoPay as a new payment option.
- New-feature testing: Testers verify that UPI AutoPay works.
- Regression testing: Testers also re-run the existing tests for card payment, net banking, wallet payment, refunds, order history and the payment-success email — because all of them share the payment module that was just modified.
If card payment now fails because a shared validation function changed, that is a regression bug. Regression testing does not ask "does the new thing work?" It asks "did the new thing break anything old?" If you are still building your foundations, our software testing tutorial for beginners covers the core vocabulary first.
When Should You Run Regression Testing?
Run regression tests whenever the code or its environment changes in a way that could affect existing behaviour. The common triggers are:
- After a bug fix — fixes often touch shared code. Retest the bug, then regress the surrounding area.
- After adding or changing a feature — new code paths can collide with old ones.
- After refactoring — behaviour should be identical; regression tests prove it.
- After configuration changes — feature flags, environment variables, database settings, payment gateway keys.
- After dependency upgrades — a new framework, library, browser or Node.js version can change behaviour silently.
- After infrastructure changes — server migration, new CDN, database version upgrade.
- Before every release — a release-candidate regression run is the final gate before production.
In a modern pipeline these triggers map to different depths: a fast subset on every pull request, the broader suite nightly, and the full suite before a release. We set exactly that up with Playwright later in this guide.
Regression Testing vs Retesting vs Smoke vs Sanity Testing
These four terms get mixed up in interviews and in real projects. Here is the clearest way to separate them:
| Type | Question it answers | Scope | When |
|---|---|---|---|
| Retesting | Is this specific bug actually fixed? | Only the failed test cases linked to the defect | After a fix is delivered |
| Regression testing | Did the change break anything that used to work? | Previously passed tests around (or across) the change | After any change; before releases |
| Smoke testing | Is this build stable enough to test at all? | Shallow check of critical paths (launch, login, main flow) | On every new build |
| Sanity testing | Does this one changed area behave reasonably? | Narrow, focused check of a specific fix or feature | After a minor fix, often before deeper regression |
The key difference between regression and retesting: retesting targets failed test cases to confirm a fix; regression testing re-runs passed test cases to confirm nothing else broke. Retesting has a guaranteed target; regression testing is a search for unknown side effects. In practice, smoke tests are usually a small, tagged slice of the regression suite — which is why tagging (covered below) matters so much.
Types of Regression Testing
Textbooks list these types slightly differently, but these seven cover what you will hear in real teams and interviews:
Regression is just one of many testing types — see our guide to the types of software testing for how it fits alongside smoke, sanity, E2E and the rest.
1. Retest-all regression
Re-run every test in the suite. It gives maximum confidence but is the most expensive. Practical only when the suite is automated and parallelised, or before a major release.
2. Selective regression
Run only the tests that cover the changed modules and the modules that depend on them. This is what most teams do day to day. It needs good traceability between features and test cases.
3. Progressive regression
Used when requirements or specifications change. You write new test cases for the changed behaviour and update the old ones, then run them together so the suite reflects the new expected behaviour.
4. Corrective regression
Used when the specification has not changed and the existing tests are still valid. You simply re-run the existing cases as they are — for example after a refactor or a performance fix.
5. Partial regression
Verifies that a new piece of code integrates correctly with the existing system, by running the tests for the change plus a focused set of tests for the areas it touches.
6. Complete regression
A broad run across the whole application, usually triggered by large changes: a framework upgrade, a root-level code change, or a major release. Similar to retest-all, but often planned as a dedicated cycle.
7. Unit-level regression
Developers re-run unit tests (Jest, JUnit, pytest and similar) on every commit to catch regressions inside a single function or class. It is the fastest layer and the first line of defence — but it cannot catch integration or UI breakages on its own.
Interview tip: If asked "what type of regression did you do?", the honest answer for most projects is "selective regression on every sprint, with a complete regression before major releases, plus automated smoke and critical-path regression in CI." That shows you understand the trade-off.
Regression Test Selection & Prioritisation
No team can run every test after every change. The skill that separates a senior tester from a junior one is choosing which tests to run. Use these three lenses together:
Risk-based selection
Score each feature by business impact (what happens if it breaks?) and likelihood of failure (how complex is it, how often does it change, how many past bugs did it have?). Payments, login, checkout and data-saving flows are almost always high on both. A static "About us" page is low on both.
Change impact analysis
Ask the developer, read the pull request, or check the commit diff: which files and modules changed, and what depends on them? A change to a shared utility (price formatting, date handling, API client) has a much wider blast radius than a change to one screen. Playwright can help here: npx playwright test --only-changed=origin/main runs only the test files changed since the given Git ref (it also follows test files whose imported helpers changed). It is useful on pull requests, but it will not know which application code each test covers — you still need judgement.
Critical user journeys
List the 10–20 journeys your business cannot afford to lose: sign up, log in, search, add to cart, pay, view order, cancel, reset password. Every one of them gets an automated end-to-end regression test, and those tests run on every build regardless of what changed.
A simple priority scheme many teams use:
| Priority | What goes in | When it runs |
|---|---|---|
P1 / @smoke |
Critical user journeys, login, payment | Every commit / pull request |
P2 / @regression |
Core features, frequent past defects, recently changed areas | Nightly and before release |
| P3 / full suite | Edge cases, low-traffic screens, rare configurations | Before major releases or weekly |
Manual vs Automated Regression Testing
Regression testing is repetitive by nature: the same steps, run again and again, with the same expected results. That makes it the most natural candidate for automation — but not everything should be automated on day one.
| Factor | Manual regression | Automated regression |
|---|---|---|
| Setup cost | Low — just test cases | Higher — framework, scripts, CI |
| Cost per run | High — tester hours every cycle | Low — machine time |
| Speed | Hours to days | Minutes, especially in parallel |
| Consistency | Varies with fatigue and attention | Same steps every time |
| Best for | Exploratory checks, UX judgement, unstable new features | Stable, repeatable, high-value flows |
When does automation pay off?
Automation pays off when a test is run often, the feature is stable (its UI and rules are not changing every week), and the flow is important enough that a miss would hurt. If a test runs once a quarter on a screen that is being redesigned, keep it manual for now. If a checkout test runs on every build, automate it first.
A practical path for a manual tester: automate your P1 smoke cases first, then the P2 cases with the most past defects, and keep exploratory testing manual. Our QA automation testing guide walks through that transition in more detail.
Regression Testing Software & Tools (2026)
There is no single "regression testing software" — regression suites are built with general test automation tools plus somewhere to run them. These are the tools you will see most in Indian QA job descriptions and real projects:
Need tools beyond regression? Our software testing tools guide compares the best options by category — test management, API, performance, mobile and security.
| Tool | Best for | Cost |
|---|---|---|
| Playwright | Modern web apps; Chromium, Firefox and WebKit from one API, built-in parallelism, auto-waiting, tracing and tags. JS/TS, Python, Java, .NET. | Free, open source |
| Selenium WebDriver | Large existing Java/Python/C# suites, widest language support, huge community and Grid for distributed runs. | Free, open source |
| Cypress | Front-end teams testing JavaScript web apps with a strong interactive runner. | Open-source runner free; Cypress Cloud is a paid service |
| Katalon | Low-code teams that want record-and-playback plus scripting across web, API and mobile. | Free tier and paid licences |
| TestComplete (SmartBear) | Enterprises testing desktop, web and mobile apps, including keyword-driven tests. | Commercial; free trial |
| BrowserStack / LambdaTest | Cloud grids to run your Playwright, Selenium or Cypress regression suite across many real browsers and devices. | Commercial; trials available |
| Percy / Applitools | Visual regression testing — catching layout and styling changes with screenshot comparison and review workflows. | Commercial; free plans/trials available |
Pricing and plan details change often — always check the vendor's site before you commit. For unit-level regression, the test runner that ships with your language (Jest, Vitest, JUnit, TestNG, pytest) is the default choice.
Which one should you learn? If you are starting fresh in 2026, Playwright is a strong default for web regression: it is free, fast, cross-browser, and has regression-friendly features (tags, projects, retries, traces) built in. Selenium remains valuable because many Indian service companies maintain large Selenium suites. For a broader comparison, see our QA automation guide.
Visual regression deserves its own note: functional tests check that a button works, not that it is still visible and in the right place. Playwright has built-in screenshot assertions with toHaveScreenshot(). We cover thresholds, masking dynamic content and updating baselines in the dedicated Playwright visual regression testing guide, so we will not repeat it here.
How to Automate a Regression Suite with Playwright (JavaScript)
Let's build a real automated regression testing setup with @playwright/test. If you do not have a project yet, run npm init playwright@latest and choose JavaScript.
Step 1: Tag your tests
Tags let one suite serve several purposes: smoke on every pull request, regression nightly, everything before a release. Playwright supports a tag option on test() and test.describe():
import { test, expect } from '@playwright/test'; // Every test in this block gets the @regression tag test.describe('Checkout', { tag: '@regression' }, () => { test('guest user can place an order', { tag: ['@smoke', '@critical'] }, async ({ page }) => { await page.goto('/products'); await page.getByRole('button', { name: 'Add to cart' }).first().click(); await page.getByRole('link', { name: 'Cart' }).click(); await page.getByRole('button', { name: 'Checkout' }).click(); await page.getByLabel('Email').fill('guest@example.com'); await page.getByRole('button', { name: 'Place order' }).click(); await expect(page.getByRole('heading', { name: 'Order confirmed' })).toBeVisible(); }); test('expired coupon shows an error', async ({ page }) => { await page.goto('/cart'); await page.getByPlaceholder('Coupon code').fill('OLD2024'); await page.getByRole('button', { name: 'Apply' }).click(); await expect(page.getByText('This coupon has expired')).toBeVisible(); }); });
Older projects often put tags directly in the title, which also works with --grep:
test('user can reset password @regression @auth', async ({ page }) => { // ... });
Step 2: Run subsets from the command line
# Run the regression suite npx playwright test --grep @regression # Run only smoke tests (fast PR check) npx playwright test --grep @smoke # Smoke OR critical npx playwright test --grep "@smoke|@critical" # Regression, but skip slow tests npx playwright test --grep @regression --grep-invert @slow # Regression on one browser only npx playwright test --grep @regression --project=chromium # Re-run only the tests that failed last time npx playwright test --last-failed # Open the HTML report npx playwright show-report
Step 3: Configure cross-browser projects, retries and traces
Projects run the same tests on several browsers and devices. Retries and traces turn a red CI run into something you can actually debug:
import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './tests', fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 2 : undefined, reporter: [['html', { open: 'never' }], ['list']], use: { baseURL: process.env.BASE_URL || 'https://staging.example.com', trace: 'on-first-retry', screenshot: 'only-on-failure', video: 'retain-on-failure', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'firefox', use: { ...devices['Desktop Firefox'] } }, { name: 'webkit', use: { ...devices['Desktop Safari'] } }, { name: 'mobile-chrome', use: { ...devices['Pixel 5'] } }, ], });
With trace: 'on-first-retry', Playwright records a full trace (DOM snapshots, network, console, actions) only when a test fails and is retried, so you get debugging data without slowing every run. Open it with npx playwright show-trace or from the HTML report.
Retries are a safety net, not a fix. A test that passes on retry is reported as flaky in the HTML report. Track those and fix the root cause — otherwise your regression suite slowly stops being trusted.
Step 4: Schedule a nightly regression run in GitHub Actions
Run smoke tests on every pull request, and the full regression suite every night against staging. GitHub Actions cron schedules use UTC, so 30 20 * * * runs at 2:00 AM IST:
name: Nightly Regression on: schedule: - cron: '30 20 * * *' # 20:30 UTC = 02:00 IST workflow_dispatch: # allow manual runs too jobs: regression: runs-on: ubuntu-latest timeout-minutes: 60 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: lts/* - name: Install dependencies run: npm ci - name: Install Playwright browsers run: npx playwright install --with-deps - name: Run regression suite run: npx playwright test --grep @regression env: BASE_URL: ${{ secrets.STAGING_URL }} - uses: actions/upload-artifact@v4 if: ${{ !cancelled() }} with: name: playwright-report path: playwright-report/ retention-days: 14
The if: ${{ !cancelled() }} line uploads the HTML report even when tests fail — which is exactly when you need it. For pull-request workflows, sharding, caching and Slack notifications, see our Playwright + GitHub Actions CI/CD guide.
Keeping Your Regression Suite Healthy
Most regression suites do not fail because of tooling. They fail because nobody maintains them, they get slow, and the team stops trusting red builds. These habits keep a suite useful:
Control flakiness
- Use web-first assertions like
await expect(locator).toBeVisible()instead of fixed waits such aspage.waitForTimeout(3000). - Prefer user-facing locators (
getByRole,getByLabel,getByTestId) over long CSS or XPath chains. - Quarantine a flaky test with
test.fixme()and a ticket, rather than letting it fail randomly for weeks.
Our flaky Playwright tests fix guide covers the root causes in depth.
Own your test data
- Create the data each test needs (via API or seed scripts) instead of relying on records someone created manually on staging.
- Use unique values (for example, timestamped emails) so parallel tests do not collide.
- Reuse login with Playwright's
storageStatein a setup project, so 200 tests do not each go through the login form.
Use parallelism wisely
- Keep tests independent — no test should depend on another test running first. That is what makes
fullyParallel: truesafe. - Split very large suites across CI machines with
--shard=1/4,--shard=2/4and so on.
Prune and review regularly
- Delete tests for removed features. Merge duplicates. A smaller suite that everyone trusts beats a large one everyone ignores.
- Every production bug should become a new regression test, so the same bug can never return unnoticed.
For structure, naming and Page Object patterns, read 15 Playwright best practices for a stable suite.
AI-Assisted Regression Maintenance with Claude & Playwright MCP
AI does not replace a regression strategy, but it can reduce the most boring part of the job: maintenance. With the Playwright MCP server, an AI assistant like Claude can open a real browser, read the page's accessibility tree, and work against your actual application rather than guessing. In practice that helps with:
- Converting manual regression cases into Playwright tests — paste the steps from your test case document and ask for a test that uses role-based locators. You still review every line.
- Diagnosing failures — when a regression test fails because a button label or page structure changed, Claude can inspect the live page and propose an updated locator.
- Suggesting missing coverage — given a diff and your existing tests, it can point to flows the change touches that have no regression test yet.
Be realistic about the limits. AI can propose a locator fix for a test that failed because of a real bug — which would hide the regression you were trying to catch. A human must decide whether the application or the test is wrong. Generated tests also need review for weak assertions. Treat the AI as a fast pair, not an authority. Our Playwright MCP for testing playbook shows the workflow step by step.
A Practical Regression Testing Checklist
- Identify what changed (code, config, dependencies, infrastructure).
- Run change impact analysis — list affected modules and their dependents.
- Select tests: always the critical journeys, plus risk-ranked tests for affected areas.
- Run smoke first; stop if the build is broken.
- Run the selected regression suite (automated where possible, manual for the rest).
- Triage every failure: real regression, test issue, environment issue or flaky.
- Log defects with steps, evidence (trace, screenshot) and the change that likely caused them.
- Add a new regression test for every escaped bug.
Frequently Asked Questions
What is regression testing in software testing?
Regression testing is re-running previously passed test cases after a code, configuration or dependency change to confirm that existing features still work. It catches side effects, where a change in one area breaks something that used to work in another area of the application.
What is the difference between regression testing and retesting?
Retesting re-runs the failed test cases linked to a specific defect to confirm the fix works. Regression testing re-runs previously passed test cases to confirm the fix or change did not break anything else. Retesting has a known target; regression testing searches for unknown side effects.
What are the types of regression testing?
Common types are retest-all, selective, progressive, corrective, partial, complete and unit-level regression. Most teams run selective regression every sprint, a complete regression before major releases, and automated smoke and critical-path regression tests on every build in CI.
Which is the best regression testing software?
There is no single best tool. Playwright is a strong free choice for modern web apps, Selenium suits large existing Java or Python suites, Cypress fits JavaScript front-end teams, and Katalon or TestComplete suit low-code or enterprise teams. Cloud grids like BrowserStack and LambdaTest run these suites across many browsers.
Can regression testing be done manually?
Yes. Small projects and new, unstable features are often regression tested manually. But because regression testing repeats the same steps every release, the stable and high-value flows such as login, checkout and payments are usually automated so they can run on every build.
How do I run only regression tests in Playwright?
Tag tests with the tag option, for example test.describe('Checkout', { tag: '@regression' }, ...), or add @regression to the test title. Then run npx playwright test --grep @regression. Use --grep-invert to exclude tags such as @slow, and --project to limit the run to one browser.
How often should regression testing be done?
Run a small smoke subset on every commit or pull request, the main regression suite nightly or before each deployment to staging, and a complete regression before major releases. Also run regression after bug fixes, dependency upgrades and configuration changes.
Can AI tools like Claude automate regression testing?
AI tools can help convert manual test cases into Playwright tests, propose locator fixes when the UI changes, and suggest missing coverage, especially with the Playwright MCP server giving Claude access to a real browser. A human still needs to review generated tests and decide whether a failure is a real bug or an outdated test.
Asim Noaman
Senior QA Automation Engineer & AI Testing Specialist
With years of hands-on experience building test automation frameworks for production applications, Asim specializes in combining traditional QA methodologies with cutting-edge AI tools. He has helped teams adopt Playwright and AI-driven testing workflows to ship faster with fewer bugs.
Playwright + Claude AI Course
Go From Manual Regression Cycles to an Automated Playwright Suite
If you run regression by hand today, the next step is automating your critical journeys. The course teaches Playwright in JavaScript from the ground up, then shows how to use Claude and the Playwright MCP server to generate and maintain tests faster. Rated 4.4★ from 116 ratings, with 460+ students, 11.5 hours and 103 lectures.
- Write reliable Playwright tests with role-based locators and web-first assertions
- Organise suites with Page Objects, fixtures and tags
- Use Claude AI and Playwright MCP to generate and fix tests
- Run your suite automatically in GitHub Actions