The tests Directory
We create a tests
directory at the top level of our project directory, next to src
. Cargo knows to look for integration test files in this directory. We can then make as many test files as we want, and Cargo will compile each of the files as an individual crate.
Let's create an integration test. With the code in Listing 11-12 still in the src/lib.rs
file, make a tests
directory, and create a new file named _tests/integrationtest.rs
. Your directory structure should look like this:
adder
├── Cargo.lock
├── Cargo.toml
├── src
│ └── lib.rs
└── tests
└── integration_test.rs
Enter the code in Listing 11-13 into the _tests/integrationtest.rs
file.
Filename: tests/integration_test.rs
use adder;
#[test]
fn it_adds_two() {
assert_eq!(4, adder::add_two(2));
}
Listing 11-13: An integration test of a function in the adder
crate
Each file in the tests
directory is a separate crate, so we need to bring our library into each test crate's scope. For that reason we add use adder;
at the top of the code, which we didn't need in the unit tests.
We don't need to annotate any code in _tests/integrationtest.rs
with #[cfg(test)]
. Cargo treats the tests
directory specially and compiles files in this directory only when we run cargo test
. Run cargo test
now:
$ cargo test
Compiling adder v0.1.0 (file:///projects/adder)
Finished test [unoptimized + debuginfo] target(s) in 1.31s
Running unittests src/lib.rs (target/debug/deps/adder-
1082c4b063a8fbe6)
1 running 1 test
test tests::internal ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0
filtered out; finished in 0.00s
2 Running tests/integration_test.rs
(target/debug/deps/integration_test-1082c4b063a8fbe6)
running 1 test
3 test it_adds_two ... ok
4 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0
filtered out; finished in 0.00s
Doc-tests adder
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0
filtered out; finished in 0.00s
The three sections of output include the unit tests, the integration test, and the doc tests. Note that if any test in a section fails, the following sections will not be run. For example, if a unit test fails, there won't be any output for integration and doc tests because those tests will only be run if all unit tests are passing.
The first section for the unit tests [1] is the same as we've been seeing: one line for each unit test (one named internal
that we added in Listing 11-12) and then a summary line for the unit tests.
The integration tests section starts with the line Running tests/integration_test.rs
[2]. Next, there is a line for each test function in that integration test [3] and a summary line for the results of the integration test [4] just before the Doc-tests adder
section starts.
Each integration test file has its own section, so if we add more files in the tests
directory, there will be more integration test sections.
We can still run a particular integration test function by specifying the test function's name as an argument to cargo test
. To run all the tests in a particular integration test file, use the --test
argument of cargo test
followed by the name of the file:
$ cargo test --test integration_test
Finished test [unoptimized + debuginfo] target(s) in 0.64s
Running tests/integration_test.rs
(target/debug/deps/integration_test-82e7799c1bc62298)
running 1 test
test it_adds_two ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0
filtered out; finished in 0.00s
This command runs only the tests in the _tests/integrationtest.rs
file.