3个版本
使用旧的Rust 2015
0.1.2 | 2018年10月10日 |
---|---|
0.1.1 | 2018年6月26日 |
0.1.0 | 2018年3月1日 |
#541 in 测试
每月下载量:29
105KB
2.5K SLoC
以娱乐和盈利为目的破坏Rust代码
这是一个架构预览,并非所有组件都已包含
这是一个针对Rust代码的突变测试框架。
突变测试
程序源代码中的任何更改(突变)都可能是一种错误。一个好的测试套件可以通过失败(“杀死”突变体)来检测源代码中的更改。如果测试套件即使在程序被突变(突变体存活)的情况下仍然是绿色的,则测试未能检测到这种错误。
突变测试是一种评估测试套件质量的方法,类似于代码覆盖率。与行覆盖率或分支覆盖率的不同之处在于,那些衡量的是被测试代码是否被执行,但那并不能说明测试是否能够捕获任何错误。
mutagen的工作原理
mutagen的核心功能通过一个过程宏实现,该宏会转换源代码。除非激活,否则将已知代码模式替换为具有相同行为的突变体。在运行时激活突变体会改变其行为——就像发生了突变。
过程宏可以访问裸AST。在过程宏执行期间,无法访问推断类型、实现特质、控制流、数据流或其他函数的签名等信息。因此,突变必须在没有额外类型信息的情况下是可能的。
为了提高速度,必须只编译一次测试套件。为了实现这一点,所有突变都一次性地嵌入到代码中,并在运行时通过环境变量选择。这意味着突变不能生成无法编译的代码。
这个项目基本上是一个实验,以了解在那些限制下我们还能应用哪些突变。
使用mutagen
注意:本README中引用的mutagen
版本(0.2.0
)尚未在crates.io
上发布。要安装和使用早期已发布的版本,请参考crates.io mutagen crate上的说明。
编译过程宏需要Rust nightly版本。
将库mutagen
添加为dev-dependency
到您的Cargo.toml
中,并引用此git仓库
[dev-dependencies]
mutagen = {git = "https://github.com/llogiq/mutagen"}
要使用属性#[mutate]
,您需要导入它。
#[cfg(test)]
use mutagen::mutate;
现在,您可以通过在函数或方法前添加#[cfg_attr(test, mutate)]
来建议mutagen
对任何函数或方法进行变异。使用cfg_attr
确保#[mutate]
属性仅在测试模式下有效。仓库中包含一个示例,展示了如何使用mutagen
。
运行mutagen
安装cargo-mutagen
,可以通过运行cargo install cargo-mutagen
来完成。在测试项目上运行cargo mutagen
,以进行完整的变异测试评估。
变异也可以手动运行:运行cargo test
将编译代码并将执行的变异写入到target/mutagen/mutations
。此文件包含可能变异的id和描述。然后,可以使用环境变量MUTATION_ID
激活由mutations
文件定义的单个变异。可以在调用测试套件之前设置环境变量,例如MUTATION_ID=1 cargo test
,MUTATION_ID=2 ..
等。对于至少有一个变异计数的情况,测试套件应该失败
可以通过运行cargo mutagen -- --coverage
来减少运行变异代码所需的时间。在此模式下运行时,它在过程开始时运行测试套件并检查哪些测试正在触达变异代码。然后,对于每个变异,而不是再次运行整个测试套件,它只执行受当前变异影响的测试。此模式特别适用于测试套件运行缓慢或变异代码只影响其中一小部分的情况。
如果您在 Using Mutagen
部分中提到的通过 git 仓库引用了 mutagen
,您可能需要安装 cargo-mutagen
的开发版本。要安装开发版本,请在本仓库的 mutagen-runner
目录下运行 cargo install
命令。运行 cargo install --force
可能是必要的,以便覆盖任何现有的 cargo-mutagen
二进制文件。
注意事项
mutagen
将更改您使用 #[mutate]
属性注释的代码。在某些情况下,这可能会导致严重后果。然而,未使用 #[mutate]
属性注释的函数将不会被更改。
请勿对可能因存在错误而导致损坏的代码使用 #[mutate]
。通过破坏程序某些部分的执行行为或健全性检查,可能会发生危险的事故。例如,可能覆盖错误的文件或向错误的服务器发送凭证。
仅将 #[mutate]
用于测试。 这是通过始终使用 #[cfg_attr(test, mutate)]
而不是 #[mutate]
属性注释函数或模块来实现的,这仅在 test
模式下应用 #[mutate]
注释。如果函数在每个模式下都使用纯 #[mutate]
注释,则突变代码将烘焙到代码中,即使在编译为发布版本时也是如此。然而,当使用 mutagen
作为 dev-dependency
时,添加纯 #[mutate]
属性会导致非测试模式下的编译错误,因为编译器找不到该注释。
除非必要,否则请将 mutagen
作为 dev-dependency
使用。 这确保了 mutagen
中的代码不会成为您发布库或应用程序的一部分。
突变限制
在 unsafe
-块和 unsafe
函数中不会引入任何突变。此类突变可能会破坏某些不变性。此外,在非安全代码中的突变可能会导致无法通过任何测试用例观察到的未定义行为。
const
和 static
表达式不能被修改。 它们在编译时进行评估,而 mutagen
只能影响可以在运行时改变其行为的代码。数组长度和全局常量是 const
表达式的例子。
模式不能被修改。 通过注入对 mutagen-内部函数的调用引入修改,这些函数不能放置在模式中。
贡献
欢迎提交问题和 PR!请参阅 CONTRIBUTING.md 了解如何帮助。
依赖关系
~115KB