Unit testing in rust

What is test?

Testing is a process by which we assure that the code we have written for our software is working in expected manner. Basically there are two types of test. One is unit test that we going to cover in this blog and another is integration test.

What is unit testing?

It is a testing process where we test the smallest possible part of a software. It usually has one or a few inputs and usually a single output. In procedural programming a unit refers to a individual program, function, procedure etc. For a object oriented programming a unit refers to method belong to super class, abstract class or child class.

How to do it?

Rust looks for all unit tests in the src/ directory. I would suggest maintain this file hierarchy for unit tests. Inside your src directory create a tests directory and then write all tests inside it and don’t forget to import all test in the mod.rs file.

.
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── main.rs
│   └── tests
│       ├── mod.rs
│       └── unit_test.rs

There are some macros we use while testing:

  • assert!(expression) – panic if false.
  • assert_eq!(left, right) and assert_ne!(left, right) – testing left and right expressions for equality and inequality respectively.

Here below an example of unit test in the rust. Inside your src/main.rs

mod tests;

fn main() {
    println!("Hello, world!");
}
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}
pub fn bad_add(a: i32, b: i32) -> i32 {
    a - b
}

Unit test go into the test module with the #[cfg(test)]. Inside your src/tests/unit_test.rs

#[cfg(test)]
mod tests {
    use crate::*;

    #[test]
    fn test_add() {
        assert_eq!(add(1, 2), 3);
    }

    #[test]
    fn test_bad_add() {
        assert_eq!(bad_add(1, 2), 3);
    }
}

Tests can be run with cargo test.

$ cargo test
   Compiling unit_test v0.1.0 (/home/aniruddha/Desktop/Rust lang/unit_test)
    Finished dev [unoptimized + debuginfo] target(s) in 0.30s
     Running target/debug/deps/unit_test-4578ae065cfb1e10

running 2 tests
test tests::unit_test::tests::test_add ... ok
test tests::unit_test::tests::test_bad_add ... FAILED

failures:

---- tests::unit_test::tests::test_bad_add stdout ----
thread 'tests::unit_test::tests::test_bad_add' panicked at 'assertion failed: `(left == right)`
  left: `-1`,
 right: `3`', src/tests/unit_test.rs:12:9
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.


failures:
    tests::unit_test::tests::test_bad_add

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

You can ignore test also. Here below the example –

#[cfg(test)]
mod tests {
    use crate::*;

    #[test]
    #[ignore]
    fn ignored_test() {
        assert_eq!(add(0, 0), 0);
    }
}

Here is the result –

$ cargo test
   Compiling unit_test v0.1.0 (/home/aniruddha/Desktop/Rust lang/unit_test)
    Finished dev [unoptimized + debuginfo] target(s) in 0.35s
     Running target/debug/deps/unit_test-4578ae065cfb1e10

running 1 test
test tests::unit_test::tests::ignored_test ... ignored

test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out

Thank you 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s