编写Rust单元测试,但在独立文件中

pw9qyyiw  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(118)

概述

我想写一些Rust单元测试。通常的方法是将它们放在与测试代码相同的文件中。但是,这通常会使代码文件非常大,特别是如果单元测试的行数比被测试的代码长很多倍。根据我的经验,这种情况经常发生。一些测试,甚至是单元测试,可能会做非常复杂和复杂的测试。我经常发现自己为一个代码单元编写了数千行的单元测试,而这个代码单元本身只有大约1k行长。如果有很多状态需要设置,并且不能将其捆绑到单个helper函数中,则经常会发生这种情况。

问题汇总

如何将测试代码移到一个单独的文件中,而不会以一个奇怪的模块结构结束?如果我正在编写一个包含另一个文件的测试的文件,那么这两个文件应该在同一个目录中。除非我错过了一些明显的东西,否则在Rust中没有直接的方法来做到这一点。也许我只是还没有意识到解决方案?

示例

考虑一个简单的例子,下面的库代码:

lib.rs
  ./my_module/
    mod.rs
    implementation.rs
    ./implementation
    the_test.rs
// lib.rs
pub mod my_module;
// my_module/mod.rs
pub mod implementation;
// my_module/implementation.rs

// silly example function
fn str_to_bool(input: &str) -> bool {

    match input {
        "true" => { return true; }
        _ => { return false; }
    }
}

mod the_test;
// my_module/implementation/the_test.rs

#[cfg(test)]

#[test]
fn str_to_bool_test() {

    let input = "true";
    assert!(str_to_bool(input) == true);
}

这是相当明显的什么缺点。虽然测试代码已成功移动到单独的文件中,但测试文件存在于测试代码下面的子目录中。
理想情况下,我更喜欢测试文件与测试文件下的代码放在一起。
我想不出一个好办法来做这件事。将模块声明移到更高的级别似乎不是一个好的解决方案,因为测试模块应该是包含被测代码的模块的子模块。

11dmarpk

11dmarpk1#

“规范”的解决方案是这样构建它:

.\implementation
        mod.rs
        tests.rs

或者这个:

.\implementation.rs
    .\implementation
        tests.rs

并将其添加到父模块:

#[cfg(test)]
mod tests;

但是如果你想要一个更扁平的文件结构,你可以使用path属性:

.\implementation.rs
.\implementation.test.rs

下面的代码位于implementation.rs的顶部:

#[cfg(test)]
#[path = "implementation.test.rs"]
mod tests;

相关问题