Testing and Documentation
Write unit tests, integration tests, and generate documentation for your Rust projects.
Rust Testing with Cargo
Introduction to Testing in Rust
Rust provides robust testing capabilities integrated directly into the Cargo build system. This allows developers to easily write and run tests to ensure code quality, correctness, and stability.
Using `cargo test`
The core command for running tests in Rust is cargo test
. This command compiles your tests and executes them, providing a summary of the results.
Detailed Explanation of `cargo test`
Basic Usage
Simply running cargo test
in the root directory of your Rust project will automatically discover and run all tests defined in your project's source code and in the tests/
directory.
Test Discovery
Cargo automatically discovers tests in the following locations:
- Functions annotated with the
#[test]
attribute within your source code (src/lib.rs
,src/main.rs
, etc.). These are typically unit tests. - Modules annotated with the
#[cfg(test)]
attribute containing functions with the#[test]
attribute. - Files located in the
tests/
directory of your project. These are integration tests. Each file intests/
is treated as a separate crate. - Files located in the
benches/
directory of your project. These are benchmarks, which are run separately.
Filtering Tests
You can filter which tests are run by providing a filter string to cargo test
. This filter matches against the name of the test function or module.
cargo test my_module
This command will only run tests whose names contain "my_module". This can include a module name like `my_module::my_test` or a test function named `my_module`.
Regular expressions can also be used for more sophisticated filtering. To enable regex filtering, use the --features regex
flag when compiling your tests, and then pass a regular expression to cargo test
.
cargo test --features regex ".*important.*"
Running Specific Tests
You can run a specific test function by providing its full path (module path followed by function name) to cargo test
.
cargo test my_module::my_test
Running Ignored Tests
Tests annotated with #[ignore]
are skipped by default. You can run these tests using the --ignored
flag.
cargo test --ignored
You can also run only ignored tests with --include-ignored
:
cargo test --include-ignored
Running Tests in Release Mode
By default, cargo test
compiles your tests in debug mode. To run tests in release mode, use the --release
flag. This allows you to test performance-critical code with optimizations enabled.
cargo test --release
Running Tests in Parallel
Cargo automatically runs tests in parallel. You can control the number of threads used with the --test-threads
flag. Setting this to 1 will run tests serially.
cargo test --test-threads 4
Running Documentation Tests
Rust supports documentation tests, which are code examples embedded in your documentation that are automatically tested. These tests can be run with cargo test
and are included by default. You can disable them with --no-run
if you only want to compile the documentation but not run the examples.
Running Benchmarks
Rust supports benchmarking code using the test
crate. To define a benchmark, use the #[bench]
attribute. Benchmarks are located in the benches/
directory.
To run benchmarks, use the following command:
cargo bench
Benchmarks are run in release mode by default to provide accurate performance measurements. They also require the nightly toolchain.
Understanding Test Output
The output of cargo test
provides information about the test results.
Key information in the output includes:
- Running n tests: Indicates the number of tests being executed.
- test test_name ... result: Shows the name of each test and its result (
ok
,failed
,ignored
). - failures: A section listing the specific tests that failed and the corresponding error messages.
- stdout: The standard output of the test functions, which can be useful for debugging.
- stderr: The standard error output of the test functions.
- test result: A summary of the test run, including the number of tests run, the number of tests that passed, failed, ignored, and measured.
For failed tests, the output will typically include a detailed error message indicating the cause of the failure. This often includes a stack trace, helping you pinpoint the location of the error in your code.
When running tests in parallel, the output may be interleaved. Cargo attempts to group the output of each test together to improve readability.
You can customize the verbosity of the output using the -v
(verbose) or -q
(quiet) flags.