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

> Atlas lists every pub item in a Rust module with the lsp documentSymbol operation, mirrors your existing #[cfg(test)] conventions, and proves the new tests with cargo test.

Atlas writes unit tests for an untested Rust module by reading the module, enumerating its exported symbols with the lsp tool's documentSymbol operation so no pub function is missed, and copying the conventions your crate already uses rather than inventing its own. Atlas greps for an existing test to learn whether you keep unit tests in a #[cfg(test)] mod tests block inside the file or as integration tests under tests/, writes the new tests with the write tool, which shows the diff in the permission prompt before anything lands on disk, and then runs cargo test through bash. The run is the point: a test that was never executed is not a test.

## Key takeaways

- The lsp tool's documentSymbol operation lists every pub item in a Rust module, including impl methods, so coverage is enumerated rather than sampled.
- Inline #[cfg(test)] modules can reach private items and files under tests/ cannot, so Atlas greps the crate before choosing where the test goes.
- Atlas runs cargo test itself; a generated Rust test that was never compiled is not coverage, it is the appearance of coverage.
- Good Rust tests assert on the Err and None branches, because rustc already covers the type errors.
- The write tool surfaces the new test file as a diff before it lands, and rustfmt keeps it consistent with the crate.

## How do you add cargo test coverage to an untested Rust module?

Atlas covers an untested Rust module in 5 moves: read the module, enumerate every exported symbol with the lsp tool's documentSymbol operation, grep an existing test for conventions, write the tests, then run cargo test through bash. Step two is what keeps a pub function from being quietly skipped.

Rust modules hide a surprising amount of public surface behind a short file. src/pricing.rs might expose three pub fn items, two pub methods on an impl block, a pub trait with a default method, and a From implementation that everything downstream depends on. A model that skims the file and writes tests for the two functions it noticed produces a confident summary and thin coverage. Atlas enumerates instead. The lsp tool's documentSymbol operation returns the symbol table from the language server, so every pub item in the module appears in the list, including trait impls and associated functions. Atlas then reads the bodies to understand what each one actually does, because a Rust test that only restates the type signature is testing the compiler, which does not need help.

## Does Atlas put Rust tests in a #[cfg(test)] module or in tests/?

Atlas greps your crate and copies whatever it finds. Rust supports 2 placements, a #[cfg(test)] mod tests block inside src/pricing.rs and integration tests under tests/, and the choice is not cosmetic: an inline module can reach private items, while a file in tests/ can only touch the public API of the crate.

That distinction is exactly the kind of thing a model gets wrong when it guesses. Write the test in tests/ and it cannot call a private helper, so it fails to compile and the natural repair is to make the helper pub, which quietly widens your crate's public API to satisfy a test. Write it inline when the crate's convention is integration tests and it looks foreign to every reviewer. Atlas resolves the question with evidence. grep for #[cfg(test)] and for files under tests/, read the closest example, and mirror the framework, the import style (a use super::*; at the top of the inline module is the usual idiom), and the naming convention. Atlas indexes code by AST declarations using tree-sitter, so the search returns real declarations rather than arbitrary line windows.

## Does Atlas actually run cargo test, or just generate test code?

Atlas runs cargo test itself through the bash tool and reads the failures. Output over 2000 lines or 50 KB is truncated and the complete log is written to a file Atlas can read, so a crate whose tests emit long panic backtraces still gets triaged in full rather than from a tail.

Generated Rust tests that were never compiled are worse than no tests, because they carry the appearance of coverage. The first cargo test run of a freshly written test file in Rust very often fails, and usually not on the assertion: it fails on the borrow checker, on a moved value in the second assert, or on a missing Clone. Those are real design signals about the module under test, and they are only visible because the test was executed. Atlas iterates with the edit tool until cargo test is green, keeping progress in a todowrite list when the module is large enough that a dozen pub items each need their own case. Ask Atlas to fix borrow-checker errors or clippy warnings that surface along the way, and review the diff before cargo build.

## How does Atlas decide what to assert in a Rust test?

Atlas asserts on behavior, and in Rust that means the Result and Option branches, not just the happy path. A pub fn returning Result<Invoice, PricingError> has at least 2 behaviors worth pinning, and documentSymbol lists the error enum alongside the function, so both ends of the signature end up covered.

