Testing

Testing in Rust means writing functions marked with the #[test] attribute that use assertion macros to check your code's behaviour, then running them all with cargo test to get a pass/fail report.

Learn Testing in our free Rust course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Rust course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll write tests with assert! , assert_eq! , and assert_ne! , organize them in a #[cfg(test)] mod tests , check for panics with #[should_panic] , and write tests that return Result .

What You'll Learn in This Lesson

1️⃣ #[test] and the assert Macros

Any function tagged #[test] becomes a test. Inside, use assert_eq!(a, b) to require two values are equal, assert_ne!(a, b) to require they differ, and assert!(cond) for any boolean condition (with an optional custom message). A test passes if it returns without panicking.

Each line shows a test name and ok , and the final summary tallies the result. (Tests run in parallel, so the order of the lines can vary between runs.)

2️⃣ #[cfg(test)] mod tests and #[should_panic]

The conventional layout puts tests in a module gated by #[cfg(test)] so they're only compiled when testing, with use super::*; to reach the code under test. To assert that code panics , add #[should_panic] — optionally with expected = "..." to match part of the panic message.

3️⃣ Tests That Return Result

A test may return . Returning Ok(()) passes and returning Err fails — and crucially, this lets you use the ? operator inside the test to unwrap fallible calls cleanly instead of .unwrap() .

Inside parses_valid_port , the ? after parse_port("8080") would turn an error into a test failure automatically. Because the value parsed fine, the test reaches Ok(()) and passes.

Your turn. Fill in the blank marked ___ , then run it.

Write a string-reversing function and three tests for it, then run them. Use cargo test and confirm 3 passed.

📋 Quick Reference — Testing

Practice quiz

Which attribute marks a function as a test?

The #[test] attribute turns a function into a test.

What command runs all tests in a Cargo project?

  • cargo test
  • cargo run
  • cargo check
  • cargo build

Answer: cargo test. cargo test compiles and runs the whole test suite.

What does assert_eq!(a, b) do?

  • Checks a is true
  • Fails if a and b are equal
  • Adds a and b
  • Fails if a and b are not equal

Answer: Fails if a and b are not equal. assert_eq! fails (and prints both values) when a and b differ.

What does assert_ne!(a, b) check?

  • a equals b
  • a and b are NOT equal
  • a is greater than b
  • a is true

Answer: a and b are NOT equal. assert_ne! fails if the two values are equal.

What does assert! take?

  • A single boolean expression
  • Two values
  • A Result
  • A panic

Answer: A single boolean expression. assert! takes one boolean and fails if it is false.

What does #[should_panic] do?

  • Skips the test
  • Fails on panic
  • Passes only if the test body panics
  • Ignores panics

Answer: Passes only if the test body panics. A #[should_panic] test passes only when its body panics.

What does #[cfg(test)] on a module do?

  • Runs it first
  • Compiles it only when building for tests
  • Makes it public
  • Disables it

Answer: Compiles it only when building for tests. #[cfg(test)] compiles the module only during testing, keeping it out of release builds.

Why write use super::*; inside a test module?

  • To import std
  • To enable panics
  • To run faster
  • To bring the parent module's items into scope

Answer: To bring the parent module's items into scope. use super::*; lets the tests call the functions being tested.

What return type lets a test use the ? operator?

  • ()
  • Result<(), E>
  • bool
  • Option<()>

Answer: Result<(), E>. A test returning Result<(), E> can use ?, returning Ok(()) to pass.

Why prefer assert_eq! over assert!(a == b)?

  • It is shorter
  • It is faster
  • On failure it prints both values for easier debugging
  • It never fails

Answer: On failure it prints both values for easier debugging. assert_eq! prints the left and right values when it fails.