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