Ignoring tests

Sometimes, we have tests that take a lot of time, or we want to avoid running a specific test all the time. To avoid running a test by default, we can add the #[ignore] attribute above the function:

    #[ignore]
    #[test]
    fn test_dummy() {
        assert!(false, "Always fail");
    }

When we run the test, we'll see that the test function was not running:

    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running target/debug/deps/ftp_server-452667ddc2d724e8

running 2 tests
test codec::tests::test_dummy ... ignored
test codec::tests::test_encoder ... ok

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

As you can see, the test_dummy() test function was ignored. To run it, we need to specify a command-line argument to the program running the tests (not to cargo itself):

cargo test -- --ignored

Note: We specified -- before --ignored to send the latter to the program running the tests (which is not cargo).

With that argument, we see that the test indeed runs:

    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running target/debug/deps/ftp_server-452667ddc2d724e8

running 1 test
test codec::tests::test_dummy ... FAILED

failures:

---- codec::tests::test_dummy stdout ----
    thread 'codec::tests::test_dummy' panicked at 'Always fail', src/codec.rs:102:8
note: Run with `RUST_BACKTRACE=1` for a backtrace.


failures:
    codec::tests::test_dummy

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

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

To end this section, let's write a unit test for the decoder:

#[cfg(test)]
mod tests {
    // …

    #[test]
    fn test_decoder() {
        let mut codec = FtpCodec;
        let mut buf = BytesMut::new();
        buf.extend(b"PWD");
        let result = codec.decode(&mut buf);
        assert!(result.is_ok());
        let command = result.unwrap();
        assert!(command.is_none());

Here, we test that None is returned in the case when more input is needed:

        buf.extend(b"\r\n");
        let result = codec.decode(&mut buf);
        assert!(result.is_ok());
        let command = result.unwrap();
        assert_eq!(command, Some(Command::Pwd));

And here, we add the missing output to check that the command was parsed correctly:

        let mut buf = BytesMut::new();
        buf.extend(b"LIST /tmp\r\n");
        let result = codec.decode(&mut buf);
        assert!(result.is_ok());
        let command = result.unwrap();
        assert_eq!(command, Some(Command::List(Some(PathBuf::from("/tmp")))));
    }
}

Finally, we test that parsing a command with an argument works. If we run cargo test again, we get the following output:

    Finished dev [unoptimized + debuginfo] target(s) in 1.70 secs
     Running target/debug/deps/ftp_server-452667ddc2d724e8

running 2 tests
test codec::tests::test_encoder ... ok
test codec::tests::test_decoder ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out