Rust testing ecosystem is not huge, but has grown quite well, providing some interesting libraries and solutions.
Rust provides quite good built-in testing capabilities, which are very well described in the following articles:
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.
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:
- Alan Somers: Rust Mock Shootout!
- Oduah Chigozie: Mocking in Rust: Mockall and alternatives
- Official
mockall
crate docs - Official
mockiato
crate docs - Official
unimock
crate docs - Audun Halland: How to write a type-level mock library in Rust
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 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 usinglibFuzzer
.- 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:
- Rust Fuzz Book
- Official
cargo-fuzz
crate docs - Official
honggfuzz
crate docs - Adrian Taylor: Comparative fuzzing parallel Rust tools
- assert_cmd - Easy command initialization and assertions.
- assert_fs - Filesystem fixtures and assertions for testing.
- predicates - Composable first-order predicate functions.
- rexpect - For interactive CLI testing.
- CLI testing
- example with rexpect
- one more example
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.
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?