Data Provider Quick Tips Posted on January 11th, 2017
Data providers are a powerful tool that allows the developer to reuse the same test with different input variables. To add a data provider, in your test case create a public that returns an array of arrays. The values of the inner arrays will be used as function parameters for your tests. In your test's docblock add the dataProvider
annotation with the name of your function as seen below:
/**
* @dataProvider simpleProvider
*/
public function testArraySum(array $input, int $sum)
{
$this->assertEquals($sum, array_sum($input));
}
public function simpleProvider()
{
return [
[[1, 2, 3], 6],
[[4, 5, 6], 15]
[[2, 1], 4]
];
}
This will run through each second level sub array in simpleProvider
passing the elements of the array as function parameters to our test, testArraySum
.
Naming
There are no hard rules when it comes to naming your data providers. However, ending your provider's method name with Provider
makes it easy to identify data providers. It also helps you to think about what kind of values should belong in the provider, e.g.: in validDataProvider
I'd expected to find data points that are valid. This might be useful when testing validation methods.
Named Data Sets
You can add names, array keys, to your array to help identify data sets:
public function responseProvider()
{
return [
'Ok' => [new Response(200)],
'Not Found' => [new Response(404)]
];
}
These keys will be logged when a test fails, which can make it easy to find the failing data set in a large provider.
- TestCase::testOkayReturnsTrueFor200LevelResponses with data set "Not Found" (Response) Failed asserting that false is true.
setUp Gotcha
setUp
is run after the data provider is called. This means that you can't define properties in your setUp
method and then use them in your data provider.
Overuse
Like all tools, it's possible that tests will arise that can be solved with a data provider but you may not want too. I've come up with a simple rule.
Only use data providers when the testing the same result.
Does X
always result in Y
. Does array_sum
always result in the sum of the arrays
? Passing in values which effect the assertions you run is a sign that you may not want a dataProvider. Take the following function:
public function canViewPost($user, $post) {
if ($post->isAuthor($user) || $user->isAdmin() || $user->isEditor()) {
return true;
}
return false;
}
I'd have a dataProvider for the test, testCanViewPostReturnsTrueForValidUsers
and not use a data provider for testCanViewPostReturnsFalseForUsersWithOutPermission
.