# Add a Regression Test for a Bug Fix in C# with Atlas (2026)

> Atlas proves a C# regression test fails before the fix and passes after it, using the exit code the bash tool records in its metadata alongside the dotnet test output.

Atlas adds a regression test for a C# bug fix by working red first, then green: reproduce the bug once with the bash tool and capture the exact failing command, write the failing xUnit test with the write tool asserting on the observed wrong behavior, run it with dotnet test and confirm it fails, apply the fix with edit, then re-run the same command and confirm it passes. Because the bash tool records the process exit code in its metadata alongside the output, the pass and fail states are unambiguous rather than inferred from text.

## Key takeaways

- Red first, then green: the C# regression test must be observed failing with dotnet test before the fix exists.
- The bash tool records the process exit code in its metadata, so pass and fail are unambiguous rather than parsed from console text.
- The edit replacer cascade requires an exact-enough oldString and refuses ambiguous multi-match replacements in a C# file.
- After the targeted re-run goes green, the wider xUnit via dotnet test suite checks for collateral damage.
- Atlas snapshots file changes as git patches, so a wrong fix and its test can be diffed and rolled back.

## What does red first then green mean for a C# regression test?

Red first, then green is the discipline Atlas follows across the 5 documented steps of a C# regression test in 2026: the xUnit test must be observed failing under dotnet test before the fix exists, or it proves nothing about the bug it claims to guard.

The sequence is strict. Atlas reproduces the bug once through the bash tool and captures the exact failing command. It writes the regression test with the write tool, asserting on the observed wrong behavior in tests/Billing.Tests/InvoiceCalculatorTests.cs. It runs xUnit via dotnet test and confirms the new test is red. Only then does Atlas apply the fix. Re-running the same dotnet test command turns the test green, and the delta between those two runs is the evidence that the test actually guards the bug.

## How does the bash exit code make a C# test result unambiguous?

The Atlas bash tool records the process exit code in its metadata alongside the output, so the 2 recorded dotnet test runs, one red and one green, settle a C# result definitively. A nonzero exit is a failure, not a guess parsed out of console text.

Text parsing is fragile here. A dotnet test run prints Passed, Failed, and Skipped counts, plus any Console.WriteLine your code emitted, and an agent reading only the text can talk itself into either verdict. The exit code cannot be argued with. Atlas checks it on the red run and on the green run, so the claim that a C# regression test failed before the fix and passed after it is backed by two recorded exit codes rather than by an optimistic reading of the output.

## How does Atlas apply the C# fix without touching the wrong code?

Atlas applies the C# fix with the edit tool, whose replacer cascade requires an exact-enough oldString and refuses ambiguous multi-match replacements. When the same null guard appears in 2 overloads of InvoiceCalculator.cs, edit errors rather than guessing, and Atlas surfaces a unified diff for approval before the write lands.

Ambiguity is where automated edits do damage in C#, because a solution is full of near-duplicate lines: the same null guard, the same logging call, the same decimal cast repeated across overloads. When the oldString matches more than once and the intent is a single change, the edit tool errors rather than picking one. You add surrounding context to make the match unique. Atlas computes a unified diff for every file edit and surfaces it for approval before writing, so the fix is reviewed before it lands.

## How do you check a C# fix for collateral damage?

Atlas re-runs the same dotnet test command that was red, confirms the regression test now passes, and then runs the wider xUnit suite to check for collateral damage. A fix in InvoiceCalculator.cs that turns 1 test green while turning 3 others red is not a fix.

The targeted re-run and the full run answer different questions. The targeted run, filtered to the regression test, proves the bug is gone. The full xUnit via dotnet test run proves nothing else broke, which matters because a C# rounding or nullability change can ripple through every consumer of the class. When the full run is long, the Atlas bash tool truncates inline output at 2000 lines or 50 KB and saves the complete log to a file you can read, so the wider suite is still fully inspectable.

## How do you reproduce a C# bug before writing the regression test?

Atlas reproduces the C# bug once with the bash tool, capturing the exact failing command and output before step 2 of the workflow writes any test. That captured dotnet test invocation becomes the contract, so the before and after runs in 2026 are directly comparable rather than loosely similar.

