Stacks

Write Unit Tests for Untested Code in C# with Atlas (2026)

Updated 8 min read

Atlas writes unit tests for untested C# code by reading the target class, enumerating its exported symbols with the lsp tool's documentSymbol operation so no public method is missed, grepping for an existing test file to copy the repo's framework, import style, and naming convention, writing the new spec with the write tool, and then actually running it with xUnit via dotnet test through the bash tool. The run is the point. A test that was never executed is not a test.

How does Atlas add xUnit tests to an untested C# class?

Atlas reads the untested C# class, then calls the lsp tool's documentSymbol operation on it to enumerate every exported symbol, so a public method buried at the bottom of a 600 line OrderService.cs is not quietly skipped. Coverage of the public surface is the goal, not coverage of the obvious methods.

Reading a C# file top to bottom and testing what you remember produces exactly the gaps you would expect: the async overload gets tested, the sync one does not; the happy-path method gets tested, the internal validation helper promoted to public last quarter does not. documentSymbol returns the real member list from the C# language server, including every public method, property, and constructor. Atlas works that list, and where the class is large it keeps progress in a todowrite entry per member so a half-covered class does not look finished.

How does Atlas match the repo's existing xUnit conventions instead of inventing its own?

Atlas greps for an existing test file in the C# solution and copies its framework, import style, and naming convention, step 2 of the documented workflow. If tests/OrderService.Tests/OrderServiceTests.cs already uses an xUnit Theory with InlineData and a shared fixture, the new spec looks the same rather than introducing a competing pattern.

Convention drift is the usual complaint about generated C# tests. An agent that does not look at your repo will happily write MSTest attributes into an xUnit project, invent its own AAA comment style, or new up dependencies that your solution injects through a fixture. Atlas greps first, through ripgrep with real regex plus include and path filters, scoped to your tests project. It reads the closest existing spec, copies the using directives, the fixture pattern, and the file naming, and writes the new test so it belongs in the solution.

Why does Atlas run dotnet test instead of just writing the C# test file?

Atlas runs the new C# spec with xUnit via dotnet test through the bash tool, because a test that was never executed is not a test. Output over 2000 lines or 50 KB is truncated with the full log saved to a file, so a long MSBuild error trail is still fully readable.

The run is where the generated assertions meet reality. dotnet test compiles the test project against the real OrderService.cs, so a wrong parameter order, a missing NuGet reference, or a misunderstood nullable annotation surfaces immediately as a compiler error rather than as a green checkmark on a file nobody ran. When the output is long, the Atlas bash tool truncates at 2000 lines or 50 KB and saves the complete log to a file you can read, so a large xUnit run is still fully inspectable.

How do you review C# test files before Atlas writes them to disk?

Atlas writes the new C# spec file with the write tool, which shows the diff in the permission prompt before anything lands on disk. Every Atlas tool call is permission-gated against 3 rule types, allow, ask, and deny, so tests/OrderService.Tests/OrderServiceTests.cs is created only after you approve the content.

You see the full file, as a diff, in the prompt. That is the review gate, and it applies to the dotnet test invocation too, so nothing runs in your solution outside your allow rules. Atlas also snapshots file changes as git patches, which means a test file that turns out to duplicate existing coverage can be diffed and rolled back cleanly. On a larger job, Atlas drafts a plan in a read-only plan agent and asks before switching to a build agent, so you can approve the member list before any C# is written.

What happens when the generated C# tests fail on the first dotnet test run?

Atlas iterates with the edit tool until the xUnit suite is green, keeping progress in a todowrite list when the C# class is large. A first dotnet test run that reports 4 failures out of 12 is the expected starting point, not a failure of the workflow.

The first failures are usually informative rather than embarrassing. A test asserting the wrong exception type tells you the class throws something more specific. A test failing on a null argument tells you the guard clause behaves differently than the signature suggested. Atlas reads the failure, edits the spec or, where the production code is genuinely wrong, flags it, and re-runs dotnet test. dotnet format keeps the touched C# files consistent, and NuGet resolves any test package the existing convention required.

Does Atlas understand a C# solution before it starts writing tests?

Atlas runs in a solution with a .csproj or .sln and reads your namespaces, project references, and NuGet packages first, the 3 documented C# setup steps. Atlas indexes C# code by AST declarations using tree-sitter, not blind line windows, so retrieval returns whole methods and classes rather than fragments.

That indexing choice is why Atlas can propose a correct xUnit test on the first attempt: when it retrieves OrderService.Validate, it gets the whole method, including the guard clauses and the exception it throws, rather than a window sliced through the middle. Atlas also searches C# code with hybrid semantic and keyword retrieval fused by reciprocal rank fusion, so asking for the class that handles refund eligibility finds it even if the class is not named that. If the code must stay local, Atlas can build the index with local Ollama embeddings.

