Confirmation and Regression Testing

Every change to software raises two questions. Confirmation testing, also called re-testing, asks whether the reported defect is really fixed: you repeat the failed test on the build that contains the fix. Regression testing asks whether the fix, or any other change, broke something that used to work: you re-run tests that passed before, in areas that were not supposed to change.

For example, a developer fixes a checkout form that rejected mobile numbers written as +966 50 000 1234. The confirmation test enters that number again and places the order. The regression tests check sign-up, profile editing and the one-time password (OTP) screen, because they use the same validation code.

Why it matters

A regression is a loss of quality caused by a change: a feature that worked yesterday fails today. Products share code, data and services, so a one-line fix in one place can break a screen nobody touched, and such a defect reaches production easily when the team checks only the reported bug.

The two give different evidence: closing a defect without a confirmation test reports a fix that may not exist, and confirming a fix without regression testing implies a safe release that nobody checked. Choosing a scope that fits the time, and what to automate, is a call you make after almost every fix.

Confirmation testing: is the defect really fixed?

The ISTQB Foundation syllabus describes confirmation testing as confirming that an original defect has been successfully fixed. Depending on the risk, you run all the test cases that failed because of the defect and add new tests that cover the changes made for the fix; when time or money is short, you at least repeat the steps that reproduced the failure and check that it no longer occurs.

Use the original steps, data and environment first, so a pass really means the fix works. Then vary one thing at a time — another input format, another role, the neighbouring boundary value — because a fix often covers only the reported case. The edge cases from the previous lesson are a good source of variants.

  • Check the build: the defect’s resolution names the build with the fix.
  • Pass: record build, data and result, then run regression tests before closing the defect.
  • Fail: reopen the same defect with the new evidence instead of opening a second one.

Regression testing: did the change break anything else?

Regression testing re-runs tests that passed before, to detect defects that a change has introduced or uncovered in parts not meant to change. "Uncovered" matters: a fix can expose an older defect that the first one was hiding, such as a second check that never ran because the first always rejected the input.

The syllabus notes that the effects can appear in the changed component, in other components or in connected systems, and that regression testing is not limited to the test object: it can also concern the environment. A fix that passed its confirmation test still needs regression testing, because the fix is itself a change, and both kinds of testing are needed at every test level where a defect is fixed or a change is made. Typical triggers:

  • Defect fixes, new features and refactoring (restructuring code without changing what it does).
  • Upgrades of libraries, frameworks, the database or the operating system.
  • Configuration changes, feature flags (switches that turn a feature on or off), database migrations and changes in connected systems.

Impact analysis: choosing what to re-run

Running every test after every change is the safest choice and, for a small suite, the right one. The syllabus advises an impact analysis first, to decide the extent of regression testing: it shows which parts of the software a change could affect. It matters most once the full suite no longer fits the time available. Read the change and ask the developer instead of choosing from memory.

The answers to the questions below give a scope in three rings: the changed area, its direct dependents, and a small core of critical journeys that runs after every change. Record what you leave out and why; a scheduled full run catches what the selection missed.

  • What exactly changed: code, data structure, configuration or a dependency? The pull request (the change the developer submits for review) and its diff of changed lines tell you.
  • Who else uses it: screens, APIs, reports, jobs or services that call the same function or read the same table. A traceability matrix shows which tests cover a changed requirement.
  • Which stored data does it touch: records saved before the change must still work after it.
  • What is high risk regardless: payments, login, data export, and areas that broke after similar changes.
After a fix: confirm the reported failure is gone, analyse the impact, run the selected regression tests, then close the defect and keep its test in the automated suite.
  1. 1Fix deliveredThe defect names the build that contains the fix
  2. 2Confirmation testalso called re-testingOriginal steps and data first, then nearby variants

    Branch: Still fails: reopen the defect with new evidenceFail

    Gate: the reported failure no longer occurs

  3. 3Impact analysisWhat changed, who uses it, which stored data it touches, what is high risk
  4. 4Selected regression testsChanged area, direct dependents, always-run core

    Branch: New failure elsewhere: report a new defect linked to the fixFail

    Gate: no new failures

  5. 5Close and keep the testClose the defect; add the confirmation test to the automated regression suite
Outside the sequence
  • Scheduled full regression runNightly or before release: catches what the selection left out

Two kinds of failure, two actions: a failed confirmation test reopens the same defect; a new failure found by regression testing becomes a new defect linked to the fix.

Try it: Regression Scenario Generator Try it: Requirements → Test Cases Try it: Risk-Based Test Generator

Worked example: a fix in shared validation code

Defect BUG-2143: at checkout, mobile numbers in international format, such as +966 50 000 1234, are rejected as "Invalid phone number". Build 3.4.2 fixes the shared function normalizePhone(). Asking "who else uses it?" shows that sign-up, profile editing and the OTP SMS service call it too.

The confirmation test passed: the number and its variants are accepted and saved in one format, and a too-short number is still rejected. Regression testing found a new failure: customers whose numbers were saved before the fix no longer receive their OTP, because the SMS service now looks numbers up in the new format. That new defect is reported separately and linked to BUG-2143, not reopened as the original.

  • The stored-data question of the impact analysis caught it: new numbers worked; only records saved before the change failed.
  • Comparing one existing customer’s profile API response on the old and the new build shows the format change at a glance.
  • The note below records the plan, including what was deliberately left out.
BUG-2143 | build 3.4.2 | changed: normalizePhone() in shared validation