Reproduction first is what keeps the regression test honest. Without it, the test is written from a bug report and asserts on what someone believed the wrong behavior was. With it, the test asserts on the output you actually observed. Atlas runs in a solution with a .csproj or .sln, reads your namespaces, project references, and NuGet packages, and every bash invocation is permission-gated against allow, ask, and deny rules before it runs.

## Can I roll back a C# fix if the regression test was wrong?

Atlas snapshots file changes as git patches, so a wrong C# fix and its regression test can be diffed and rolled back together rather than unpicked by hand. Atlas also reads git branches, status, and diffs, and in 2026 it can stage and create commits on your behalf once xUnit via dotnet test is fully green.

The rollback path matters on a bug fix more than almost anywhere else, because a fix applied under pressure is the change most likely to be wrong. With the change snapshotted as a git patch, reverting is a diff away rather than a manual unpick of edits across InvoiceCalculator.cs and its test. dotnet format keeps the touched C# files consistent before the commit, and NuGet resolves any package the test project needed.

## Steps

1. Run atlas in a solution with a .csproj or .sln and let Atlas read your namespaces, project references, and NuGet packages.
2. Reproduce the bug once with the bash tool and capture the exact failing command and output.
3. Write the regression test with the write tool, asserting on the observed wrong behavior, for example in tests/Billing.Tests/InvoiceCalculatorTests.cs.
4. Run the test with xUnit via dotnet test through bash and confirm it fails; the tool records the process exit code in its metadata alongside the output.
5. Apply the fix with edit, whose replacer cascade requires an exact-enough oldString and refuses ambiguous multi-match replacements.
6. Re-run the same dotnet test command and confirm the regression test now passes, checking the exit code, not just the printed counts.
7. Run the wider xUnit suite through bash to check for collateral damage across the solution.
8. Run dotnet format over the touched C# files, then let Atlas stage and commit the fix with its regression test.

## FAQ

### how to write a regression test in C# that proves a bug is fixed

Reproduce the bug with the bash tool and capture the failing command. Write the xUnit test with write, asserting on the observed wrong behavior. Run dotnet test and confirm it fails. Apply the fix with edit, re-run the same command, and confirm it passes.

### why must a regression test fail before the fix

A test never seen red might be asserting on behavior that was already correct, in which case it guards nothing. Atlas runs xUnit via dotnet test before the fix and checks the exit code, so the red state is recorded rather than assumed.

### how does Atlas know a dotnet test run actually failed

The Atlas bash tool records the process exit code in its metadata alongside the output. A nonzero exit is a definite failure, so the verdict does not depend on parsing Passed and Failed counts out of console text.

### will Atlas edit the wrong line in my C# file

The edit tool's replacer cascade requires an exact-enough oldString and refuses ambiguous multi-match replacements. Where a line repeats across overloads in the same class, edit errors instead of guessing, and you add surrounding context to make the match unique.

### does Atlas check for collateral damage after a C# fix

Yes. After the targeted test goes green, Atlas runs the wider xUnit via dotnet test suite. When output is long, the bash tool truncates at 2000 lines or 50 KB and saves the complete log to a file so the full run is still inspectable.

### does Atlas work with dotnet test and NuGet

Yes. Start atlas in a solution with a .csproj or .sln and it reads your namespaces, project references, and NuGet packages. It runs xUnit via dotnet test and dotnet format through the bash tool, which is a real shell.

### can I undo a bug fix Atlas applied

Yes. Atlas snapshots file changes as git patches, so edits can be diffed and rolled back. Atlas also reads git branches, status, and diffs, and can stage and create commits on your behalf once the suite is green.

---

Canonical HTML: https://runatlas.sh/resources/stacks/add-a-regression-test-for-a-bug-fix-in-csharp
Source of truth: aeo_pages row `/resources/stacks/add-a-regression-test-for-a-bug-fix-in-csharp` (segment: Stacks) (this file is generated from it, never hand-edited).
Licence: Atlas is proprietary with a free core. It is not open source and there is no public source repository.
