合肥seo网站排名,o2o平台信息表格,重庆招投标综合信息网,wordpress 好用的主题开发环境
Windows 10Rust 1.73.0 VS Code 1.83.1 项目工程
这里继续沿用上次工程rust-demo 测试组合
正如本章开始时提到的#xff0c;测试是一个复杂的学科#xff0c;不同的人使用不同的术语和组织。Rust社区根据两个主要类别来考虑测试:单元测试和集成测试。单元测试很…开发环境
Windows 10Rust 1.73.0 VS Code 1.83.1 项目工程
这里继续沿用上次工程rust-demo 测试组合
正如本章开始时提到的测试是一个复杂的学科不同的人使用不同的术语和组织。Rust社区根据两个主要类别来考虑测试:单元测试和集成测试。单元测试很小也更集中一次测试一个独立的模块并且可以测试私有接口。集成测试完全在库的外部使用代码的方式和其他外部代码一样只使用公共接口每次测试可能使用多个模块。
编写这两种类型的测试对于确保你的库的各个部分按照你期望的那样单独地或者一起地工作是很重要的。
单元测试
单元测试的目的是独立于代码的其余部分测试每个代码单元以快速查明代码在哪里以及没有按预期工作。您将把单元测试放在每个文件的src目录中其中包含他们正在测试的代码。惯例是在每个文件中创建一个名为tests的模块来包含测试函数并用cfg(test)来注释该模块。
测试模块和#[cfg(test)]
测试模块上的#[cfg(test)]注释告诉Rust只有在运行cargo test时才编译和运行测试代码而不是在运行cargo build时。当您只想构建库时这可以节省编译时间并且因为不包括测试所以可以节省最终编译工件的空间。您将会看到因为集成测试位于不同的目录中所以它们不需要#[cfg(test)]注释。但是因为单元测试与代码在同一个文件中所以您将使用#[cfg(test)]来指定它们不应该包含在编译结果中。
回想一下当我们在本章的第一节中生成新的adder项目时Cargo为我们生成了以下代码:
文件名:src/lib.rs
#[cfg(test)]
mod tests {#[test]fn it_works() {let result 2 2;assert_eq!(result, 4);}
} 这段代码是自动生成的测试模块。属性cfg代表配置它告诉Rust只有在给定某个配置选项的情况下才应该包含以下项目。在这种情况下配置选项是test它由Rust提供用于编译和运行测试。通过使用cfg属性只有当我们主动使用cargo test运行测试时Cargo才会编译我们的测试代码。除了用#[test]注释的函数之外这还包括可能在这个模块中的任何帮助函数。
测试私有函数
在测试社区中有关于私有函数是否应该被直接测试的争论其他语言使得私有函数很难或者不可能被测试。不管你坚持哪种测试思想Rust的隐私规则确实允许你测试私有功能。考虑示例11-12中带有私有函数internal_adder的代码。 文件名:src/lib.rs
pub fn add_two(a: i32) - i32 {internal_adder(a, 2)
}fn internal_adder(a: i32, b: i32) - i32 {a b
}#[cfg(test)]
mod tests {use super::*;#[test]fn internal() {assert_eq!(4, internal_adder(2, 2));}
}
示例11-12:测试私有函数
注意internal_adder函数没有标记为pub。测试只是Rust代码tests模块只是另一个模块。正如我们在“模块树中引用项目的路径”一节中所讨论的子模块中的项目可以使用它们的祖先模块中的项目。在这个测试中我们use super::*将tests模块的所有父项纳入范围然后测试可以调用internal_adder。如果你认为私有函数不应该被测试Rust中没有任何东西会强迫你这么做。
集成测试
在Rust中集成测试完全在你的库之外。他们使用你的库的方式和其他代码一样这意味着他们只能调用属于你的库的公共API的函数。他们的目的是测试你的库的许多部分是否正确地一起工作。独立正常工作的代码单元在集成时可能会出现问题因此集成代码的测试覆盖率也很重要。要创建集成测试您首先需要一个测试目录。
tests目录
我们在项目目录的顶层创建一个测试目录紧挨着src。Cargo知道在这个目录中寻找集成测试文件。然后我们可以根据需要制作尽可能多的测试文件Cargo会将每个文件编译成一个单独的crate箱。
让我们创建一个集成测试。示例11-12中的代码仍然在src/lib.rs文件中创建一个tests目录并创建一个名为tests/integration_test.rs的新文件。 adder ├── Cargo.lock ├── Cargo.toml ├── src │ └── lib.rs └── tests └── integration_test.rs 将示例11-13中的代码输入tests/integration_test.rs文件:
文件名:tests/integration_test.rs
use adder;#[test]
fn it_adds_two() {assert_eq!(4, adder::add_two(2));
}
示例11-13:adder crate箱中函数的集成测试
tests目录中的每个文件都是一个单独的crate箱所以我们需要将我们的库放到每个测试箱子的范围内。因此我们在代码的顶部添加了use adder这在单元测试中是不需要的。
我们不需要用#[cfg(test)]注释tests/integration_test.rs中的任何代码。Cargo对tests目录进行了特殊处理仅当我们运行cargo test时才编译该目录中的文件。立即运行cargo test:
$ cargo testCompiling adder v0.1.0 (file:///projects/adder)Finished test [unoptimized debuginfo] target(s) in 1.31sRunning unittests src/lib.rs (target/debug/deps/adder-1082c4b063a8fbe6)running 1 test
test tests::internal ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sRunning tests/integration_test.rs (target/debug/deps/integration_test-1082c4b063a8fbe6)running 1 test
test it_adds_two ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sDoc-tests adderrunning 0 teststest result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s 输出的三个部分包括单元测试、集成测试和doc测试。请注意如果某个部分中的任何测试失败下面的部分将不会运行。例如如果一个单元测试失败集成和文档测试将不会有任何输出因为这些测试只有在所有单元测试都通过的情况下才会运行。
单元测试的第一部分和我们看到的一样:每个单元测试一行(我们在示例11-12中添加了一个名为internal的行),然后是单元测试的总结行。
集成测试部分从Running tests/integration_test.rs行开始接下来集成测试中的每个测试函数都有一行在Doc-tests adder部分开始之前集成测试的结果有一个摘要行。
每个集成测试文件都有自己的部分所以如果我们在测试目录中添加更多的文件就会有更多的集成测试部分。
我们仍然可以通过将测试函数的名称指定为cargo test的参数来运行特定的集成测试函数。要运行特定集成测试文件中的所有测试请使用cargo test的- test参数后跟文件名:
$ cargo test --test integration_testCompiling adder v0.1.0 (file:///projects/adder)Finished test [unoptimized debuginfo] target(s) in 0.64sRunning tests/integration_test.rs (target/debug/deps/integration_test-82e7799c1bc62298)running 1 test
test it_adds_two ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s 此命令仅运行tests/integration_test.rs文件中的测试。
集成测试中的子模块
当您添加更多的集成测试时您可能想要在测试目录中创建更多的文件来帮助组织它们例如您可以根据测试功能对测试功能进行分组。如前所述tests目录中的每个文件都被编译成它自己的单独的箱这对于创建单独的范围来更接近地模拟最终用户使用您的箱的方式是很有用的。然而这意味着tests目录中的文件与src中的文件不具有相同的行为正如你在第7章中了解到的如何将代码分成模块和文件。
当您有一组在多个集成测试文件中使用的帮助函数并且您试图按照第7章“将模块分离到不同的文件”一节中的步骤将它们提取到一个公共模块中时测试目录文件的不同行为是最明显的。例如如果我们创建tests/common.rs并在其中放置一个名为setup的函数我们可以向setup添加一些代码我们希望从多个测试文件中的多个测试函数调用这些代码:
文件名:tests/common.rs
pub fn setup() {// setup code specific to your librarys tests would go here
} 当我们再次运行测试时我们将在common.rs文件的测试输出中看到一个新的部分尽管这个文件不包含任何测试函数也没有从任何地方调用setup函数:
$ cargo testCompiling adder v0.1.0 (file:///projects/adder)Finished test [unoptimized debuginfo] target(s) in 0.89sRunning unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4)running 1 test
test tests::internal ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sRunning tests/common.rs (target/debug/deps/common-92948b65e88960b4)running 0 teststest result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sRunning tests/integration_test.rs (target/debug/deps/integration_test-92948b65e88960b4)running 1 test
test it_adds_two ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00sDoc-tests adderrunning 0 teststest result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
让common出现在测试结果中并显示正在running 0 tests这不是我们想要的。我们只是想与其他集成测试文件共享一些代码。 为了避免common出现在测试输出中我们不创建tests/common.rs而是创建tests/common/mod.rs。 ├── Cargo.lock ├── Cargo.toml ├── src │ └── lib.rs └── tests ├── common │ └── mod.rs └── integration_test.rs 这是我们在之前的章节“替代文件路径”一节中提到的Rust也理解的旧命名约定。以这种方式命名文件告诉Rust不要将common模块视为集成测试文件。当我们将setup函数代码移动到tests/common/mod.rs中并删除tests/common.rs文件时测试输出中的部分将不再出现。测试目录子目录中的文件不会被编译成单独的箱子也不会在测试输出中包含任何部分。
在我们创建了tests/common/mod.rs之后我们可以从任何集成测试文件中将它作为一个模块来使用。下面是一个从tests/integration_test.rs中的it_adds_two测试调用setup函数的示例:
文件名:tests/integration_test.rs
use adder;mod common;#[test]
fn it_adds_two() {common::setup();assert_eq!(4, adder::add_two(2));
} 注意mod common声明与我们在示例7-21中演示的模块声明相同。然后在测试函数中我们可以调用common::setup()函数。
二元crate箱的集成测试
如果我们的项目是一个只包含src/main.rs文件而没有src/lib.rs文件的二进制文件我们就不能在tests目录中创建集成测试也不能用use语句将src/main.rs文件中定义的函数带入范围。只有库crate箱暴露了其他箱可以使用的功能二进制crate箱是用来独立运行的。
这就是提供二进制文件的Rust项目有一个直接的src/main.rs文件来调用src/lib.rs文件中的逻辑的原因之一。使用这种结构集成测试可以测试库的use情况以使重要的功能可用。如果重要的功能起作用src/main.rs文件中的少量代码也将起作用并且这少量代码不需要测试。
总结
Rust的测试功能提供了一种方式来指定代码应该如何运行以确保它继续按照您的预期工作即使您进行了更改。单元测试分别测试库的不同部分并且可以测试私有的实现细节。集成测试检查库的许多部分是否能正确地协同工作它们使用库的公共API来测试代码就像外部代码使用它一样。尽管Rust的类型系统和所有权规则有助于防止某些类型的错误但测试对于减少与代码预期行为有关的逻辑错误仍然很重要。
让我们结合你在本章和前几章学到的知识来做一个项目
本章重点
测试组合的概念和分类单元测试的概念和使用集成测试的概念和使用 文章转载自: http://www.morning.qhrsy.cn.gov.cn.qhrsy.cn http://www.morning.qbtkg.cn.gov.cn.qbtkg.cn http://www.morning.dxqwm.cn.gov.cn.dxqwm.cn http://www.morning.kysport1102.cn.gov.cn.kysport1102.cn http://www.morning.hhfqk.cn.gov.cn.hhfqk.cn http://www.morning.fqmbt.cn.gov.cn.fqmbt.cn http://www.morning.pqjlp.cn.gov.cn.pqjlp.cn http://www.morning.lxlfr.cn.gov.cn.lxlfr.cn http://www.morning.tkchm.cn.gov.cn.tkchm.cn http://www.morning.btnmj.cn.gov.cn.btnmj.cn http://www.morning.shyqcgw.cn.gov.cn.shyqcgw.cn http://www.morning.qjlkp.cn.gov.cn.qjlkp.cn http://www.morning.mrskk.cn.gov.cn.mrskk.cn http://www.morning.jrlgz.cn.gov.cn.jrlgz.cn http://www.morning.kxyqy.cn.gov.cn.kxyqy.cn http://www.morning.rdkqt.cn.gov.cn.rdkqt.cn http://www.morning.tsxg.cn.gov.cn.tsxg.cn http://www.morning.trtdg.cn.gov.cn.trtdg.cn http://www.morning.ytfr.cn.gov.cn.ytfr.cn http://www.morning.gzzxlp.com.gov.cn.gzzxlp.com http://www.morning.jnbsx.cn.gov.cn.jnbsx.cn http://www.morning.qbtkg.cn.gov.cn.qbtkg.cn http://www.morning.kzrbn.cn.gov.cn.kzrbn.cn http://www.morning.dzdtj.cn.gov.cn.dzdtj.cn http://www.morning.ctbr.cn.gov.cn.ctbr.cn http://www.morning.wnjsp.cn.gov.cn.wnjsp.cn http://www.morning.ns3nt8.cn.gov.cn.ns3nt8.cn http://www.morning.lwdzt.cn.gov.cn.lwdzt.cn http://www.morning.qtrlh.cn.gov.cn.qtrlh.cn http://www.morning.pflry.cn.gov.cn.pflry.cn http://www.morning.mjctt.cn.gov.cn.mjctt.cn http://www.morning.ncwgt.cn.gov.cn.ncwgt.cn http://www.morning.qhmhz.cn.gov.cn.qhmhz.cn http://www.morning.wffxr.cn.gov.cn.wffxr.cn http://www.morning.snnb.cn.gov.cn.snnb.cn http://www.morning.xckqs.cn.gov.cn.xckqs.cn http://www.morning.nsrtvu.com.gov.cn.nsrtvu.com http://www.morning.rqpgk.cn.gov.cn.rqpgk.cn http://www.morning.ftsmg.com.gov.cn.ftsmg.com http://www.morning.hhrpy.cn.gov.cn.hhrpy.cn http://www.morning.gwsll.cn.gov.cn.gwsll.cn http://www.morning.ygxf.cn.gov.cn.ygxf.cn http://www.morning.rjfr.cn.gov.cn.rjfr.cn http://www.morning.znsyn.cn.gov.cn.znsyn.cn http://www.morning.ahlart.com.gov.cn.ahlart.com http://www.morning.hkswt.cn.gov.cn.hkswt.cn http://www.morning.smmby.cn.gov.cn.smmby.cn http://www.morning.fwcnx.cn.gov.cn.fwcnx.cn http://www.morning.bpmns.cn.gov.cn.bpmns.cn http://www.morning.jltmb.cn.gov.cn.jltmb.cn http://www.morning.gpsrk.cn.gov.cn.gpsrk.cn http://www.morning.wxrbl.cn.gov.cn.wxrbl.cn http://www.morning.ylmxs.cn.gov.cn.ylmxs.cn http://www.morning.qdmdp.cn.gov.cn.qdmdp.cn http://www.morning.ptzf.cn.gov.cn.ptzf.cn http://www.morning.fesiy.com.gov.cn.fesiy.com http://www.morning.yodajy.cn.gov.cn.yodajy.cn http://www.morning.kzrg.cn.gov.cn.kzrg.cn http://www.morning.zrnph.cn.gov.cn.zrnph.cn http://www.morning.gkxyy.cn.gov.cn.gkxyy.cn http://www.morning.llllcc.com.gov.cn.llllcc.com http://www.morning.wjxyg.cn.gov.cn.wjxyg.cn http://www.morning.qhrdx.cn.gov.cn.qhrdx.cn http://www.morning.hmdyl.cn.gov.cn.hmdyl.cn http://www.morning.xhsxj.cn.gov.cn.xhsxj.cn http://www.morning.bncrx.cn.gov.cn.bncrx.cn http://www.morning.brbmf.cn.gov.cn.brbmf.cn http://www.morning.rzmsl.cn.gov.cn.rzmsl.cn http://www.morning.nqgjn.cn.gov.cn.nqgjn.cn http://www.morning.vvbsxm.cn.gov.cn.vvbsxm.cn http://www.morning.dpzcc.cn.gov.cn.dpzcc.cn http://www.morning.fgxr.cn.gov.cn.fgxr.cn http://www.morning.znqmh.cn.gov.cn.znqmh.cn http://www.morning.xtkw.cn.gov.cn.xtkw.cn http://www.morning.txqgd.cn.gov.cn.txqgd.cn http://www.morning.ydnx.cn.gov.cn.ydnx.cn http://www.morning.mgtmm.cn.gov.cn.mgtmm.cn http://www.morning.xhftj.cn.gov.cn.xhftj.cn http://www.morning.zlhcw.cn.gov.cn.zlhcw.cn http://www.morning.ddrdt.cn.gov.cn.ddrdt.cn