人们喜欢反复提及在 Rust 语言中“只要代码能编译,就能正常运行”的说法。编译器确实消除了一整类错误,但它并不检查你的业务逻辑。错误的折扣计算可以顺利编译通过。向支付应用程序接口(API)发送请求时混淆了头部信息,同样也能编译通过。你仍然需要编写测试,而在 Rust 中编写测试相当简单:测试运行器已内置于工具链中,无需安装 Jest 或 Pytest。
首先快速了解一下基础知识,然后探讨令人头疼的部分:测试涉及超文本传输协议(HTTP)通信的代码。
语言提供的功能
一个零依赖的最小化测试:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn discount_is_applied() {
assert_eq!(apply_discount(100, 10), 90);
}
}
运行 cargo test 即可完成。单元测试与代码放在一起,可以访问私有函数。集成测试则放入 tests/ 目录,将当前 crate(代码包)视为外部使用者,仅能访问公开的应用程序接口(API)。
此外还有文档测试。文档中的代码示例在每次运行时都会被编译和执行。如果自述文件(README)中的示例过时,它将无法通过持续集成(CI)检查。虽然这只是个小细节,但它能确保你保持严谨。
至于第三方库,dev-dependencies(开发依赖)中常见的库包括 pretty_assertions(在比较大型结构体时提供差异对比,而非冗长的文本输出)和 proptest——一种基于属性的测试库,你只需描述不变量,该库便会生成数百种输入数据,并为你简化反例。有些人更喜欢 quickcheck,它更古老且简单。对于快照测试,可以使用 insta。异步测试则使用 #[tokio::test] 进行包装。
有一项功能并非开箱即用,那就是参数化测试。rstest 填补了这一空白——通过 #[case] 属性,一个测试可以针对多组输入数据运行,并且在此基础上提供了类似 Pytest 的夹具(fixtures)功能:
#[rstest]
#[case(100, 10, 90)]
#[case(100, 0, 100)]
#[case(0, 50, 0)]
fn discount(#[case] price: <
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。