Step by step

  1. 01Run atlas in a solution with a .csproj or .sln and let Atlas read your namespaces, project references, and NuGet packages.
  2. 02Read the C# class under test, then use the lsp tool's documentSymbol operation to enumerate its exported symbols so no public method is missed.
  3. 03Grep the tests project for an existing spec to copy the repo's framework, using directives, fixture pattern, and file naming convention.
  4. 04Write the new spec file with the write tool, which shows the diff in the permission prompt before anything lands on disk.
  5. 05Run the suite with xUnit via dotnet test through the bash tool; output over 2000 lines or 50 KB is truncated and the full log is saved to a file you can read.
  6. 06Iterate with edit until the xUnit suite is green, reviewing the unified diff Atlas surfaces for each change.
  7. 07Keep progress in a todowrite list, one entry per public member, when the C# class is large.
  8. 08Run dotnet format over the new test files and dotnet build before committing the coverage.

Frequently asked questions

how to generate xUnit tests for an untested C# class
Run atlas in your solution. Atlas reads the class, enumerates its public members with the lsp tool's documentSymbol operation, greps your tests project for the existing convention, writes the spec with the write tool, and runs xUnit via dotnet test until it is green.
will an AI agent write C# tests that match our existing conventions
Atlas greps for an existing test file first and copies the repo's framework, using directives, fixture pattern, and naming convention rather than inventing its own. The new spec is written to look like it belongs in the solution.
does Atlas actually run dotnet test or just write the test file
Atlas runs the suite with xUnit via dotnet test through the bash tool. A test that was never executed is not a test: running it is what catches a wrong parameter order, a missing NuGet reference, or a misunderstood nullable annotation.
how does Atlas make sure no public C# method is left untested
The lsp tool's documentSymbol operation enumerates the class's exported symbols from the C# language server, so the member list is authoritative rather than remembered. On a large class, Atlas tracks one todowrite entry per member.
can I review generated C# test files before they are written
Yes. The write tool shows the diff in the permission prompt before anything lands on disk, and every Atlas tool call is permission-gated against allow, ask, and deny rules. Atlas also snapshots file changes as git patches so a file can be rolled back.
what if the dotnet test output is too long to read
The Atlas bash tool truncates inline output at 2000 lines or 50 KB and writes the complete log to a retained file, telling you the path. Atlas reads that file, so a large xUnit run is triaged against the full output.
does Atlas run dotnet format on the tests it writes
Atlas can run dotnet format over the new C# files through the bash tool, subject to your allow, ask, and deny permission rules. Every tool call is permission-gated before it runs.

Try Atlas in your terminal

The terminal-native AI coding agent. Free core, single binary.

Install Atlas

Related guides

Write Unit Tests for Untested Code with Atlas in 2026

How to write unit tests for untested code with Atlas in 2026: the lsp tool enumerates exported symbols, grep copies repo conventions, and bash actually runs the suite.

Atlas for C# in 2026

Atlas is a terminal-native AI coding agent for C# and the .NET SDK in 2026. Run it in a solution with a .csproj or .sln and approve every diff before dotnet build.

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

Red first, then green. Atlas writes a failing xUnit test in C#, proves it reproduces the bug with dotnet test in 2026, applies the fix, and re-runs the same command.

Self-Review Your Working Diff Before Committing in C# with Atlas (2026)

Self-review a C# working diff in 2026 with Atlas: read the full diff and every changed file, grep for leftovers, revert from a snapshot, then run xUnit via dotnet test.

Review a Pull Request in C# With Atlas (2026)

Review a C# pull request with the context a line-by-line read misses. Atlas pulls the raw diff, reads whole files, and checks callers with the lsp tool's findReferences.

Locate Where a Behavior Is Implemented in C# with Atlas (2026)

Find the exact C# file and symbol behind a behavior in 2026: Atlas attacks a .sln from three angles with codebase_search, grep through ripgrep, and the lsp tool.

Refactor a legacy module in C# with Atlas (2026)

How Atlas refactors a legacy C# module in 2026: lsp findReferences enumerates every callsite, apply_patch anchors on context, and xUnit via dotnet test pins behavior.

Diagnose a Hanging or Long-Running Command in C# with Atlas (2026)

Work out whether a dotnet build is genuinely slow or silently blocked on input, using Atlas in 2026, and get NuGet restore and dotnet test unstuck for good.

Browse this resource hub