1. CONFIRMATION  (original steps, data and environment first)
   [ ] checkout with +966 50 000 1234        -> accepted, order placed
   [ ] 0500001234, 966500001234, with spaces -> accepted, saved as +966500001234
   [ ] +966 50 000 12 (too short)            -> still rejected

2. REGRESSION  (selected by impact analysis)
   changed area  phone field at checkout: all existing test cases
   dependents    sign-up, profile edit, OTP by SMS: same stored format
   stored data   customers saved before 3.4.2 still receive their OTP
   core          log in, search, card payment (critical journeys)
   left out      wishlist and reviews: they do not use phone numbers
   safety net    full regression suite in the scheduled nightly run

Try it: API Response Comparator

Why regression tests are the first to automate

Regression tests run again and again and the suite grows with every release, so the syllabus calls regression testing a strong candidate for automation, started early. In continuous integration they run on every change, often at several levels: component tests for logic, API tests for services, a few end-to-end journeys.

A confirmation test is often run once, by hand. Keep it as an automated regression test at the lowest level that can express it — here, a component test of normalizePhone() with the reported number and its variants — so the defect cannot return unnoticed.

  • Good candidates: stable features, deterministic expected results, critical journeys, rules checked with many data values.
  • Poor candidates: features still changing every sprint, one-off checks, judgements about layout or ease of use.
  • Automation runs tests but does not choose them, and the suite needs maintenance like any code.

Common mistakes

  • Closing a defect on the developer’s word, without a confirmation test on the fixed build.
  • Re-testing only the reported value and missing variants the fix does not handle.
  • Treating a passed confirmation test as proof that the release is safe and skipping regression testing.
  • Choosing regression tests from memory instead of from the change, its dependents and its data.
  • Reopening the original defect for a new failure found by regression testing, mixing two histories.
  • Letting the regression suite only grow until outdated, duplicated and skipped tests slow every run.

The QA perspective

On a team, this work starts when a defect is marked resolved. Ask the developer which build contains the fix, what exactly changed and what else uses that code; record the answers and your scope in the defect or test run so the decision can be reviewed.

Report the two results apart, for example: "BUG-2143 confirmed fixed on 3.4.2. Regression: 45 of 46 selected tests passed, one failed with a new defect (BUG-2150), wishlist and reviews not run, full suite tonight." Release decisions rest on such a sentence, so it must say what was and was not tested.

Practice exercise

Plan the re-test and regression scope for a shipping fix

Your task

Defect BUG-3310: "Orders of 200.00 SAR or more ship free, but the check ignores coupons: a 210.00 SAR cart with a 20.00 SAR coupon still ships free." Build 5.2.0 fixes calculateShipping() in the pricing service, which the cart page, the checkout summary, the mobile order preview and the nightly invoice export also use.

Plan the confirmation tests and the regression rings, say what you leave out, and pick one test to automate.

Steps
  1. Write the confirmation test with the defect’s original data.
  2. Add variants on both sides of the 200.00 limit after the discount; prices step by 0.01, as with the boundary values in the previous lesson.
  3. Answer the impact-analysis questions and list the regression rings, including what you leave out.
  4. Pick one test to automate and name its level.
Show the model answer
Model answer

Confirmation: 210.00 minus a 20.00 coupon is 190.00, so shipping is charged. Variants: 199.99 after the discount → charged; exactly 200.00 (220.00 minus 20.00) → free; 250.00 with a 25% coupon (187.50) → charged; 210.00 without a coupon → still free.

Impact analysis: the shipping check in calculateShipping() changed; the cart page, checkout summary, mobile order preview and invoice export use it; orders placed before 5.2.0 are the stored data; payment totals are high risk.

Rings: changed area — all shipping and coupon test cases; dependents — cart, checkout summary and mobile preview show the fee the pricing API returns, and invoices are right for orders before and after 5.2.0; core — log in, add to cart, card payment. Left out: profile, search and reviews, which do not call calculateShipping(). Safety net: the scheduled full run.

Automate: a data-driven component or API test of calculateShipping() (one test that runs once per row of values) with 199.99, 200.00 and the original case, in the pipeline’s regression suite.

Frequently asked questions

Is re-testing the same as regression testing?

No. Re-testing, which ISTQB calls confirmation testing, checks that one specific defect is fixed by repeating the tests that failed. Regression testing checks that the fix, or any other change, did not break other parts that used to work. After a fix you normally need both.

Do I need regression testing if only one line of code changed?

Yes, but its size should match the impact. One line in a shared function can affect every caller, while one changed text on a single screen may need little more than the confirmation test and the always-run core. Impact analysis tells you which case you are in.

Should confirmation tests be automated?

The first confirmation is often done by hand, because it follows the defect report and needs judgement. Afterwards, adding it to the automated regression suite, at the lowest level that can express it, protects against the same defect returning.

Who decides the regression scope?

Usually the tester proposes it from the impact analysis and the risk list, the developer confirms what the change touches, and the test lead or the team agrees on it when time is limited. Whatever is decided, record it so it can be reviewed.

References

Practise with Mutqan tools

Convert a list of numbered requirements into traceable test cases with a requirement-to-test matrix.

Test Design

Score features by likelihood and impact, then generate a prioritised risk-based test plan.

Test Design

Compare two API responses (e.g. staging vs production) and list every structural and value difference.

API Testing

Go deeper

Your progress on this topic

Part of the QA Roadmap