Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Testing  ›  Lesson

Integration Tests in the tests Folder

Unit & Integration Testing 12 minIntegration tests live in the tests folder, each file is compiled as a separate crate, and they can only use the library's public API, just as a real user would.

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 pub items. Private helpers are invisible.
  • No #[cfg(test)] is needed; Cargo only builds this folder for cargo test.
  • They need a library crate (src/lib.rs). A crate with only src/main.rs has nothing to import, so keep logic in lib.rs and let main.rs call it.
  • Helpers shared by several test files go in tests/common/mod.rs and are loaded with mod common;. A plain tests/common.rs would 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.

Sorting the library's testsStep 1 of 4
  1. tidy_title (private)

    Users cannot call it. Unit test in the same file.

Drills

Answer fast — trust the rule.

quick drill

How is each file in the tests folder compiled?

quick drill

Can tests/lending.rs call a private function tidy_title in src/lib.rs?

quick drill

Where should helpers shared by several integration test files go?

quick drill

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 in tests/common/mod.rs.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainUnit or integration?

The library crate has a private helper tidy_title and a public Library::lend that uses it. Explain where you would test each, why an integration test cannot call tidy_title, and why a crate with only src/main.rs is awkward to integration-test.