Skip to content

Clearer error for failed tests which returned a Result Err() #69517

Open
@dbr

Description

@dbr

Problem
I have a test function which returns a Result<...> as a convenient way of testing failable methods. For example:

#[test]
fn exampletest() -> Result<(), std::io::Error> {
    let f = std::fs::File::open("/root/nonexistantfile")?;
    assert_eq!(example_method(&f), 0);
    Ok(())
}

The test started failing for whatever reason, and the cargo test output looked like this:

$ cargo test
   Compiling confusing v0.1.0 (/Users/dbr/confusing)
    Finished test [unoptimized + debuginfo] target(s) in 0.42s
     Running target/debug/deps/confusing-3ccdc020a15819b0

running 1 test
test exampletest ... FAILED

failures:

---- exampletest stdout ----
Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }
thread 'exampletest' panicked at 'assertion failed: `(left == right)`
  left: `1`,
 right: `0`: the test returned a termination value with a non-zero status code (1) which indicates a failure', src/libtest/lib.rs:196:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.


failures:
    exampletest

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--bin confusing'

Not reading the output properly, I interpreted the panicked at 'assertion failed: ... as being a failure from my assert_eq! and started trying to work out why my example_method was returning 0.

I also tried running the tests under a debugger, but the backtrace only pointed at the test closure rather than the probelmatic line:

...
  13: std::panicking::begin_panic_fmt
             at src/libstd/panicking.rs:328
  14: test::assert_test_result
             at ./<::std::macros::panic macros>:9
  15: confusing::exampletest::{{closure}}
             at src/main.rs:6
  16: core::ops::function::FnOnce::call_once
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/ops/function.rs:227

..where src/main.rs:6 is the line fn exampletest() -> Result<(), std::io::Error> {

Steps

  1. Write a test case returning a Result<...>
  2. Have the test case fail by returning Err(...)
  3. Misread the output!

Possible Solution(s)
I think there are two aspects to this:

First is the panic message from the assert is talking about "internal" details - the exit code of the test. The fact the test (I assume) runs as a process and the exit-code is used to determine failure isn't something I was thinking about while writing/debugging the test.

For this, I think it would help a lot to just simplify the panic message from saying

thread 'exampletest' panicked at 'assertion failed: `(left == right)`
  left: `1`,
 right: `0`: the test returned a termination value with a non-zero status code (1) which indicates a failure', src/libtest/lib.rs:196:5

to something more concise like:

thread 'exampletest' panicked at 'the test exited with non-zero exit code (1) which indicates a failure', src/libtest/lib.rs:196:5

Second part I'm not so clear about, but it seems like the Result isn't being handled specially - the Err is just being turned into an exit code, then asserted later. Since the panic comes from this assertion, the backtrace doesn't reference the actual line which failed.

This is different to if I had, say, used .unwrap() instead of ?:

...
  16: core::result::Result<T,E>::unwrap
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/result.rs:933
  17: confusing::exampletest
             at src/main.rs:7
  18: confusing::exampletest::{{closure}}
             at src/main.rs:6
  19: core::ops::function::FnOnce::call_once
             at /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14/src/libcore/ops/function.rs:227
...

where line 7 is the problem-causing line let _f = std::fs::File::open("/root/nonexistantfile").unwrap(); - it would be nice if using ? resulted in a similar traceback

Notes

Output of cargo version:

cargo 1.40.0 (bc8e4c8be 2019-11-22)
$ rustup show
Default host: x86_64-apple-darwin
rustup home:  /Users/dbr/.rustup

installed toolchains
--------------------

stable-x86_64-apple-darwin
nightly-x86_64-apple-darwin

installed targets for active toolchain
--------------------------------------

arm-unknown-linux-musleabihf
wasm32-unknown-unknown
x86_64-apple-darwin

active toolchain
----------------

stable-x86_64-apple-darwin (default)
rustc 1.40.0 (73528e339 2019-12-16)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-libtestArea: `#[test]` / the `test` libraryC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions