Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VSCode Test Explorer - cannot parse cargo test json output when --nocapture is used #18896

Open
duncanawoods opened this issue Jan 9, 2025 · 1 comment
Labels
C-bug Category: bug

Comments

@duncanawoods
Copy link

duncanawoods commented Jan 9, 2025

Summary

RA fails to parse the json output from cargo test if it doesn't include a stdout field which can happen depending on the cargo test flags used. This can be fixed by treating it as optional in test_runner::TestState e.g.

#[derive(Debug, Deserialize)]
#[serde(tag = "event", rename_all = "camelCase")]
pub(crate) enum TestState {
    Started,
    Ok,
    Ignored,
    Failed { 
        #[serde(skip_serializing_if = "String::is_empty", default)]      // <--- add this
        stdout: String 
    },
}

Detailed Explanation

It's often necessary to see the stdout from println/trace/log generated during a unit test in the vscode Test Results window:

#[cfg(test)]
pub mod tests {
    #[test]
    fn my_test_fails() {
        println!("this is a message before failure");
        assert_eq!(2 + 2, 5);
    }

    #[test]
    fn my_test_works() {
        println!("this is a message before success");
        assert_eq!(2 + 2, 4);
    }
}

By default the stdout is swallowed by cargo test so we need to add the --nocapture flag in settings.json e.g.

"rust-analyzer.runnables.extraTestBinaryArgs": [
    "--nocapture",
    "--show-output"
],

This doesn't cause any issue with passing tests but it has a side-effect that stdout is no longer included in the json output which causes RA to fail to parse test failures so they appear as ignored and don't cause failure to bubble up to the module/package/workspace level e.g.

Image

The raw output from the two command lines RA uses:

Without nocapture

cargo test --package test_example --no-fail-fast --manifest-path ./Cargo.toml -- my_test_fails -Z unstable-options --format=json --show-output
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.00s
     Running unittests src/lib.rs (target/debug/deps/test_example-0f2d3ceff68e8c95)
{ "type": "suite", "event": "started", "test_count": 1 }
{ "type": "test", "event": "started", "name": "example::tests::my_test_fails" }
{ "type": "test", "name": "example::tests::my_test_fails", "event": "failed", "stdout": "this is a message before failure\nthread 'example::tests::my_test_fails' panicked at src/example.rs:6:9:\nassertion `left == right` failed\n  left: 4\n right: 5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
{ "type": "suite", "event": "failed", "passed": 0, "failed": 1, "ignored": 0, "measured": 0, "filtered_out": 1, "exec_time": 0.000434872 }
error: test failed, to rerun pass `-p test_example --lib`
   Doc-tests test_example
{ "type": "suite", "event": "started", "test_count": 0 }
{ "type": "suite", "event": "ok", "passed": 0, "failed": 0, "ignored": 0, "measured": 0, "filtered_out": 0, "exec_time": 0.000057919 }
error: 1 target failed:
    `-p test_example --lib`

With nocapture

cargo test --package test_example --no-fail-fast --manifest-path ./Cargo.toml  -- my_test_fails -Z unstable-options --format=json --show-output --nocapture
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.00s
     Running unittests src/lib.rs (target/debug/deps/test_example-0f2d3ceff68e8c95)
{ "type": "suite", "event": "started", "test_count": 1 }
{ "type": "test", "event": "started", "name": "example::tests::my_test_fails" }
this is a message before failure
thread 'example::tests::my_test_fails' panicked at src/example.rs:6:9:
assertion `left == right` failed
  left: 4
 right: 5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
{ "type": "test", "name": "example::tests::my_test_fails", "event": "failed" }
{ "type": "suite", "event": "failed", "passed": 0, "failed": 1, "ignored": 0, "measured": 0, "filtered_out": 1, "exec_time": 0.000326727 }
error: test failed, to rerun pass `-p test_example --lib`
   Doc-tests test_example
{ "type": "suite", "event": "started", "test_count": 0 }
{ "type": "suite", "event": "ok", "passed": 0, "failed": 0, "ignored": 0, "measured": 0, "filtered_out": 0, "exec_time": 0.000059012 }
error: 1 target failed:
    `-p test_example --lib`
@duncanawoods
Copy link
Author

@HKalbasi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: bug
Projects
None yet
Development

No branches or pull requests

1 participant