Test Cases in Rust are simple to write

Reading Time: 4 minutes

Rust has been the most loved programming language for the last five years in a row. Rust is a low-level statically-typed multi-paradigm programming language that’s focused on safety and performance.

Rust solves problems that C/C++ has been struggling with for a long time, such as memory errors and building concurrent programs. Due to the borrow checker, Rust can prevent data races at compile-time. Data races occur when two threads access the same memory at the same time, and they can lead to unpredictable behaviour. Thankfully, preventing undefined behaviour is all that Rust is about. Rust also allows you to write test cases that would check your code for correct behaviour.

Tests are the code that is written with the intention to test whether the non-test code is working fine or not. Testing includes the following major processes.

  1. Set up any needed data or state.
  2. Run the code you want to test.
  3. Assert the results are what you expect.

Now let us look more about tests in Rust.

Test automation tools: 8 trends and techniques to watch | TechBeacon

Test Functions

A Test function in Rust is a function annotated by the test attribute. Attributes are the things we write in square brackets after a # symbol. They tell some important things about the code followed by them. We have use #[derive] before structures. So to make a function a test case, we write #[test] before the function.

For example-

fn code_success(){

The above function represents a test case in Rust. We can write as many test cases in Rust by following the same approach of writing the test functions.

To test the code or in other words, to run the test cases, we need to run a command.

cargo test

This command uses the test case written by us and executes them, resulting in a detailed report of passing and failing test cases.

Creating Test File

Now, we will be building a demo project to show how can we write test cases in a Rust project. First of all, we will be creating a new Rust library project. To create a library project we run the following command-

cargo new demo --lib

This command will create a brand new library project for us. In this project, we will see an src folder. Open the src folder and open the lib.rs file in this.

We will write the code that we want to test. Let us make a program to check if a given number is even or not.

Write the following code in the lib.rs file.

fn is_even(num:i32) -> bool {
    if num % 2 == 0{
    else { false }

This function takes an i32 parameter and checks whether the number is even or not. It returns a bool value as a result.

Now, we will create a test.rs file in the src folder that will contain our test cases. Create a Rust file inside the src folder and copy the following code in that file.

use crate::is_even;

fn check_even_success(){

fn check_even_failure(){

The above code uses the test attribute to create two test functions by the name check_even_success and check_even_failure. These two functions use assert! and assert_eq! macros to decide how to handle the test cases. assert! macro passes the test cases if a true value is passed to it. Similarly, assert_eq! macro compares the two given values and passes the test cases if they are equal.

Now, To test the code, we include this test.rs module in our lib.rs file by adding the following line at the top of lib.rs file.

mod test;

This will attach the test.rs file to the lib.rs file.

Test the code

Now, we are good to go. Open the terminal in the root folder of the project and run the cargo test command to test the code we have written.

We see the following output.

   Compiling demo v0.1.0 (/home/knoldus/demo)
    Finished test [unoptimized + debuginfo] target(s) in 0.24s
     Running unittests (target/debug/deps/demo-3865032985419301)

running 2 tests
test test::check_even_success ... ok
test test::check_even_failure ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests demo

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

This tells us that our code was correct and all the test cases passed successfully.

If you want to read more content like this?  Subscribe to Rust Times Newsletter and receive insights and latest updates, bi-weekly, straight into your inbox. Subscribe to Rust Times Newsletter: https://bit.ly/2Vdlld7.

Test cases