Test Organization
Test Types
- The Rust community thinks about tests in terms of two main categories Unit Tests and Integration tests.
Unit Tests | Integration tests |
---|---|
Small and Focused | Large and Broad |
Internal | External |
Tests One Module | Tests Multiple Modules |
Can Test Private Interfaces | Only Tests Public Interfaces |
Testing Internally such that external code may not possibly do | Testing like some external code would do |
Lives inside src directory inside each module | Lives in tests directory right outside src directory |
Module named tests inside each module with #[cfg(test)] | Different files inside tests directory without #[cfg(test)] |
Unit Tests
-
This annotation
#[cfg(test)]
tells Rust to only run this module oncargo test
, not when you runcargo build
. -
Thus, the functions following this annotation are never part of compiled result, hereby saving some space.
-
Only used for unit tests, since integration tests are different directory they don't need to use it.
-
An example worth noting:
Integration tests
-
For integration test, we create a new directory
target
beside thesrc
directory. -
Each file in the tests directory is compiled as its own separate crate.
-
Treating each integration test file as its own crate is useful to create separate scopes that are more like the way end users will be using your crate.
-
However, this means files in the tests directory don’t share the same behavior as files in src do.
-
The file structure of integration tests are:
-
The helper functions lives inside file
tests/common/mod.rs
. -
This is a naming convention that rust uses to prevent functions inside this file not to appear in output logs of tests.
-
Files in subdirectories of the tests directory don’t get compiled as separate crates or have sections in the test output.
-
It looks something like this:
-
The
integration_test.rs
looks similar to this: -
To run all the tests in a particular integration test file, use:
cargo test --test <integration-test-filename>
-
We can't write integration tests for binary crates, the rust projects that only contains a
src/main.rs
file and doesn’t have asrc/lib.rs
file. -
The reason is that we cannot bring functions defined in the
src/main.rs
file into scope of files intests
directory with a use statement. -
Only library crates expose functions that other crates can use; binary crates are meant to be run on their own.
-
Though, if a project contains both
src/lib.rs
andsr/main.rs
, we can write integration tests for the important functionality insidesrc/lib.rs
using theuse
keyword. -
If the important functionality works, the small amount of code in the
src/main.rs
file will work as well, and that small amount of code doesn’t need to be tested.
Doc Tests
-
You can write doc tests above the item, using the
Examples
with the docs comment///
like this: -
Running
cargo test
will run the code examples in your documentation as tests! In case we change the function, the test will panic, and we'll require to update the docs to make it work.Doc-tests my_crate running 1 test test src/lib.rs - add_one (line 5) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.27s
Tests Output Log
- The output logs section has three parts:
- Unit Tests
- Integration Tests
- Doc Tests