[为 PHPUnit12 做准备] [ INFO ] 没有找到测试 ← 这个 [dataProvider]
目录
[为 PHPUnit12 做准备] [ INFO ] 没有找到测试 ← 这个 [dataProvider]
介绍
我叫 Enoki,来自系统开发部。
这次,我将介绍如何解决使用dataProvider运行测试时出现INFO No tests found的问题。
这是一场漫长的闹剧,如果你只想知道答案,请看结论
主要故事
事情的开始
*测试内容在本文中并不重要,因此不必担心它不是测试本身的一部分。我:“你想写一个测试吗……?对于这个测试内容,dataProvider 就可以了!” 我:“哼。”
<?php namespace Tests\Unit; use PHPUnit\Framework\Attributes\DataProvider; use Tests\TestCase; class DataProviderTest extends TestCase { /** * @return array */ public function provideParam(): array { return[ 'params' => ['data', 'true'], ]; } /** * @dataProvider ProvideParam */ public function test_Dataprovider test($data, $expected) $this->assertTrue(true);
root:/var/www/html/src# php artisan test tests/Unit/DataProviderTest.php 警告 在方法 Tests\Unit\DataProviderTest::test_DataProviderTest() 的文档注释中找到的元数据已被弃用,并将被弃用。 PHPUnit 12 不再支持。更新您的测试代码以使用属性 INFO 未找到测试。
我:“嗯?”
我:“嗯~从 PHPUnit12 开始,你用属性而不是 Doc 来指定它!”
*这是属性 → #[]
#[DataProvider('provideParam')] public function test_Data provider test($data, $expected) { $this->assertTrue(true);
我:“嘿!”
我:“我们开始吧。”
root:/var/www/html/src# php artisan test 测试/Unit/DataProviderTest.php 信息 未找到测试。
我:“是吗?”
主要议题
我几乎能听到人们说:“这是一场闹剧。” 不管怎样,这里重要的是它说测试未找到 在这种情况下你会怎么做? 现在,我认为您可能会执行 php artisan optimize:clear、composer dump-autoload 等操作,并检查命名空间和文件名。 (请这样做。) 当然,我也想,“啊,那是平常的事情。” 然而,写下这篇文章,自然也就意味着过不去。 我希望您记住的是,它只是显示为 INFO。 通常,当您指定并执行不存在的测试时,结果如下。
root:/var/www/html/src# php artisan test tests/Unit/NoneTest.php PHPUnit 11.2.2 由 Sebastian Bergmann 和贡献者找到 测试文件“tests/Unit/NoneTest.php”。
这意味着测试必须存在,但无法找到。 接下来,我创建了一个随机测试来看看这个理论是否正确。
<?php namespace Tests\Unit; use PHPUnit\Framework\Attributes\DataProvider; use Tests\TestCase; class DataProviderTest extends TestCase { /** * @return array */ public function provideParam(): array { return[ 'params' => ['data', 'true'], ]; } public function test_Appropriate test() { $this->assertTrue(true); } #[DataProvider('provideParam')] public function test_测试数据提供者 ($data, $预期) { $this->assertTrue(true);
root:/var/www/html/src# php artisan test tests/Unit/DataProviderTest.php FAIL Tests\Unit\DataProviderTest ⨯ 数据提供者测试 ✓ 任意测试 0.06s ──────────── ── ──────────────────────────────────────────────────── ──────────────────────────────────────────── 失败的测试\ Unit\DataProviderTest > 数据提供程序测试 为 Tests\Unit\DataProviderTest::test_Data Provider Test 指定的数据提供程序无效 数据提供程序方法 Tests\Unit\DataProviderTest::provideParam() 不是静态 测试:1 次失败,1 次通过(1 个断言) 持续时间: 0.10秒
我得到的结果比我预期的要多。不仅可以识别文件,还可以识别测试。
并且有准确的错误。
您似乎想将 dataProvider 方法创建为静态方法。
成为一个追随错误的机器人。
<?php namespace Tests\Unit; use PHPUnit\Framework\Attributes\DataProvider; use Tests\TestCase; class DataProviderTest extends TestCase { /** * @return array */ public static function provideParam(): array { return[ 'params' => ['data', 'true'], ]; } #[DataProvider('provideParam')] public function test_Data 提供程序 test($data, $expected) { $this->assertTrue(true);
root:/var/www/html/src# php artisan test 测试/Unit/DataProviderTest.php 通过 Tests\Unit\DataProviderTest ✓ 使用数据集“params”进行数据提供者测试 0.06s 测试:1 次通过(1 次断言) 持续时间:0.09 s
通过了!
显然,如果您将用作 dataProvider 的方法设置为静态,它将按照您想要的方式运行。
我现在已经解决了这个问题,但我想探究“INFO Notestsfound”的奥秘。
追求事业
根据目前所知,我们可以做出的假设是用作 dataProvider 的方法必须是静态的。
在这里,第一次运行的结果很有帮助。
root:/var/www/html/src# php artisan test tests/Unit/DataProviderTest.php 警告 在方法 Tests\Unit\DataProviderTest::test_DataProviderTest() 的文档注释中找到的元数据已被弃用,并将被弃用。 PHPUnit 12 不再支持。更新您的测试代码以使用属性 INFO 未找到测试。
正如您所看到的,在文档注释中使用 dataProvider 仍然只是“已弃用”,因此这是一个警告。
这意味着即使是静态的dataProvider方法也能成功执行。
<?php namespace Tests\Unit; use PHPUnit\Framework\Attributes\DataProvider; use Tests\TestCase; class DataProviderTest extends TestCase { /** * @return array */ public static function provideParam(): array { return[ 'params' => ['data', 'true'], ]; } /** * @dataProvider ProvideParam */ public function test_Dataprovider test($data, $expected) { $this->assertTrue(true);
root:/var/www/html/src# php artisan test tests/Unit/DataProviderTest.php 警告 在方法 Tests\Unit\DataProviderTest::test_DataProviderTest() 的文档注释中找到的元数据已被弃用,并将被弃用。 PHPUnit 12 不再支持。更新您的测试代码以使用属性 PASS Tests\Unit\DataProviderTest ✓ 使用数据集“params”进行数据提供程序测试 0.09 秒 测试:1 个通过(1 个断言) 持续时间:0.14 秒。
正如假设的那样,它成功执行了。
但是,为什么它需要是静态的呢?根据我的记忆并查看源代码,它之前不需要是静态的。
所以我调查了一下。
〇引用: https://docs.phpunit.de/en/10.5/writing-tests-for-phpunit.html#data-providers
数据提供者方法必须是公共的和静态的,
一个可迭代的值,可以是一个数组,也可以是一个实现 Traversable 接口的对象。
翻译
数据提供者方法必须是公共且静态的。 它必须返回一个可迭代值(一个数组或一个实现 Traversable 接口的对象)。
情况似乎确实如此。跟上变化。
还有以下声明:
原文当
一个测试依赖于一个使用数据提供者的测试时,当它所依赖的测试至少在一个数据集上成功时,才会执行依赖的测试。
使用数据提供者的测试的结果不能注入到依赖的测试中。 。
翻译
测试依赖于使用数据提供者的测试,则当依赖测试在至少一个数据集上成功时,依赖测试将会运行。 使用数据提供程序的测试结果不会注入到相关测试中。
这似乎是我进行适当测试时出现错误的原因。
当你这么说的时候,这是一个合法的拳头,不会让你说:“是的!你是对的!”
如果测试之前的部分失败并且只有一个假设“未找到测试”的测试,这是很自然的。
结论
将 dataProvider 的目标方法设为静态方法。
题外话
为什么它需要是静态的? 问题出现了。 (我想知道为什么你的观点是,如果你是一名工程师,你会因害怕被要求提供来源而颤抖。)我认为这可能是“保证测试数据与测试的独立性”的一种方法。 重复性和不干扰其他测试在测试中非常重要,我们可以保证提供独立于实例状态的纯数据。我尝试搜索各种官方来源,但请使其静态!有关此更新的信息已随处可见。 但是,我找不到任何关于为什么它被强制静态的信息......(如果有人知道,请告诉我)