sandstorm / fuzzer
通过模糊测试提高您的功能性和单元测试:一种寻找测试中缺失边缘情况的技巧。
Requires
- phpunit/php-code-coverage: 1.2.*
- typo3/flow: *
This package is auto-updated.
Last update: 2020-02-08 19:30:13 UTC
README
-- 测试您的测试覆盖率 --
(c) Sebastian Kurfürst,Sandstorm 媒体 UG(有限责任)
2.0 新增
单元和功能测试
在版本 1.* 中,Fuzzer 只能与单元测试一起工作。在新版本中,它支持单元和功能测试,大大扩展了其用例。
通过 Composer 安装 PHPUnit
现在也支持通过 composer 安装 PHPUnit,如果 PEAR 已安装版本,则回退到该版本
增强鲁棒性
现在会检查所需的命令行工具是否可用。
功能测试的代码覆盖率辅助工具
收集和分析您的功能测试的代码覆盖率。请见下面的使用说明。
2.0 新增:代码覆盖率辅助工具
除了模糊测试之外,该包还实现了几个与功能测试一起工作的辅助工具
# run unit and functional tests, both creating code coverages
bin/phpunit -c Build/BuildEssentials/UnitTests.xml --coverage-php Build/Reports/RawUnitTestCoverage.php
bin/phpunit -c Build/BuildEssentials/FunctionalTests.xml --coverage-php Build/Reports/RawFunctionalTestCoverage.php
# post-process the functional test coverage (conversion from cache directories to packages)
./flow codecoverage:convert Build/Reports/RawFunctionalTestCoverage.php Build/Reports/FunctionalTestCoverage.php --packages Your.Package,Your.OtherPackage
# Merge the reports for unit and functional test coverage
./flow codecoverage:merge Build/Reports/RawUnitTestCoverage.php Build/Reports/FunctionalTestCoverage.php Build/Reports/TestCoverage.php
# render the final report as HTML:
./flow codecoverage:render Build/Reports/TestCoverage.php Build/Reports/TestCoverage
# OR: render the final report as clover file
./flow codecoverage:render Build/Reports/TestCoverage.php Build/Reports/TestCoverage.xml --format clover
模糊测试
您使用自动化的单元/功能测试来检查您的软件吗?您正在监控单元测试的代码覆盖率吗?是的 -- 那么这款软件就是为您准备的!它有助于在测试中找到缺失的边缘情况。
它实现了一种称为 模糊测试 的技术。
我们对覆盖率的理解
正常的“代码覆盖率”指标(例如,由 PHPUnit 测量)仅计算在测试运行期间代码行被执行的频率。
因此,虽然 PHPUnit 代码覆盖率检查您是否 执行 所有已覆盖的行,但它并不能证明您在特定行上执行的功能是否已被 验证。
以下是一个示例来阐明这一点。假设您有一个以下类
class Foo { protected $someInternalState = 0; public function someMethod() { $this->someInternalState++; return 42; } public function getInternalState() { return $this->someInternalState; } }
... 以及以下测试用例
/** * @test */ public function someTest() { $myObject = new Foo(); $this->assertSame(42, $myObject->someMethod()); } /** * @test */ public function someOtherTest() { $myObject = new Foo(); $this->assertSame(0, $myObject->someInternalState()); }
此示例的 代码覆盖率 为 100%,因此您可能会说“是的,太棒了,这里没有需要改进的地方”。然而,如果您仔细查看代码,您会看到注释掉 $this->someInternalState++
这一行将 不会破坏单元测试,尽管功能已损坏。
出现模糊测试器
模糊测试器会自动 修改您的源代码,检查生成的文件是否具有有效的语法,然后运行单元/功能测试。在一个理想的世界里,测试会在每次修改后失败,因为我们修改了源代码,并故意破坏了某些功能。
模糊测试器会检测到源代码已被修改,但测试仍然成功运行的情况,这表明您需要编写哪些其他测试用例。
安装
该系统已在 Mac OS 上进行测试,并且应该在 Linux 上也能运行。它可能在 Windows 上无法运行。
只需运行 composer require --dev sandstorm/fuzzer:2.*
您还需要安装以下命令行工具
- git
- php (由于您已经有一个正常工作的TYPO3 Flow安装,所以不应存在问题)
- xdebug (因为我们必须能够运行带有代码覆盖率报告的phpunit)
- phpunit (也可以使用Composer安装)
- timeout (在Mac OS上,您可以使用MacPorts通过“port install timeout”安装;默认情况下,许多Linux发行版中都已安装)
用法
首先,请确保您有相当高的代码覆盖率,因为模糊测试器只会在单元测试覆盖的代码上工作(以减少误报的数量)。
./flow3 fuzzer:fuzz <ThePackageKeyYouWantToTest>
该包必须拥有自己的Git仓库,并且必须没有未提交的更改,否则工具将无法运行。
示例输出
Unmodified unit tests took 1 seconds, setting timeout to 3 seconds (to be safe).
Generating and Testing Mutations:
_.__.._..._.___....__.E._._..._..._.__.E._...._..E__.__.._.._.._E_.___._.___...E_.._._._..._.T._..._
Undetected Mutations
--------------------
Classes/Domain/Model/FooBar.php
Package: TYPO3.FooBar
Diff follows below
diff --git a/Classes/Domain/Model/FooBar.php b/Classes/Domain/Model/FooBar.php
index 8fde46c..bee58d7 100644
--- a/Classes/Domain/Model/FooBar.php
+++ b/Classes/Domain/Model/FooBar.php
@@ -107,7 +107,7
public function registerIfPossible() {
- parent::registerIfPossible();
+# parent::registerIfPossible();
foreach ($this->elements as $element) {
$element->doStuff();
}
... output for all other undetected mutations ...
Fuzzing Statistics
------------------
Total Mutations: 253
Mutations with Broken Syntax: 120
Detected Mutations: 127
Undetected mutations: 6 (see above for details)
Total Runtime: 61 s
在上面的示例中,您可以看到注释掉“parent::...”调用并没有导致单元测试失败——因此您现在可以编写这个额外的单元测试。
对于每次变异运行,都会显示一个进度指示器,就像PHPUnit那样完成。字符代表以下含义
_
变异包含PHP语法错误.
单元测试可以运行,并且它们正确失败T
单元测试遇到了超时(这也是预期行为)E
单元测试成功运行;这意味着没有检测到变异。 这是我们正在寻找的情况。
超时
随着我们修改源代码,修改后的源代码可能不再终止。因此,我们首先检查单元测试的运行时间,然后添加一些偏移量,如果测试运行时间超过预期,则终止测试。如果发生这种情况,我们将以与测试失败相同的方式处理它。
内部
系统中提供了不同的模糊测试器,用于生成源代码变异
- SingleLineFuzzer:逐行注释掉源代码中的一行。仅适用于在单元测试中至少执行过一次的行
- (此处还将有更多内容)
许可证
所有代码均受GPL许可证许可。