[PHPUnit] I tried using DataProvider!

Hello!
This is Fukui from the System Development Department!

This time, I tried using an annotation called DataProvider (a convenient mechanism) that can be used with PHPUnit, so I will introduce how to use it along with the background and history of how I came to use it!
*In this article, I will not be explaining the annotation itself (what is an annotation)

What is a DataProvider?

overview

Simply put, a convenient mechanism that allows you to use multiple arbitrary arguments in PHPUnit test methods .
*For more detailed explanations and annotations, please refer to the official PHPUnit documentation.

■ PHPUnit official documentation
https://phpunit.de/documentation.html

■ About DataProvider (annotation)
https://docs.phpunit.de/en/11.0/annotations.html#dataprovider

When to use

As mentioned above, you can pass multiple arguments to a test method,
useful when you want to use multiple different values ​​for the same test method .


Specifically , for example, suppose there is a parameter check process for user information and the "login ID is required."

・Null and empty strings are rejected as abnormal
・Response parameters are the same (resulting in the same error response)

In this case,
strictly speaking, the test cases are different, but the difference required for the test is whether
the login ID is "null" or "empty string." I think this will be useful when implementing such tests.

So, since it's hard to understand just from text, I'll try writing some actual test code below

How to use

Try writing it yourself

For now, I wrote a simple test code using DataProvider

I would like to see whether the multiple values ​​set in DataProvider (in this case, empty string and null) can be obtained from the test method arguments and whether the test at least passes

namespace Tests\Feature; use Tests\TestCase; use Illuminate\Testing\Assert; class DataProviderSampleTest extends TestCase { /** * Abnormal case: Test when login ID is not specified * @param string $invalidLoginId * @dataProvider invalidLoginIds */ public function testInvalidLoginId($invalidLoginId): void { Assert::assertEmpty($invalidLoginId); } /** * Abnormal login ID test data * * @return array */ public static function invalidLoginIds(): array { return [ [''], [null], ];

The key points of implementation are as follows:

  1. You can use invalidLoginIds() as a DataProvider by annotating the test method with @dataProvider
  2. Although invalidLoginIds() returns an array, the elements within the array must also be described as an array (like [''] and [null])
  3. The argument to testInvalidLoginId() is $invalidLoginId, but you can choose any value you like (this is not intended to be singular)

Check the test results

I was able to confirm that the test passed successfully

Additionally, when we actually set the arbitrary value "Beyond Inc." and used the debug function (dd()), we were able to confirm that the intended string was stored in $invalidLoginId

More practical uses

So far, we have written the minimum test code using DataProvider.
However, the above code lacks convenience, so we will also introduce a more practical use.

The following is the changed code:

namespace Tests\Feature; use Tests\TestCase; use Illuminate\Testing\Assert; class DataProviderSampleTest extends TestCase { /** * Login ID string verification test * @param string $loginId Login ID string * @param bool $isEmpty Expected value of empty() * @dataProvider loginIds */ public function testLoginId($loginId, $isEmpty): void { Assert::assertSame($isEmpty, empty($loginId)); } /** * Login ID string test data * * @return array */ public static function loginIds(): array { return [ 'null should be Empty' => [null, true], 'empty string should be Empty' => ['', true], 'testLoginId should not be Empty' => ['testLoginId', false], ]; }

The main changes are as follows:

  1. Specify a key for each element of the test data. (Specifying the test case or value as the key makes it easier to see the execution results. We will attach the execution results later.)
  2. Specify multiple elements in the array (in the above example, the login ID string and the expected value (bool) when the assertion is executed are specified)
  3. Accept multiple values ​​specified by a data provider as arguments to a test method

Check the execution results again

Let's check the test execution results again.

The test passed successfully.
As mentioned earlier, by specifying a key, it is now easier to see which tests passed .
Also, by passing a bool as the expected value, has become more versatile, covering both normal and abnormal cases

Personal impressions

Frankly, I think this is a useful feature for writing DRY code.
I think it's a good way to write simpler and smaller test code, so I'd like to use it in future implementations.

Also, to digress a bit, the reason I started looking into DataProvider this time
was because I had a situation in another language framework where I wanted to "change only the values ​​used in the test and run a loop," which made me think, "Well, PHPUnit must have a similar function...!" It was
a good opportunity to reaffirm how useful it is to expand your arsenal of implementation methods across languages ​​and frameworks.
There are other annotations I haven't used yet, so I'll continue to explore them.

That's all for today's article!
Thank you for reading to the end!
See you next time!

For web system/application development
(service page here)

If you found this article helpful , please give it a like!
4
Loading...
4 votes, average: 1.00 / 14
3,096
X facebook Hatena Bookmark pocket

The person who wrote this article

About the author

Hiroto Fukui

Joined Beyond in June 2020.
He works in the System Development Department (Yokohama office). His work focuses on PHP, developing game APIs and web systems, and developing Shopify private apps.
He likes music in general, mainly Western music, and plays the guitar as a hobby. His favorite TV shows are "Detective! Night Scoop" and "Infestation! Ad Street Heaven."