User (Un)friendliness Again

I have come back to Rust after a long break. This time I tried to use unit testing as recommended, via cargo test.

I had to spend way too much time overcoming unexpected barriers put in my way at every step, like the program output being turned off (I mean, who would expect that?) and the backtrace not working without learning about, and setting, an obscure environment variable. I mean, really?? I think you could do a lot better than this in your drive for user friendliness.

Frankly, it is a lot more effective for me to debug manually with a few judicious print statements than having to cope with all this bull.

1 Like

Agreed, Cargo is a bit extreme with its preference for "clean" output.

This may be helpful to you:

cargo test -- --nocapture
4 Likes

It is pretty common, not only in Rust, for test runners to capture output, so that you can at all times feed information to stdout that is then immediately shown in case a test breaks.

And RUST_BACKTRACE is literally advertised in the panic message when running without it. That's not very obscure.

7 Likes

This bugs me too. I'd like a persistable (e.g. in git) Cargo config option to (at e.g. the crate level, or even globally on a host) consistently turn on prints/logs written to stdout and stderr i.e. without filthy print-then-panic hacks.
The cargo test -- --nocapture command works but is onerous to remember and use each time.
I really mean it: I keep forgetting 1. that the command exists and 2. what in tarnation it actually is.

This is a little different, the reason for this I think is that backtraces are meant explicitly as a development tool i.e. not something a regular user should be exposed to. But this behavior is definitely different than you're probably used to coming from e.g. C/C++.

On a minor side note: I think it's really cool to see Rust being picked up by retirees (ok, retiree at this point) :slight_smile:

3 Likes

Off topic: I suspect that many of us are retirees. I retired in 2007, after 50 years programming and designing computers.

5 Likes

Pro tip: Add export RUST_TEST_NOCAPTURE=1 to your shell profile to disable stdout capturing by default. You can unset the variable if you ever want to re-enable the default behavior. The environment variable is documented in the book and the rustc manpage.

3 Likes

Correct me if i'm wrong, but doesn't rust only capture output when tests pass?

Technically it always captures stdout. But it will print what was captured when a test fails.

fn add(a: i32, b: i32) -> i32 {
    println!("to stdout: {} + {}", a, b);
    eprintln!("to stderr: {} + {}", a, b);
    a + b
}

fn main() {
    println!("Hello, world! {}", add(2, 2));
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        assert_eq!(add(2, 2), 4);
    }

    #[test]
    fn bad_assertion() {
        assert_eq!(add(3, 4), 5);
    }
}
$ cargo test
   Compiling test-test v0.1.0 (~/Desktop/test-test)
    Finished dev [unoptimized + debuginfo] target(s) in 0.50s
     Running target/debug/deps/test_test-cababb7820a3e03f

running 2 tests
test tests::it_works ... ok
test tests::bad_assertion ... FAILED

failures:

---- tests::bad_assertion stdout ----
to stdout: 3 + 4
to stderr: 3 + 4
thread 'tests::bad_assertion' panicked at 'assertion failed: `(left == right)`
  left: `7`,
 right: `5`', src/main.rs:22:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.


failures:
    tests::bad_assertion

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

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