#mutation #runner #fun #breaking #mutagen

app cargo-mutagen

Rust 的突变测试 - 运行器

2 个版本

使用旧的 Rust 2015

0.1.2 2018 年 6 月 26 日
0.1.1 2018 年 3 月 7 日
0.1.0 2018 年 3 月 7 日

Cargo 插件 中排名 #455

Apache-2.0/MIT

18KB
406

为了乐趣和利润打破 Rust 代码

这是一个架构预览,不是所有组件都存在

这是一个用于 Rust 代码的突变测试框架。

突变测试

程序源代码中的更改(突变)很可能是一种类型的错误。一个好的测试套件可以通过失败(“杀死”突变体)来检测源代码中的更改。如果测试套件在程序突变的情况下仍然为绿色(突变体存活),则测试未能检测到此错误。

突变测试是评估测试套件质量的一种方法,类似于代码覆盖率。与行或分支覆盖率的区别在于,那些衡量的是测试代码是否被 执行,但这并没有说测试是否会捕获任何错误。

mutagen 的工作原理

mutagen 的核心功能通过一个过程宏实现,该宏转换源代码。已知代码模式被具有相同行为的突变器替换,除非激活。在运行时激活突变器会改变其行为——具有突变的效果。

过程宏可以访问裸 AST。在过程宏执行期间,无法访问有关推断类型、实现的特质、控制流、数据流或其他函数签名的信息。因此,突变必须在没有额外类型信息的情况下是可能的。

为了快速执行,必须只编译一次测试套件。为此,所有突变都一次性嵌入到代码中,并通过环境变量在运行时选择。这意味着突变不允许产生无法编译的代码。

这个项目基本上是一个实验,看看在那些限制下我们还可以应用哪些突变。

使用 mutagen

注意:本README中引用的mutagen(版本0.2.0)尚未在crates.io上发布。要安装和使用更早已发布的版本,请按照crates.io mutagen crate上的说明进行操作。

编译过程宏需要Rust夜间构建版本。

将库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 testMUTATION_ID=2 ..等。对于至少有一个变异计数的情况,测试套件应该失败

您可以通过运行cargo mutagen -- --coverage来减少运行变异代码所需的时间。在此模式下运行时,它会在进程开始时运行测试套件并检查哪些测试正在影响变异代码。然后,对于每个变异,而不是再次运行整个测试套件,它只会执行受当前变异影响的测试。此模式在测试套件运行缓慢或变异代码只影响其一小部分时特别有用。

如果您在 cargo.toml 中通过 Git 仓库引用了 mutagen(如《使用 Mutagen》部分所述),您可能需要安装 cargo-mutagen 的开发版本。要在该仓库的 mutagen-runner 目录下安装开发版本,请运行 cargo install。运行 cargo install --force 可能是必要的,以覆盖任何现有的 cargo-mutagen 二进制文件。

警告

mutagen 将更改您使用 #[mutate] 属性注解的代码。在某些情况下,这可能会产生严重后果。然而,未使用 #[mutate] 属性注解的函数将不会被更改。

不要将 #[mutate] 用于可能因错误而造成损坏的代码。通过破坏程序某些部分的运行行为或健全性检查,可能会发生危险的事故。例如,通过覆盖错误的文件或将凭证发送到错误的服务器。

仅将 #[mutate] 用于测试。这是通过始终使用 #[cfg_attr(test, mutate)] 来注解函数或模块来实现的,这仅在 test 模式下应用 #[mutate] 注解。如果一个函数在每个模式下都使用纯 #[mutate] 注解,则突变代码将被编译到代码中,即使编译为发布版本。但是,当使用 mutagen 作为 dev-dependency 时,添加纯 #[mutate] 属性将在非测试模式下导致编译错误,因为编译器找不到注解。

除非必要,否则请将 mutagen 作为 dev-dependency 使用。这确保了 mutagen 中的代码不会成为您的发布库或应用程序的一部分。

突变的限制

不会在 unsafe-块和 unsafe 函数中引入突变。此类突变可能会破坏某些不变量。此外,在非安全代码中的突变可能导致无法通过任何测试用例观察到的未定义行为。

conststatic 表达式不能被突变。它们在编译时进行评估,而 mutagen 只能影响可以在运行时改变其行为的代码。数组长度和全局常量是 const 表达式的例子。

模式不可变。 变更通过注入对mutagen内部函数的调用而引入,这些调用不能放置在模式内。

贡献

欢迎提出问题和PR!有关如何帮助的详细信息,请参阅CONTRIBUTING.md

依赖项

约265KB