tezvyn:

How does Rust differentiate unit and integration tests?

AI-drafted, machine-checkedSource: doc.rust-lang.orgbeginner

Tests Rust test layout and privacy. Unit tests sit in src/ under #[cfg(test)] and call private functions via super::. Integration tests go in tests/ as external crates. Wrong: claiming it blocks private testing or merging them into src/.

WHAT THIS TESTS: This question checks whether you understand Cargo's test layout conventions and how Rust's module privacy rules apply to test code. It separates candidates who have merely written tests from those who understand why unit and integration tests live in different locations and how visibility interacts with the module tree.

A GOOD ANSWER COVERS: First, location and annotation. Unit tests live in files inside the src directory, conventionally inside a module named tests that is annotated with #[cfg(test)]. This annotation ensures Cargo compiles the test code only when running cargo test, not during cargo build. Second, integration test location. Integration tests live in a top-level tests directory, next to src. Cargo automatically discovers them there and compiles each file as its own separate crate. Third, privacy access. Because unit tests are child modules of the code they test, they can access private functions by bringing parent items into scope with use super::*. Integration tests are external crates, so they are restricted to the public API just like any other consumer. Fourth, the rationale. Unit tests are small and focused, testing one module in isolation and allowing inspection of internal state, while integration tests verify that the public API works correctly from the outside.

COMMON WRONG ANSWERS: A frequent mistake is claiming that Rust forbids testing private functions. In fact, child modules can always access private items in ancestor modules, so a tests module inside src can call private functions freely. Another error is suggesting integration tests should also use #[cfg(test)]; they do not need this because they already live in a separate directory and Cargo handles them differently. Some candidates also confuse the tests directory with the test attribute, or suggest placing integration tests inside src to keep everything in one place.

LIKELY FOLLOW-UPS: An interviewer might ask why integration tests do not need the #[cfg(test)] annotation. The answer is that because they live in the tests directory, Cargo already knows to compile them only during testing and not during cargo build. Another follow-up might ask whether you can test private functions from integration tests; the answer is no, because integration tests are external crates and private items are only visible to child modules within the same crate.

ONE CONCRETE EXAMPLE: Imagine a crate with a public function add_two that calls a private function internal_adder. In src/lib.rs, you create a #[cfg(test)] mod tests block with use super::* and write a unit test that calls internal_adder directly. For integration tests, you create a file in the tests directory and write a test that calls add_two, but any attempt to call internal_adder will fail to compile because the integration test is an external crate and internal_adder is private.

Read the original → doc.rust-lang.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.