Testing
Rust has built-in capabilities to write tests.
Test Functions
A function is a test function when #[test] attribute is applied to it.
#[cfg(test)]mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); }}A function fails when it panics. Otherwise, it passes. Each test is run in a new thread.
Macros and attributes
Some useful testing macros:
#[cfg(test)]- placed on a module. Thanks to it, the test module is compiled only whencargo testis used. It saves time and space when building the code.#[test]- required for a function to be runnable withcargo testassert!(should_be_true)assert_eq!(expected, actual)assert_ne!(something, not_something)#[should_panic]- it accepts an optional string that the panic should be thrown with. This helps to verify that the expected panic was thrown#[ignore]- test will not run. We can still forcecargoto run it usingcargo test -- --ignored. It’ll run only the ignored tests.
Controlling Tests
cargo test parameters
--test-threads=n- allows to specify how many threads run the tests. We could set it to1to disable multithreading.--show-output- by defaultprint!does not show anything for passing tests. This setting changes that- passing single test function name will run just that function
Organization
Unit Tests
Unit tests should be placed in the same file as the code they’re testing. A
separate testing module (with #[cfg(test)]) should be created to include all
the tests.
Integration Tests
Integration tests should be separate from the tested code. There should be a
tests directory next to src. Each file in that directory will become a separate
crate.
These tests will be run with cargo test.