Testing
Rust has built-in capabilities to write tests.
Test Functions
A function is a test function when #[test]
attribute is applied to it.
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 test
is used. It saves time and space when building the code.#[test]
- required for a function to be runnable withcargo test
assert!(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 forcecargo
to 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 to1
to 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
.