I have a number of methods in a mod
. These methods need to be tested but they're private. I currently have the unit tests inside the same mod
, but I'm not sure this is the right way to go about it, as I'm mixing two different things.
Should I put my unit tests in a different file? If so, how do I test private methods?
At its simplest, a test in Rust is a function that's annotated with the test attribute. Attributes are metadata about pieces of Rust code; one example is the derive attribute we used with structs in Chapter 5. To change a function into a test function, add #[test] on the line before fn .
The general rule for unit tests is to test the smallest possible piece that you can test. A good rule is that each test should exercise exactly a single method from a public API. That means it should only execute this method and no other, not even transiently.
Unit tests should validate all of the details, the corner cases and boundary conditions, etc. Component, integration, UI, and functional tests should be used more sparingly, to validate the behavior of the APIs or application as a whole.
Most of the time, you'll make a separate test directory. But Rust encourages you to write unit tests in the same file as the function definition. We do this by having a section at the bottom of our file specifically for tests.
Our algorithm is simple enough. But how do we know it works? The obvious answer is to write some unit tests for it. Rust is actually a bit different from Haskell and most other languages in the canonical approach to unit tests. Most of the time, you'll make a separate test directory.
But just to give you an idea, tests in Rust are written inside the tests module (the mod tests part says it's the tests module), and anything written inside this module tells cargo to run them only during testing (and that's essentially what the # [cfg (test)] attribute implies). A test in Rust is essentially just a function annotated as a test.
The first one, called compiletest, is part of the testing infrastructure of the Rust compiler and maintained by the Rust developers. With UI testing, you simply write a Rust program that should fail to compile, and compiletest runs the compiler, writing the error output into a .stderr file per test file. If the error output changes, the test fails.
It's recommended to place tests in their own module. This module should be a child of the module whose code you want to test (and it can be defined in the same or different file).
#[cfg(test)] mod tests { #[test] fn test_some_stuff() { // ... test code ... } }
Private methods are not private to child modules, but you still need to import them with use super::some_name;
.
By the way, this is all explained in the test organization section (11.3) of the Rust Book.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With