[PHPUnit] I tried using DataProvider!

Hello!
This is Fukui from the Systems Development Department!

This time, I'll be using the DataProvider annotation (a convenient mechanism) available in PHPUnit, and I'll explain how to use it, along with the background and reasons why I decided to use it!
*This article will omit an explanation of annotations themselves (what annotations are).

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 information about 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.

, let's say there's a process for checking user information parameters, and "the login ID is required."
Specifically

- Both null and empty strings are rejected as abnormal cases.
- The response parameters are the same (resulting in the same error response).

In this case,
strictly speaking, the test cases are separate, but the only difference needed for testingthe login ID is "null" or an "empty string"is whether
This will be useful when implementing tests like this.

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

Up to this point, we've used DataProvider to write some basic test code.
However, the above code lacks convenience, so I'd like to introduce some more practical ways to use it as well.

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 results again. The

tests passed successfully.
As I mentioned earliereasier to see which tests passedmakes it
Also, by passing a boolean value representing the expected result,more versatile, including both normal and abnormal caseshas become

Personal impressions

Frankly, I found this to be a useful feature for writing DRY code.
I felt it was a good way to write test code more simply and concisely, so I would like to utilize it in future implementations.

Also, and this is a slight digression, the reason I looked into DataProvider this time
was because I encountered a situation in another language's framework where I wanted to "change only the values ​​used in the test and run a loop," and I thought, "Well, PHPUnit must have a similar function...!" This
was a good opportunity to reaffirm how beneficial it is to expand your implementation methods and tools beyond languages ​​and frameworks.
There are still other annotations I haven't touched yet, so I'll continue to try them out.

That concludes this article!
Thank you for reading to the end!
See you next time!

For web system/app development
(service page here)

If you found this article helpful,please give it a "Like"!
4
Loading...
4 votes, average: 1.00 / 14
3,397
X Facebook Hatena Bookmark pocket

The person who wrote this article

About the author

Hiroto Fukui

I joined Beyond in June 2020. I work in the Systems Development Department (Yokohama office).
My work mainly involves PHP, and I am in charge of developing game APIs, web systems, and Shopify private apps.
I like music in general, mainly Western music, and I play the guitar as a hobby. My favorite TV programs are "Detective! Night Scoop" and "Appearance! Admatic Heaven".