Regression Testing for Prompt Changes

La Lakshmi Priya Updated 07 Nov 2026
8 min read ·Lesson 118 of 140

What Is a Regression? A regression is a case that worked before a change and fails after it. In software, regressions happen when fixing one bug breaks something else. Prompts are especially prone to them, because a prompt's behavior is shaped by every word, and a change aimed at one problem can quietly affect many other inputs.

Example A support classifier mislabels "Payment went through but I can't open the course" as Billing. You add a rule: "If the customer cannot access a course they paid for, choose Access." The case is fixed. But now "I was charged twice and can't see the second receipt" is also labeled Access, because it mentions both payment and not being able to see something. Overall accuracy may even look similar, but the prompt has changed behavior on cases that used to be right.

Regression testing means re-running a fixed set of test cases after every change and comparing the results case by case with the results before the change.

What Triggers Regression Tests Regressions are not caused only by editing the prompt text.

Change Example Prompt text A new rule, a reworded instruction, a new example Shared fragments A change to a data-handling rule included in many prompts (Lesson 68) Model A new model version or a different model (Lesson 67) Settings Temperature, output limits, reasoning settings Retrieval New chunking, new embedding model, updated documents (Lesson 101) Tools Changed tool descriptions or result formats (Lesson 109) Code around the prompt New validation rules, parsing changes Any of these should trigger the regression suite before the change reaches users.

The Regression Testing Process

  1. Keep a stable regression suite: test cases with expected results (Lesson 115)
  2. Record a baseline: the results of the current version on every case
  3. Make the change
  4. Run the same suite on the new version
  5. Compare case by case: fixed, broken, still failing, unchanged
  6. Apply a gate: pass, review, or block
  7. If accepted, the new results become the baseline Why Case-by-Case Comparison Matters Overall scores can hide regressions. If a change fixes two cases and breaks two others, the total stays the same, but the two broken cases may be the important ones. Comparing individual cases reveals exactly what changed (Lesson 66, paired comparison).

Comparing Runs in Code def compare_runs(baseline: dict[str, bool], candidate: dict[str, bool], critical_ids: frozenset[str] = frozenset()) -> tuple[dict, float, float, str]: """Compare pass/fail results per case and decide whether the change may proceed.""" report = {"fixed": [], "broken": [], "still_failing": [], "missing_in_candidate": []} for case_id, passed_before in baseline.items(): if case_id not in candidate: report["missing_in_candidate"].append(case_id) continue passed_now = candidate[case_id] if passed_now and not passed_before: report["fixed"].append(case_id) elif passed_before and not passed_now: report["broken"].append(case_id) elif not passed_before and not passed_now: report["still_failing"].append(case_id)

before = sum(baseline.values()) / len(baseline) after = sum(candidate.get(case_id, False) for case_id in baseline) / len(baseline) critical_broken = [case_id for case_id in report["broken"] if case_id in critical_ids]

if critical_broken or report["missing_in_candidate"] or after < before: decision = "block" elif report["broken"]: decision = "review" else: decision = "pass" return report, round(before, 2), round(after, 2), decision

baseline = {"t1": True, "t2": True, "t3": False, "t4": True, "t5": False, "t6": True} candidate = {"t1": True, "t2": False, "t3": True, "t4": True, "t5": True, "t6": True}

print(compare_runs(baseline, candidate)) print(compare_runs(baseline, candidate, critical_ids=frozenset({"t2"}))[3]) print(compare_runs(baseline, {**candidate, "t2": True})[3]) Output:

({'fixed': ['t3', 't5'], 'broken': ['t2'], 'still_failing': [], 'missing_in_candidate': []}, 0.67, 0.83, 'review') block pass Code Explanation Categories Each case is compared between the baseline and the candidate (the new version):

fixed: failed before, passes now broken: passed before, fails now (a regression) still_failing: failed in both missing_in_candidate: not run in the new version, which means the comparison is incomplete Pass rates before and after are the share of cases passing. The candidate improves the pass rate from 0.67 to 0.83.

The gate

block if a critical case broke, if any case was not run, or if the overall pass rate dropped. review if any non-critical case broke: a person must look at it and decide. pass if nothing broke. Reading the Three Results The candidate fixes two cases but breaks t2. The overall rate improved, so the decision is review, not pass: someone must check whether breaking t2 is acceptable. When t2 is marked critical, for example because it represents a refund rule, the same results are blocked. When t2 also passes, nothing is broken and the change passes. This gate encodes an important principle: an improvement in the overall score does not justify breaking important cases without a deliberate decision.

Critical Cases Not all test cases are equally important. Mark as critical the cases where a failure would cause real harm:

Critical Case Type Example Policy and money Refund eligibility at the 7-day boundary Safety Prompt injection attempts that must be refused (Lessons 121–125) Privacy Requests for another student's data must be refused Format required by code Outputs consumed by automation must always parse Previously fixed bugs Every serious bug, once fixed, becomes a critical case Critical cases should never be broken without an explicit, documented decision.

