Testing in Rust
# CHAPTER 27
Testing in Rust
1. Chapter Introduction
In many languages, setting up a testing framework (like Jest or JUnit) takes hours of configuration. Rust believes testing is so critical that it built a world-class test runner directly into the language and the Cargo toolchain. You don't need to install *anything* to start testing. In this chapter, we will learn how to write Unit Tests, assert logic, and organize Integration Tests to guarantee our software works flawlessly.2. Learning Objectives
By the end of this chapter, you will be able to:-
Write Unit Tests using the
#[test]attribute.
-
Use
assert!,asserteq!, andassertne!macros.
-
Test for expected Panics using
#[should_panic].
-
Organize tests using the
cfg(test)module.
-
Write Integration Tests in the
tests/directory.
3. Writing Your First Unit Test
Unit tests verify that a small, isolated piece of code (like a single function) works correctly. To mark a function as a test, simply add the#[test] attribute above it.
4. Running Tests
To execute your tests, open your terminal and simply type:Cargo compiles your code in a special test mode, runs all functions marked with #[test], and prints a beautiful green ok or a red FAILED.
5. Assertion Macros
Rust provides three primary macros to verify outcomes:-
1.
assert!(expression): Passes if the boolean expression evaluates totrue.
-
2.
asserteq!(left, right): Passes if both sides are equal. Prints both values if they fail, which makes debugging very easy!
-
3.
assertne!(left, right): Passes if both sides are NOT equal.
6. Testing for Panics
Sometimes, a function *should* crash if given bad data. We can test that a panic correctly occurs using the#[should_panic] attribute.
7. Unit Tests vs. Integration Tests
Unit Tests:- Written in the *same file* as the code they are testing.
-
Wrapped in a
#[cfg(test)]module so they are not compiled into your final production binary.
- Can test private functions.
Integration Tests:
- Verify that different parts of your library work together correctly from the outside.
-
Placed in a separate folder at the root of your project called
tests/.
-
Can ONLY test
pub(public) functions.
Creating an Integration Test:
-
1.
Create a folder
tests/next tosrc/.
-
2.
Create a file
tests/integration_test.rs.
8. Common Mistakes
-
Forgetting
use super::*;: Inside themod testsblock, you must import the functions you want to test from the parent scope. If you don't, the compiler will say the function is not found.
-
Testing Private Functions in
tests/: Integration tests act exactly like external users. If a function is not markedpub, your integration tests cannot see it.
9. Best Practices
-
Test Driven Development (TDD): Rust's incredibly fast test runner makes it perfect for TDD. Write the
#[test]first, watch it fail, then write the code to make it pass.
10. Exercises
-
1.
Write a function
iseven(num: i32) -> bool.
- 2. Create a test module.
-
3.
Write one test
testevenusingassert!(iseven(4)).
-
4.
Write one test
testoddusingasserteq!(iseven(5), false).
-
5.
Run
cargo test.
11. MCQs with Answers
Q1. Do you need to install a third-party crate like Jest or JUnit to test Rust code? a) Yes b) No, a world-class test runner is built into Rust and Cargo natively. Answer: b) No, it is built-in.
What terminal command executes all tests in your project?
What attribute marks a standard function as a test?
What does the asserteq!(a, b) macro do?
Why is asserteq! often preferred over assert!(a == b)?
What does the #[cfg(test)] attribute do?
If a function is supposed to crash (panic) when given invalid input, how do you verify this in a test?
Where do Unit Tests live?
Where do Integration Tests live?
fn without pub)?
a) Yes b) No, they act as external consumers of your library and can only access public APIs.
Answer: b) No, they can only access public APIs.
12. Interview Questions
- Q: Differentiate between Unit Tests and Integration Tests in the Rust ecosystem.
-
Q: Explain how conditional compilation (
#[cfg(test)]) benefits the final production build of a Rust application.