当前位置:嗨网首页>书籍在线阅读

08-隔离测试代码

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

3.3.3 隔离测试代码

当我们的测试变得日益复杂时,可能需要创建其他辅助方法,这些方法只能在测试代码的上下文中使用。在这种情况下,将相关的测试代码与实际代码隔离是很有益的。我们可以通过将所有与测试有关的代码封装在模块中,并在其上放置#[cfg(test)]注释标记来达到此目的。

[cfg(...)]属性中的 cfg 通常用于条件编译,但不限于测试代码。它可以为不同体系结构或配置标记引用或排除某些代码。这里的配置标记是test。你可能还记得第2章的测试中已经采用了这种格式。这样做的好处是,只有当你运行cargo test命令时,测试代码才会被编译,并包含到已编译的二进制文件中,否则其将会被忽略。

假如你希望以编程方式生成测试数据,但是不必在正式上线的版本中包含这些代码。让我们通过运行cargo new unit_test --lib命令来演示这一点。在lib.rs中,我们定义了一些测试和函数:

// unit_test/src/lib.rs
//我们想要测试的函数
fn sum(a: i8, b: i8) -> i8 {
    a + b
}
#[cfg(test)]
mod tests {
    fn sum_inputs_outputs() -> Vec<((i8, i8), i8)> {
        vec![((1, 1), 2), ((0, 0), 0), ((2, -2), 0)]
    }
    #[test]
    fn test_sums() {
        for (input, output) in sum_inputs_outputs() {
            assert_eq!(crate::sum(input.0, input.1), output);
        }
    }
}

我们可以通过cargo test命令来运行这些测试。让我们详细解读一下上述代码。在sum_inputs_outputs函数中会生成已知的输入和输出对。#[test]属性使得test_sums函数不会出现在正式发布的编译版本中。但是,sum_inputs_outputs并没有使用#[test]进行标记,如果它是在tests模块之外声明的,那么它会被包含到正式发布的编译版本中。通过将#[cfg(test)]标记和一个mod tests子模块搭配使用,并将所有测试代码及其相关函数封装到此模块中,可以确保代码和生成的二进制文件都是纯粹的测试代码。

我们的sum函数在前面没有pub关键字修饰的情况下是私有的,这意味着模块中的单元测试还允许用户测试私有的函数和方法。这样做会非常方便。