Runtime detection of tests
There's no global variable that is set when running tests. You could add one, but it's pretty complicated to get it right. This example does not get it completely right:
use std::cell::Cell;
thread_local! {
pub static IS_TESTING: Cell<bool> = Cell::new(false);
}
fn my_code() -> u8 {
if IS_TESTING.with(|t| t.get()) {
0
} else {
42
}
}
#[test]
fn one() {
IS_TESTING.with(|t| t.set(true));
assert_eq!(0, my_code());
IS_TESTING.with(|t| t.set(false));
}
To do this correctly, you need to handle a few things:
- Tests are run in a multithreaded environment, so you need to make sure that you handle that.
- Using a thread-local is probably incorrect if your code spawns new threads, as the variable won't carry over to them.
- You need to make sure to set the flag back to false even when the test aborts early due to an assertion failure.
Compile time detection of tests
More likely, what you want is to detect if you are compiling for tests. This is much simpler and you are probably already using the same technique to conditionally compile your tests themselves:
fn my_code() -> u8 {
if cfg!(test) {
0
} else {
42
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn one() {
assert_eq!(0, my_code());
}
}
Dependency injection is better
Editorially, runtime or compile time detection is a bad idea from the perspective of code quality. Instead of littering your code with boatloads of conditional checks that will complicate and perhaps even slow down your code, introduce dependency injection:
trait ValueSource {
fn value(&self) -> u8;
}
struct ProductionSource;
impl ValueSource for ProductionSource {
fn value(&self) -> u8 {
42
}
}
fn my_code<S>(source: S) -> u8
where
S: ValueSource,
{
source.value()
}
#[cfg(test)]
mod test {
use super::*;
struct TestSource(u8);
impl ValueSource for TestSource {
fn value(&self) -> u8 {
self.0
}
}
#[test]
fn one() {
let src = TestSource(99);
assert_eq!(99, my_code(src));
}
}
This will concentrate related details into one object and the compiler monomorphizes the calls, producing optimized code.