Rust's type system does a great deal of the work that tests do in other languages, which changes what a good Rust test asserts. There is no point testing that a function refuses a wrong type; rustc already guarantees it. What is worth testing is the logic inside the Result: which inputs produce Err, which variant of the error enum, whether an Option is None at the boundary, whether an arithmetic path saturates or wraps as intended. Atlas reads the module body before writing so the assertions target those branches, using assert_eq! for values and matching on the error variant rather than merely checking is_err(). Run rustfmt on the new test file so it matches the rest of the crate, and let cargo test decide whether the assertions hold.

## How do I review Rust tests an AI agent wrote before they land?

In 2026, Atlas shows the new test file as a diff in the write tool's permission prompt before anything lands on disk, and every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs. Adding src/pricing.rs tests is therefore an approval you give, not something you discover later in git status.

Reviewing an AI-written Rust test is quick if you know what to look for. Does the test cover the Err branches documentSymbol surfaced, or only the happy path? Does it live in the right place given whether it needs private access? Does it avoid smuggling in an unwrap that turns a real failure into a panic with no message? Does it clone excessively to dodge the borrow checker rather than modeling ownership the way the rest of the crate does? Atlas gives you the diff up front, and it snapshots file changes as git patches, so a test file you decide against can be diffed and rolled back cleanly. When the tests are right, cargo test is the arbiter and rustfmt keeps them consistent with the crate.

## Steps

1. Start atlas in the crate that holds Cargo.toml so the index covers your modules, traits, and the rest of the cargo workspace.
2. Have Atlas read the untested module, for example src/pricing.rs, so the tests assert on real behavior rather than restating type signatures.
3. Use the lsp tool's documentSymbol operation to enumerate the module's exported symbols, including pub methods on impl blocks and trait implementations, so no public item is missed.
4. Grep for an existing #[cfg(test)] mod tests block and for files under tests/ to learn whether the crate keeps unit tests inline or as integration tests.
5. Let Atlas write the tests with the write tool, matching the crate's import idiom such as use super::*;, and read the diff in the permission prompt before it lands.
6. Run cargo test with the bash tool; output over 2000 lines or 50 KB is truncated and the full log is saved to a file Atlas can read.
7. Iterate with the edit tool until cargo test is green, asking Atlas to work through borrow-checker errors or clippy warnings that the new tests surface.
8. Run rustfmt on the new test code, keep one todowrite entry per untested pub item when the module is large, and review the diff before cargo build.

## FAQ

### Can an AI agent write cargo test coverage for a Rust module that has none?

Yes. Atlas reads the module, enumerates its exported symbols with the lsp tool's documentSymbol operation, greps the crate for existing test conventions, writes the tests with the write tool, and runs cargo test through bash until the crate is green.

### Should Rust unit tests go in a #[cfg(test)] module or the tests directory?

It depends on access, and Atlas greps your crate to find out what you already do. An inline #[cfg(test)] mod tests block can reach private items; a file under tests/ only sees the crate's public API, so putting the wrong test there pressures you to widen visibility.

### How do I make sure every pub function in my Rust module gets tested?

Use the symbol table. Atlas calls the lsp tool's documentSymbol operation to enumerate exported symbols, so pub functions, pub methods on impl blocks, and trait implementations in src/pricing.rs all appear rather than only the ones a skim would notice.

### Does Atlas run the Rust tests it writes?

Yes. Atlas runs cargo test with the bash tool and reads the failures, iterating with edit until the suite passes. Output over 2000 lines or 50 KB is truncated and the complete log is saved to a file, so long panic backtraces are still triaged in full.

### What should a Rust unit test actually assert?

Behavior, not types. rustc already rejects wrong types, so the value is in pinning the Err variants of a Result, the None branches of an Option, and arithmetic edge cases, matching on the error variant rather than only checking is_err().

### Will the new tests break on the borrow checker?

Often, and that is useful information. The first cargo test run of new Rust tests commonly fails on a moved value or a missing Clone. Ask Atlas to fix borrow-checker errors or clippy warnings, then review the diff before cargo build.

### How do I review Rust test files an AI agent generated before they land?

The write tool shows the file as a 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 changes as git patches, so a rejected test file rolls back cleanly.

---

Canonical HTML: https://runatlas.sh/resources/stacks/write-unit-tests-for-untested-code-in-rust
Source of truth: aeo_pages row `/resources/stacks/write-unit-tests-for-untested-code-in-rust` (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.
