Skip to content

Debug cargo test

Stop inside a Rust test.

Prerequisites

  • codelldb on PATH
  • a profile for the project — the test flow inherits everything but the program from it

The short way: the test under the cursor

No extra config. In Neovim, put the cursor inside the test and:

:DebugTest

Or from a terminal, naming the location:

bugsaur gui --project . --test-at src/lib.rs:42

Bugsaur builds the tests with cargo test --no-run --message-format=json, picks the resulting test binary from the compiler's output, and debugs that with the selected test's filter.

The adapter, environment and working directory come from the profile; only the program and its arguments are replaced.

Two conditions

The buffer must be saved. The backend reads the file from disk and cannot match unsaved text against a compiled binary.

Saved breakpoints are not picked up. A test run uses only the breakpoints of that request — unlike :DebugStart.

The whole test module

Put the cursor on the group line — mod tests — and run the same command. It runs the entire group instead of one test.

The long way: a dedicated profile

Useful when you always debug the same test binary, for instance in CI-like conditions.

cargo test --no-run --message-format=json | grep executable

Take the path it prints and point a profile at it:

[profiles.lib-tests]
adapter = "codelldb"
program = "target/debug/deps/mycrate-1a2b3c4d5e6f"
args = ["my_test_name", "--exact", "--nocapture"]

The hash in the file name changes

The test binary's name contains a build hash, which changes when the crate is rebuilt. That is exactly why the test-under-cursor flow exists — it re-reads the path from the compiler on every run.

Common test-specific settings

Tests that read testdata/

cargo test starts the binary from the package directory. Under the debugger the working directory is the project root, so relative paths differ:

[profiles.lib-tests]
adapter = "codelldb"
program = "target/debug/deps/mycrate-1a2b3c4d5e6f"
cwd = "crates/mycrate"

Seeing test output

Rust captures output from passing tests. --nocapture in args shows it in the Logs panel under the Program category.

When it does not work

Symptom Fix
:DebugTest refuses the cursor is not inside a test function; #[test] counts
"buffer not saved" save the file
Breakpoints ignored expected — a test run uses only this request's breakpoints
Stops in the wrong test the filter matched several; use a more specific name
Nothing builds run cargo test --no-run by hand and read the error