If you find this helpful, please like, bookmark, and follow. To keep learning along, follow this series.
11.9.1 Test Categories
Rust divides tests into two categories: unit tests and integration tests.
- Unit tests are smaller and more focused. Each one tests a single module in isolation, and they can also test private interfaces.
- Integration tests live completely outside the codebase. They use your code the same way external code does. Integration tests can only access public interfaces, and each test may use multiple modules.
11.9.2 The #[cfg(test)] Annotation
The purpose of unit tests is to isolate a small piece of code so we can quickly determine whether it behaves as expected. We usually keep unit tests and the code under test in the same file under src.
By convention, each source file should also have a test module to hold these functions, and #[cfg(test)] is used to annotate the test module. Code marked with this annotation is compiled and run only when cargo test is executed; it is not compiled when you run cargo build.
Those are the rules for unit tests. Integration tests live in a different directory, so they do not need the #[cfg(test)] annotation.
cfg in #[cfg(test)] is short for configuration. Using it tells Rust that the annotated item is included only under the specified configuration option.
For example:
pub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
The configuration option in #[cfg(test)] is test. This configuration option is provided by Rust for compiling and running tests, and items under #[cfg(test)] are compiled and run only when you execute cargo test.
11.9.3 Testing Private Functions
Rust allows you to test private functions, which is not always the case in other languages.
For example:
pub fn add_two(a: usize) -> usize {
internal_adder(a, 2)
}
fn internal_adder(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn internal() {
let result = internal_adder(2, 2);
assert_eq!(result, 4);
}
}
Even though internal_adder is not declared public with pub, it can still be called inside the test module.
Top comments (0)