[Prepare for PHPUnit12] [INFO] No tests found ←This [dataProvider]

[Prepare for PHPUnit12] [INFO] No tests found ←This [dataProvider]

Introduction

This is Enoki from the System Development Department.
This time, I will explain how to solve the problem when you run a test using a dataProvider and get the message "INFO: No tests found."
This is a long story, so if you just want the answer, just read the conclusion

Main Story

The beginning

*In this article, the test content is not important in the slightest, so please don't mind that it doesn't really constitute a test. Me: "Let's write a test... For this test content, dataProvider will be fine!" Me: "Hmph."
<?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_DataProviderTest($data, $expected) $this->assertTrue(true); } }
root:/var/www/html/src# php artisan test tests/Unit/DataProviderTest.php WARN Metadata found in doc-comment for method Tests\Unit\DataProviderTest::test_DataProviderTest(). Metadata in doc-comments is deprecated and will no longer be supported in PHPUnit 12. Update your test code to use attributes instead. INFO No tests found.

Me: "Huh?"
Me: "Wow, so from PHPUnit12 onwards you specify it with an attribute instead of Doc! Got it!"
※The attribute is this → #[]

#[DataProvider('provideParam')] public function test_DataProviderTest($data, $expected) { $this->assertTrue(true); }

Me: "Here we go."
Me: "Let's do it."

root:/var/www/html/src# php artisan test tests/Unit/DataProviderTest.php INFO No tests found.

Me: "Huh?"

Main topic

I can hear some people saying this is a long, drawn-out joke. Anyway, the important thing here is that it says " tests not found ." What do you do in this situation? You'd probably try things like php artisan optimize:clear, composer dump-autoload, or reviewing the namespace and file name. (Please do so.) Naturally, I also just thought, "Oh, it's the same old thing." However, the fact that I'm writing this article means that, naturally, the problem still hasn't been fixed. What I want you to remember here is that it only appears as INFO. Normally, when you specify and run a test that doesn't exist, the following will appear:
root:/var/www/html/src# php artisan test tests/Unit/NoneTest.php PHPUnit 11.2.2 by Sebastian Bergmann and contributors. Test file "tests/Unit/NoneTest.php" not found

This means that the test must exist, but it cannot be found. Next, I created a suitable test to see if this theory was correct
<?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 provider test($data, $expected) { $this->assertTrue(true); } }
root:/var/www/html/src# php artisan test tests/Unit/DataProviderTest.php FAIL Tests\Unit\DataProviderTest ⨯ Data provider test ✓ Appropriate test 0.06s ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────── FAILED Tests\Unit\DataProviderTest > Data provider test The data provider specified for Tests\Unit\DataProviderTest::test_dataprovider test is invalid Data Provider method Tests\Unit\DataProviderTest::provideParam() is not static Tests: 1 failed, 1 passed (1 assertions) Duration: 0.10s

This is more than I expected. It recognizes the file and even the test,
with a precise error.
It seems to want me to make the dataProvider method static.
It will be a robot that follows the error.

<?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_DataProviderTest($data, $expected) { $this->assertTrue(true); } }

root:/var/www/html/src# php artisan test tests/Unit/DataProviderTest.php PASS Tests\Unit\DataProviderTest ✓ Test of data provider with data set "params" 0.06s Tests: 1 passed (1 assertions) Duration: 0.09s

It passed!
It seems that if you make the method used as dataProvider static, it will behave as expected.
For now, the problem has been solved, but I would like to investigate the mystery of "INFO No tests found."

Investigating the cause

Based on the information we have so far, the hypothesis we can make is that the method used as dataProvider must be static.
Here, the first execution result will be helpful.

root:/var/www/html/src# php artisan test tests/Unit/DataProviderTest.php WARN Metadata found in doc-comment for method Tests\Unit\DataProviderTest::test_DataProviderTest(). Metadata in doc-comments is deprecated and will no longer be supported in PHPUnit 12. Update your test code to use attributes instead. INFO No tests found. 

As you can see, the Doc comment states that using dataProvider is still "deprecated" so it's a WARN.
This means that if the dataProvider method is static, it should be able to run normally.

<?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_DataProviderTest($data, $expected) { $this->assertTrue(true); } }

 

root:/var/www/html/src# php artisan test tests/Unit/DataProviderTest.php WARN Metadata found in doc-comment for method Tests\Unit\DataProviderTest::test_DataProviderTest(). Metadata in doc-comments is deprecated and will no longer be supported in PHPUnit 12. Update your test code to use attributes instead. PASS Tests\Unit\DataProviderTest ✓ DataProvider test with data set "params" 0.09s Tests: 1 passed (1 assertions) Duration: 0.14s

As expected, it ran successfully.
However, why does it need to be static? From my memory and looking at the source code, it didn't need to be static before.
So I looked into it.
Quote: https://docs.phpunit.de/en/10.5/writing-tests-for-phpunit.html#data-providers

 public
 and static.
 It must return a value that is iterable, either an array or an object that implements the Traversable interface.
Translation
 data provider methods must be public and static and must return an iterable value (an array or an object that implements the Traversable interface).

That seems to be the case. Let's keep up with the changes.
There was also the following description:

Original textWhen
 a test depends on a test that uses data providers, the depending test will be executed when the test it depends upon is successful for at least one data set.
 The result of a test that uses data providers cannot be injected into a depending test.
 a translation
 test depends on a test that uses a data provider, the dependent test will be executed if the dependent test succeeds for at least one data set. The results of tests that use a data provider will not be injected into the dependent test.

This seems to be the reason why an error occurred when I entered a random test.
It was a perfectly reasonable punch that left me speechless: "Yes! That's exactly right!"
If the previous part of the test failed and the only test that existed was one that assumed that, then it's only natural to get "No tests found."

conclusion

The target method of dataProvider must be a static method

A side note

 why does it need to be static?
 (If you're an engineer, you're probably trembling with fear of being asked to provide the source code, so why is that your opinion?) I think it's probably to "ensure the independence of test data from other tests." Reproducibility and not affecting other tests are very important in testing, and it can guarantee that pure data that is not dependent on the state of the instance is provided. I've looked through various official sources, but I've found information here and there about updates that say, "Make it static!" However, I haven't been able to find any information on why they started forcing it to be static... (If anyone knows, please let me know.)
If you found this article useful, please click [Like]!
12
Loading...
12 votes, average: 1.00 / 112
1,456
X Facebook Hatena Bookmark pocket

The person who wrote this article

About the author

Enoki

I play anything, including FPS, RPG, MMO, and crafting