How Tests Are Collected
Snforge executes tests, but it does not compile them directly.
Instead, it compiles tests by internally running scarb build --test
command.
The snforge_scarb_plugin
dependency, which is included with snforge_std
dependency makes all functions
marked with #[test]
executable and indicates to Scarb they should be compiled.
Without the plugin, no snforge tests can be compiled, that's why snforge_std
dependency is always required in all
snforge projects.
Thanks to that, Scarb collects all functions marked with #[test]
from valid locations and compiles
them into tests that are executed by snforge.
[[test]]
Target
Under the hood, Scarb utilizes the [[test]]
target mechanism to compile the tests. More information about the
[[test]]
target is available in
the Scarb documentation.
By default, [[test]]]
target is implicitly configured and user does not have to define it.
See Scarb documentation
for more details about the mechanism.
Tests Organization
Test can be placed in both src
and test
directories. When adding tests to files in src
you must wrap them in tests
module.
You can read more about tests organization in Scarb documentation.
Unit Tests
Test placed in src
directory are often called unit tests.
For these test to function in snforge, they must be wrapped in a module marked with #[cfg(test)]
attribute.
// src/example.rs
// ...
// This test is not in module marked with `#[cfg(test)]` so it won't work
#[test]
fn my_invalid_test() {
// ...
}
#[cfg(test)]
mod tests {
// This test is in module marked with `#[cfg(test)]` so it will work
#[test]
fn my_test() {
// ..
}
}
Integration Tests
Integration tests are placed in tests
directory.
This directory is a special directory in Scarb.
Tests do not have to be wrapped in #[cfg(test)]
and each file is treated as a separate module.
// tests/example.rs
// ...
// This test is in `tests` directory
// so it works without being in module with `#[cfg(test)]`
#[test]
fn my_test_1() {
// ..
}
Modules and lib.cairo
As written above, each file in tests
directory is treated as a separate module
$ tree
Output:
tests/
├── module1.cairo <-- is collected
├── module2.cairo <-- is collected
└── module3.cairo <-- is collected
Scarb will collect each file and compile it as a
separate test target.
Each of these targets will be run separately by snforge
.
However, it is also possible to define lib.cairo
file in tests
.
This stops files in tests
from being treated as separate modules.
Instead, Scarb will only create a single test target for that lib.cairo
file.
Only tests that are reachable from this file will be collected and compiled.
$ tree
Output:
tests/
├── lib.cairo
├── module1.cairo <-- is collected
├── module2.cairo <-- is collected
└── module3.cairo <-- is not collected
// tests/lib.cairo
mod module1;
mod module2;