DEV Community

Cover image for How to Write Tests in Rust
Francesco Ciulla
Francesco Ciulla

Posted on

How to Write Tests in Rust

Testing is an essential part of software development, especially when coding professionally and improving your code's quality.

In Rust, testing is built into the language, making writing and running tests straightforward.

This article will introduce you to the basics of testing in Rust with practical examples.

If you prefer a video version

Create the lib project

In this case, we will create a library project using the following command:

cargo new adder --lib
Enter fullscreen mode Exit fullscreen mode

Remember to use the --bin flag to create a binary project.

To run the tests, you can use the following command:

cargo test
Enter fullscreen mode Exit fullscreen mode

This command will compile the code and run the tests.

Now let's create a simple function to test.

Basic Test Function

Let's start with a simple test function. In Rust, test functions are annotated with #[test].

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the #[cfg(test)] attribute ensures that the test module is only compiled when running tests. The #[test] attribute marks the function as a test.

The assert_eq! macro checks if the two arguments are equal. If they are not, the test will fail.

The output of the test will look like this:

running 1 test
test tests::it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Enter fullscreen mode Exit fullscreen mode

Making a Test That Fails

It's often useful to see what happens when a test fails.

Here's an example:

#[cfg(test)]
mod tests {
    #[test]
    fn it_fails() {
        assert_eq!(2 + 2, 5);
    }
}
Enter fullscreen mode Exit fullscreen mode

When you run this test, it will fail, and you'll see an error message like this:

---- it_fails stdout ----
thread 'tests::it_fails' panicked at 'assertion failed: `(left == right)`
  left: `4`,
 right: `5`', src/lib.rs:4:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Enter fullscreen mode Exit fullscreen mode

Using the assert! Macro

The assert! macro is used to check boolean expressions. If the expression evaluates to false, the test will fail.

#[cfg(test)]
mod tests {
    #[test]
    fn check_true() {
        assert!(true);
    }
}
Enter fullscreen mode Exit fullscreen mode

Testing Equality with assert_eq! and assert_ne!

The assert_eq! macro checks if two values are equal, while assert_ne! checks if they are not.

#[cfg(test)]
mod tests {
    #[test]
    fn test_equality() {
        assert_eq!(3 * 3, 9);
        assert_ne!(3 * 3, 8);
    }
}
Enter fullscreen mode Exit fullscreen mode

Adding Custom Failure Messages

You can add custom failure messages to your tests using the assert! macro.

#[cfg(test)]
mod tests {
    #[test]
    fn custom_message() {
        assert_eq!(2 + 2, 5, "Math is broken!");
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the test will fail with the message "Math is broken!".

The output will look like this:

---- custom_message stdout ----
thread 'tests::custom_message' panicked at 'assertion failed: `(left == right)`
  left: `4`,
 right: `5`: Math is broken!', src/lib.rs:4:9
Enter fullscreen mode Exit fullscreen mode

Checking for Panics with should_panic

You can test if a function panics using the should_panic attribute.

#[cfg(test)]
mod tests {
    #[test]
    #[should_panic]
    fn it_panics() {
        panic!("This test will panic");
    }
}
Enter fullscreen mode Exit fullscreen mode

Using Result in Tests

Test functions can return Result<(), E> to use the ? operator for error handling.

#[cfg(test)]
mod tests {
    #[test]
    fn test_with_result() -> Result<(), String> {
        if 2 + 2 == 4 {
            Ok(())
        } else {
            Err("Math is broken".into())
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Rust makes testing easy and powerful with its built-in features.

By using attributes like #[test], assert!, assert_eq!, and should_panic, you can write robust tests for your code.

If you prefer a video version

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.