Integration Tests in the tests Folder
Unit tests prove each piece works alone. But does lending, then returning, then lending again work when the pieces are used together, through the same functions another program would call? That is the job of integration tests, and Cargo has a folder waiting for them.
The rule
Unit tests check the parts from inside; integration tests use the public API from outside.
Put integration tests in a tests folder beside src:
shelf/
├── Cargo.toml
├── src/
│ ├── lib.rs # the library: pub struct Library, ...
│ └── main.rs # a thin program that uses the library
└── tests/
├── lending.rs
└── common/
└── mod.rs # shared helpers, not a test file itself// tests/lending.rs
use shelf::Library;
#[test]
fn lend_then_return_then_lend_again() {
let mut lib = Library::new();
lib.add("Iron Tides");
assert!(lib.lend("Iron Tides", 1042).is_ok());
assert!(lib.lend("Iron Tides", 2001).is_err()); // already out
lib.give_back("Iron Tides");
assert!(lib.lend("Iron Tides", 2001).is_ok());
}What makes these different:
- Each file in
tests/is compiled as its own crate that depends on yours. It imports your library by name,use shelf::..., like any outside user. - So it can use only
pubitems. Private helpers are invisible. - No
#[cfg(test)]is needed; Cargo only builds this folder forcargo test. - They need a library crate (
src/lib.rs). A crate with onlysrc/main.rshas nothing to import, so keep logic inlib.rsand letmain.rscall it. - Helpers shared by several test files go in
tests/common/mod.rsand are loaded withmod common;. A plaintests/common.rswould be treated as a test file of its own.
cargo test runs unit tests, then each integration file, then documentation examples. cargo test --test lending runs just one file.
The shortcut
Ask of each thing you want to check: "Could a user of my library call this?" Yes → integration test in tests/. No, it is an internal helper → unit test beside it.
tidy_title (private)
Users cannot call it. Unit test in the same file.
Drills
Answer fast — trust the rule.
How is each file in the tests folder compiled?
Can tests/lending.rs call a private function tidy_title in src/lib.rs?
Where should helpers shared by several integration test files go?
Why is a crate with only src/main.rs hard to integration-test?
Remember
tests/files are separate crates that use only your public API.- "Could a user call this?" Yes → integration test; internal → unit test.
- Keep logic in
lib.rs, shared helpers intests/common/mod.rs.
