Smart Contracts Unit Testing

Unit tests are useful to check for code integrity, and detect basic errors on isolated methods. However, since unit tests do not run on a blockchain, there are many things which they cannot detect. Unit tests are not suitable for:

  • Testing gas and storage usage
  • Testing transfers
  • Testing cross-contract calls
  • Testing complex interactions, i.e. multiple users depositing money on the contract

You can also check official NEAR Unit test documentation for more details

For all these cases it is necessary to complement unit tests with integration tests.

If you want to execute all of your unit tests you can run them with:

cargo test

Or if you prefer to execute just 1 test you can do it using the following command:

cargo test --lib -- <module-name>::<test-name> --exact --show-output

Replacing <module-name> and <test-name> with the corresponding values.

For example, based on the Hello Contract example, these are the tests available:

#![allow(unused)]
fn main() {
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn get_default_greeting() {
        let contract = Contract::default();
        // this test did not call set_greeting so should return the default "Hello" greeting
        assert_eq!(contract.get_greeting(), "Hello");
    }

    #[test]
    fn set_then_get_greeting() {
        let mut contract = Contract::default();
        contract.set_greeting("howdy".to_string());
        assert_eq!(contract.get_greeting(), "howdy");
    }
}
}

The tests module is called tests and you can choose to execute any of get_default_greeting or set_then_get_greeting test.

Run only get_default_greeting test:

cargo test --lib -- tests::get_default_greeting --exact --show-output

Output:

    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.57s
     Running unittests src/lib.rs (target/debug/deps/near_smart_contract-fdb69a096598ebaf)

running 1 test
test tests::get_default_greeting ... ok

successes:

successes:
    tests::get_default_greeting

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

Run only set_then_get_greeting test:

cargo test --lib -- tests::set_then_get_greeting --exact --show-output

Output:

    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.19s
     Running unittests src/lib.rs (target/debug/deps/near_smart_contract-fdb69a096598ebaf)

running 1 test
test tests::set_then_get_greeting ... ok

successes:

---- tests::set_then_get_greeting stdout ----
Saving greeting: howdy


successes:
    tests::set_then_get_greeting

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