Handling Inconsistent Results Model outputs can vary between runs (Lesson 120). A case that passes and fails at random would appear as "fixed" or "broken" by chance, creating false alarms or hiding real regressions.

Run Each Case Several Times For cases with variable outputs, run them several times and compare pass rates rather than single results:

Case Baseline Pass Rate Candidate Pass Rate Interpretation t7 5/5 5/5 Stable pass t8 5/5 2/5 Regression t9 3/5 3/5 Unstable in both: investigate the prompt, not the change Practical Rules Treat a case as passing only if it passes in all, or nearly all, of several runs. Define the threshold in advance. Cases that are unstable in the baseline are a problem in themselves; fix the instability before relying on them (Lesson 120). Use deterministic settings where your model and API support them, to reduce variation during testing. Running Regression Tests Automatically Regression tests are most effective when they run automatically, in the same way as code tests:

Pull request changes a prompt file ↓ CI runs the regression suite with the new prompt version ↓ compare_runs() against the stored baseline ↓ pass → merge allowed review → reviewer must approve broken cases with a note block → merge not allowed until fixed What to Store Item Why Prompt version and model for each run Know exactly what was tested (Lesson 67) Full outputs, not only pass/fail Read what changed in broken cases Per-case results Compare runs case by case The baseline used for comparison Reproduce the decision later Cost Control Regression suites call the model many times. Keep a core suite of the most important and representative cases that runs on every change, and run a larger suite before releases or model upgrades.

Regression Testing When Models Change Model updates can change behavior across many cases at once, even when your prompt is unchanged. Before switching models or versions:

Run the full regression suite on the new model. Compare case by case with the current model's baseline. Read every broken case, and check critical cases first. Adjust prompts if needed, and re-run. Switch only when the gate passes, and keep the old model available for rollback. Pinning model versions in production, where your provider allows it, ensures that model changes happen when you choose, after testing (Lesson 67).

Common Mistakes Mistake 1: Comparing Only Overall Scores What it is: Accepting a change because the average improved.

Why it happens: Averages are easy to compare.

What it causes: Important cases break unnoticed.

How to fix it: Compare case by case and review every broken case.

Mistake 2: No Stable Suite What it is: Testing each change on a different set of examples.

Why it happens: New examples are chosen for each change.

What it causes: Regressions in older cases are never checked.

How to fix it: Keep a stable regression suite, and add to it rather than replacing it.

Mistake 3: Ignoring Non-Prompt Changes What it is: Running regression tests only when prompt text changes.

Why it happens: The prompt seems to be the only thing that affects behavior.

What it causes: Model, retrieval, and tool changes introduce regressions silently.

How to fix it: Trigger the suite for every change that can affect outputs.

Mistake 4: Treating Random Variation as Regression What it is: Reacting to single-run differences on unstable cases.

Why it happens: Each case is run once.

What it causes: False alarms, or real regressions dismissed as noise.

How to fix it: Run unstable cases several times and compare pass rates.

Mistake 5: Updating Expectations to Make Tests Pass What it is: Changing a test's expected result because the new version fails it.

Why it happens: It makes the gate pass.

What it causes: Regression tests stop protecting anything.

How to fix it: Change expectations only when the requirement itself changed, with a documented reason.

Best Practices Keep a stable regression suite. Include critical cases and every fixed bug.

Store baselines with versions and full outputs. Make comparisons reproducible.

Compare case by case. Fixed, broken, still failing, missing.

Gate changes automatically. Block critical breaks; require review for others.

Run the suite for every change that affects outputs. Prompts, fragments, models, settings, retrieval, tools.

Handle variation deliberately. Multiple runs and pass-rate thresholds for unstable cases.

Try It Yourself Exercise 1: Baseline and Candidate Run your test suite from Lesson 115 with your current prompt and save the pass/fail result for each case. Make one prompt change, run the suite again, and use compare_runs() to produce a report and a decision.

Exercise 2: Critical Cases Mark at least five cases in your suite as critical, with a one-sentence reason for each. Make a deliberately harmful prompt change, such as removing the boundary rule, and confirm that the gate blocks it.

Exercise 3: Unstable Cases Run every case in your suite five times. Identify cases that do not pass consistently in the baseline, and list them. For each, decide whether the instability comes from an ambiguous test case or from the prompt, and fix one of them.

0 Comments

Reviewed before they appear

No comments yet.

