Skip to content

Latest commit

 

History

History
 
 

3_1_testing

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

Task 3.1: Testing and mocking

Rust testing ecosystem is not huge, but has grown quite well, providing some interesting libraries and solutions.

Built-in testing capabilities

Rust provides quite good built-in testing capabilities, which are very well described in the following articles:

BDD style

BDD (behavior-driven development) testing style implies that test cases represent a program specification, while tests themselves prove the specification correctness.

While Rust ecosystem has some BDD testing style crates (the most mature one is cucumber crate), it's not a requirement to use them to follow the BDD style (as they may be too complex for some trivial cases, like unit testing). There is nothing preventing you from following BDD style in usual Rust tests. So, instead of:

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_hash() {
        let h = hash("some_string");
        
        assert_eq!(h.len(), 64);
        assert!(!h.contains("z"));
    }
}

You're always free to write it more meaningfully:

#[cfg(test)]
mod hash_spec {
    use super::*;
    
    #[test]
    fn has_64_symbols_len() {
        assert_eq!(hash("some_string").len(), 64);
    }
    
    #[test]
    fn contains_hex_chars_only() {
        assert!(!hash("some_string").contains("z"));
    }
}

This makes tests more granular (and so, more meaningful test failures) and testing intentions become more understandable for readers.

Mocking

Rust ecosystem has enough solutions for mocking, some of them are quite mature.

The most interested one is mockiato crate at the moment, as is quite ergonomic in use and supports stable Rust. unimock crate works in the very similar way, but supports supertraits, as uses the single Unimock type for mocking. faux and mry crates are focused on struct mocking (instead of traits).

Additionally, mockito and wiremock crates should be mentioned as a quite useful one for HTTP testing.

The most powerful, however, is mockall crate. See this overview for more details.

For better overview and familiarity with mocking in Rust, read through the following articles:

Property testing

Property testing is another testing paradigm for considering. In a nutshell, it can be explained in the following way:

Property testing is a system of testing code by checking that certain properties of its output or behaviour are fulfilled for all inputs. These inputs are generated automatically, and, critically, when a failing input is found, the input is automatically reduced to a minimal test case.

Rust ecosystem has quite good proptest and quickcheck crates, which provide tools and primitives for property testing.

For better understanding and familiarity with property testing in Rust, read through the following articles:

Fuzzing

Fuzzing is another testing technique, which involves providing invalid, unexpected, or random data as inputs to a computer program. It really helps to spot program crashes and memory leaks in edge cases.

Rust ecosystem has several tools for fuzzing at the moment. Most known are:

  • cargo-fuzz is a command-line wrapper for using libFuzzer.
  • afl.rs allows to run AFL (american fuzzy lop) on code written in Rust.
  • honggfuzz is a security oriented fuzzer with powerful analysis options, which supports evolutionary, feedback-driven fuzzing based on code coverage (software- and hardware-based).

For better understanding and familiarity with fuzzing in Rust, read through the following articles:

More reading

Integrated tests

CLI Testing

Task

Estimated time: 1 day

For the implementation of a small guessing game in this task's crate provide all possible tests you're able to write.

Questions

After completing everything above, you should be able to answer (and understand why) the following questions:

  • What is TDD style? What is BDD style? Where is the essential accent of BDD?
  • What is mocking? When is it useful?
  • What is property-based testing? How does it achieve its goals?
  • What is fuzzing? How does it differ from property testing?