Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do some devs use mod tests for tests?

Tags:

rust

Some people do

#[cfg(test)]
mod tests {
   //all tests here
}

While simply putting every test in the end of the file like

#[test]
fn test1() {

}

#[test]
fn test2() {

}

works too and I can even run single tests by cargo.

What is the difference? Why do some people do it the first way?

like image 769
Gatonito Avatar asked Apr 23 '21 03:04

Gatonito


People also ask

What is a mod test?

THE MODULE 1 TEST (MOD 1) Module 1 is a test of your machine control and is conducted at an off-road site called a 'motorcycle manoeuvre area' or MMA for short. With our training you'll be able to practice on the official DSA site prior to taking the test.

Why is it important to test code?

Testing your code teaches you how to write good code because you have to fix all of your bad code. When you have to go through and fix your own bugs you learn different ways to solve problems. The number of ways you can break code is immeasurable and that's what makes it so interesting.

What is CFG test?

The #[cfg(test)] annotation on the tests module tells Rust to compile and run the test code only when you run cargo test , not when you run cargo build .

How do you test for Rust?

A primary testing method is Salt Spray testing, which as its name indicates, evaluates how resistant a part or material is to corrosion when exposed to a salt spray for extended periods of time. Effective Salt Spray testing must be performed in a controlled environment, such as a closed salt fog tank.

Do developer tests include regression or system tests?

Note that developer tests do not consider Regression or System Tests. Developers can also write code to automate Regression and/or System Tests, but that would come at a later stage in the development cycle when the application is in a more complete state.

How are developer tests written?

Developer tests are written whilst the developer is writing the actual functionality. This process is tightly integrated so that the developer can work in a flow of writing tests and the logic. There are two widely adopted approaches for writing developer tests: Test Driven Development (TDD)

What is test driven development (TDD)?

Test Driven Development (TDD) Behaviour Driven Development (BDD) These different approaches are often the main point of contention amongst developers when setting out a testing strategy. Note that developer tests do not consider Regression or System Tests.

What is regression testing and how does it work?

Regression testing is the repetition of previously executed test cases for the purpose of finding defects in software that previously passed the same set of tests. Such tests would commonly be used before shipping code to a new environment or as part of a build process.


Video Answer


2 Answers

You often need to share some code between your tests, for example macros and functions used for building the test cases or to check the result values. And you sometimes have to import whole crates just for your tests.

The #[cfg(test)] conditional compilation attribute makes it possible to have code not compiled when not testing. This enables faster checks and a faster compilation in the general case. If you include a crate just for the tests, you can import it in those mods and specify the dev dependency in a [dev-dependencies] section of your Cargo.toml.

Here's an example of such a test mod where some functions are used in several tests: wrap.rs.

I personally create a mod as soon as the tests of a function aren't trivial, even when there's not (yet) any shared help function: the test mod then appears as an easy to notice test block in my code.

Sometimes you go even further by using the "tests" directory solution for your integration tests, which makes it easier to have whole mods shared between your tests. This is often the most practical solution when your tests are more than unit tests (some crates have more tests than tested code).

Read the rust book on test organization to know more.

like image 132
Denys Séguret Avatar answered Oct 21 '22 22:10

Denys Séguret


You don't want your code under test to be able to access any test code. By putting the tests and helper functions in a child module (and not making them pub), you prevent the code under test to access any test code.

The following sample code will help demonstrate my point:

src/add.rs

pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

pub fn compiler_test() {
    // Uh oh, below compiles!
    #[cfg(test)]
    test_add();

    // Good, error[E0603]: function `test_add` is private
    #[cfg(test)]
    tests::test_add();
    //     ^^^^^^^^ private function
}

#[test]
fn test_add() {
    assert_eq!(add(4, 5), 9)
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_add() {
        assert_eq!(super::add(1, 2), 3)
    }
}

Note that skipping mod tests does not prevent you from making use of [dev-dependencies], because #[test] is enough to make compilation conditional on #[cfg(test)].

like image 43
Enselic Avatar answered Oct 21 '22 22:10

Enselic