Prompt Engineering
Prompt Engineering Introduction How Large Language Models Respond to Prompts Prompting Basics Elements of an Effective Prompt Writing Clear Instructions for AI Models Adding Context to a Prompt Providing Input Data in Prompts Using Output Indicators and Response Formats Prompt Formatting: Questions, Instructions, and Templates General Tips for Designing Better Prompts Common Prompt Engineering Mistakes Iterative Prompt Design and Refinement Understanding Instruction, Context, Input, and Output How Specificity and Conciseness Affect Prompt Quality Breaking Large Tasks into Smaller Prompting Tasks Zero-Shot Prompting Zero-Shot Prompting Examples for Everyday Tasks Zero-Shot Text Classification Zero-Shot Question Answering Zero-Shot Summarization Zero-Shot Translation Zero-Shot Prompting for Information Extraction When to Use Zero-Shot Prompting Limitations of Zero-Shot Prompting Improving Weak Zero-Shot Prompts Few-Shot Prompting One-Shot Prompting vs Few-Shot Prompting Choosing Good Examples for Few-Shot Prompts Formatting Examples in Few-Shot Prompts Few-Shot Classification with Examples Few-Shot Prompting for Structured Output Few-Shot Prompting Zero-Shot vs Few-Shot Prompting Role Prompting and Persona Instructions Instruction-Based Prompting Task-Oriented Prompt Templates Using Delimiters to Separate Prompt Sections Prompt Templates with Variables Chain-of-Thought Prompting Zero-Shot Chain-of-Thought Prompting Few-Shot Chain-of-Thought Prompting Automatic Chain-of-Thought (Auto-CoT) When Chain-of-Thought Prompting Helps Limitations of Chain-of-Thought Prompting Self-Consistency Prompting Comparing Chain-of-Thought and Self-Consistency Tree of Thoughts (ToT) Prompting Exploring Multiple Solutions with Tree of Thoughts Least-to-Most Prompting Complexity-Based Prompting Maieutic Prompting Self-Consistency: Sampling Multiple Reasoning Paths Self-Consistency for Arithmetic and Logic Tasks Tree of Thoughts: Search, Evaluation, and Backtracking Meta Prompting Generate Knowledge Prompting Directional Stimulus Prompting Program-Aided Language Models (PAL) React: Reasoning and Acting with Language Models Reflexion: Improving Agents Through Feedback Prompt Chaining Designing Multi-Step Prompt Chains Decomposing Complex Tasks into Prompt Chains Automatic Prompt Engineer (APE) Active-Prompt: Selecting Useful Reasoning Examples Optimizing Prompts Systematically Prompt Iteration and Versioning Building Reusable Prompt Libraries Testing Prompt Variants Prompt Chaining Fundamentals Passing Outputs Between Prompt Steps Prompt Chains for Summarization and Extraction Validating Intermediate Results in a Prompt Chain Debugging a Multi-Step Prompt Workflow Graph Prompting Multimodal Chain-of-Thought Prompting Automatic Reasoning and Tool-Use (ART) Prompting for Tool Selection and Use Combining Prompting Techniques for Complex Tasks Prompts for Text Summarization Prompts for Information Extraction Prompts for Text Classification Prompts for Question Answering Prompts for Sentiment Analysis Prompts for Rewriting and Editing Prompts for Translation and Localization Prompts for Brainstorming and Creative Writing Prompts for Generating Structured Data Prompts for Explaining Technical Concepts Prompts for Generating and Reviewing Code Prompting for Code Generation Prompting for Code Explanation Prompting for Debugging and Error Analysis Prompting for Unit Test Generation Prompting for SQL Query Generation Prompting for API Documentation Prompting for Technical Documentation Using Prompting to Extract Requirements Creating JSON-Style Structured Responses with Prompts Designing Prompts for Repeatable Developer Workflows Retrieval-Augmented Generation (RAG) How Prompt Engineering Supports RAG Writing Prompts That Use Retrieved Context Grounding Answers in Provided Documents Handling Missing Information in RAG Prompts Reducing Unsupported Claims in Context-Based Answers Prompt Engineering for AI Agents ReAct Prompting for Tool-Using Agents Writing Tool Instructions for AI Agents Prompting Agents to Plan Multi-Step Tasks Prompting Agents to Observe Tool Results Using Feedback and Reflection in Agent Workflows Prompting for Agent Error Recovery How to Evaluate Prompt Quality Creating Test Cases for Prompts Comparing Prompt Outputs with a Rubric Evaluating Accuracy, Relevance, and Completeness Regression Testing for Prompt Changes Building a Prompt Evaluation Dataset Common Causes of Inconsistent Prompt Outputs Prompt Injection: Introduction and Examples Recognizing Prompt Injection Attempts Prompt Leaking and Instruction Disclosure Risks Jailbreaking: Understanding Adversarial Prompts Writing Safer Prompts for Untrusted Inputs Reducing Hallucinations with Clear Instructions and Context Prompt Safety: Limitations and Best Practices Build a Zero-Shot Sentiment Classifier Project Goal Build a Few-Shot Text Classification Prompt Build a Prompt-Based Text Summarizer Project Goal Build a Structured Information Extraction Prompt Build a Prompt Template for Blog Outlines Build a Prompt-Based SQL Assistant Build a Code Explanation Prompt Workflow Build a Multi-Step Research and Summarization Workflow Build a Prompt Comparison and Evaluation Pipeline Build a Prompt-Chaining Workflow for Document Analysis Build a RAG Prompt for Question Answering over Documents Build a Tool-Using ReAct Assistant Create a Reusable Prompt Library for a Web Application
Ask about this post
AI Ask about this post

Ask questions about Regression Testing for Prompt Changes and get answers drawn from it.

Signed-in readers only.