Skip to content

Commit

Permalink
allowed passing multiple parameters to test methods via data provider
Browse files Browse the repository at this point in the history
this closes #33
  • Loading branch information
konecnyjakub committed Dec 20, 2024
1 parent 9cf6fbe commit d335c23
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 26 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Version 7.0.0+dev
- filename of generated code coverage report is now shown in console (if a report is generated and is saved into a file)
- callbacks in Job::$onAfterExecute receive Job as first parameter
- improved error message for assertion assertCount
- allowed passing multiple parameters to test methods via data provider

Version 7.0.0
- BC break: used interfaces for data provider and skip checker in TestCase
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class Tests extends MyTester\TestCase

#### Parameters for test methods

Test methods of TestCase descendants can take one parameter. You can provide a name of a public method from the class which returns an array with DataProvider attribute. It can be a list of value, in that case the method will be run multiple time, every time with one value from the list. Example:
Test methods of TestCase descendants can take one or more parameters. You can provide a name of a public method from the class which returns an array with DataProvider attribute. It should be an array of arrays. Example:

```php
<?php
Expand All @@ -46,18 +46,24 @@ use MyTester\Attributes\DataProvider;
class Tests extends MyTester\TestCase
{
#[DataProvider("dataProvider")]
public function testParams(string $text): void
public function testParams(string $text, int $number): void
{
$this->assertContains("a", $text);
$this->assertGreaterThan(0, $number);
}

public function dataProvider(): array
{
return ["abc", "def", ];
return [
["abc", 1, ],
["abcd", 2, ],
];
}
}
```

In the example the test method will be run 2 times, first time with parameters "abc" a 1, second time with "abcd" and 2.

#### Custom names for tests

You can give test methods and whole test suites custom names that will be displayed in the output instead of standard NameOfClass::nameOfMethod. It is done via attribute Test/TestSuite. Example:
Expand Down
2 changes: 1 addition & 1 deletion RELEASE_NOTES
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
A new version of My Tester is out.
A new version of My Tester is out. Test methods can now can multiple parameters from data provider.

For complete list of changes since previous version, see CHANGELOG.md.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "7.0.x-dev"
"dev-master": "7.1.x-dev"
}
},
"bin": [
Expand Down
32 changes: 25 additions & 7 deletions src/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,37 @@ function (Job $job): void {
},
],
];

$requiredParameters = (new ReflectionMethod($this, $method))->getNumberOfParameters();
if ($requiredParameters === 0) {
$this->jobs[] = new Job(... $job);
continue;
}

$data = $this->dataProvider->getData($this, $method);
if (count($data) > 0) {
foreach ($data as $value) {
if (count($data) === 0) {
$job["skip"] = "Method requires at least 1 parameter but data provider does not provide any.";
$this->jobs[] = new Job(... $job);
continue;
}

foreach ($data as $value) {
if ($requiredParameters === 1 && !is_array($value)) {
$job["params"][0] = $value;
} elseif (!is_array($value) || count($value) < $requiredParameters) {
$job["skip"] = sprintf(
"Method requires at least %d parameter(s) but data provider provides only %d.",
$requiredParameters,
is_array($value) ? count($value) : 0
);
$this->jobs[] = new Job(... $job);
$job["params"] = [];
}
} else {
$rm = new ReflectionMethod($this, $method);
if ($rm->getNumberOfParameters() > 0) {
$job["skip"] = "Method requires at least 1 parameter but data provider does not provide any.";
break;
} else {
$job["params"] = $value;
}
$this->jobs[] = new Job(... $job);
$job["params"] = [];
}
}
}
Expand Down
72 changes: 58 additions & 14 deletions tests/TestCaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,32 @@ public function testParamsNoneProvided(string $text): void
$this->assertTrue(false);
}

#[DataProviderAttribute("dataProvider")]
public function testParamsNotEnough(string $text, int $number): void
{
$this->assertTrue(false);
}

#[DataProviderAttribute("dataProviderMulti")]
public function testParamsMulti(string $text, int $number): void
{
$this->assertContains("a", $text);
$this->assertGreaterThan(0, $number);
}

public function dataProvider(): array
{
return ["abc", "adef", ];
}

public function dataProviderMulti(): array
{
return [
["abc", 1, ],
["abcd", 2, ],
];
}

/**
* Test custom test's name
*/
Expand Down Expand Up @@ -148,6 +169,8 @@ public function testGetTestMethodsNames(): void
"testState",
"testParams",
"testParamsNoneProvided",
"testParamsNotEnough",
"testParamsMulti",
"testTestName",
"testSkip",
"testSkipPhpVersion",
Expand All @@ -170,7 +193,7 @@ public function testGetTestMethodsNames(): void
public function testGetJobs(): void
{
$jobs = $this->getJobs();
$this->assertCount(18, $jobs);
$this->assertCount(21, $jobs);

$job = $jobs[0];
$this->assertSame("TestCase::testState", $job->name);
Expand Down Expand Up @@ -201,97 +224,118 @@ public function testGetJobs(): void
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[4];
$this->assertSame("TestCase::testParamsNotEnough", $job->name);
$this->assertSame([$this, "testParamsNotEnough", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertSame("Method requires at least 2 parameter(s) but data provider provides only 0.", $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[5];
$this->assertSame("TestCase::testParamsMulti", $job->name);
$this->assertSame([$this, "testParamsMulti", ], $job->callback);
$this->assertSame(["abc", 1, ], $job->params);
$this->assertFalse((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[6];
$this->assertSame("TestCase::testParamsMulti", $job->name);
$this->assertSame([$this, "testParamsMulti", ], $job->callback);
$this->assertSame(["abcd", 2, ], $job->params);
$this->assertFalse((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[7];
$this->assertSame("Custom name", $job->name);
$this->assertSame([$this, "testTestName", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertFalse((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[5];
$job = $jobs[8];
$this->assertSame("Skip", $job->name);
$this->assertSame([$this, "testSkip", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertTrue((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[6];
$job = $jobs[9];
$this->assertSame("PHP version", $job->name);
$this->assertSame([$this, "testSkipPhpVersion", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertTrue((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[7];
$job = $jobs[10];
$this->assertSame("CGI sapi", $job->name);
$this->assertSame([$this, "testCgiSapi", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertTrue((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[8];
$job = $jobs[11];
$this->assertSame("Extension", $job->name);
$this->assertSame([$this, "testSkipExtension", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertTrue((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[9];
$job = $jobs[12];
$this->assertSame("OS family", $job->name);
$this->assertSame([$this, "testSkipOsFamily", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertTrue((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[10];
$job = $jobs[13];
$this->assertSame("No assertions", $job->name);
$this->assertSame([$this, "testNoAssertions", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertFalse((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[11];
$job = $jobs[14];
$this->assertSame("TestCase::testGetSuiteName", $job->name);
$this->assertSame([$this, "testGetSuiteName", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertFalse((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[12];
$job = $jobs[15];
$this->assertSame("TestCase::testGetJobName", $job->name);
$this->assertSame([$this, "testGetJobName", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertFalse((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[13];
$job = $jobs[16];
$this->assertSame("TestCase::testGetTestMethodsNames", $job->name);
$this->assertSame([$this, "testGetTestMethodsNames", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertFalse((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[14];
$job = $jobs[17];
$this->assertSame("TestCase::testGetJobs", $job->name);
$this->assertSame([$this, "testGetJobs", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertFalse((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[15];
$job = $jobs[18];
$this->assertSame("TestCase::testIncomplete", $job->name);
$this->assertSame([$this, "testIncomplete", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertFalse((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[16];
$job = $jobs[19];
$this->assertSame("TestCase::testSkipInside", $job->name);
$this->assertSame([$this, "testSkipInside", ], $job->callback);
$this->assertSame([], $job->params);
$this->assertFalse((bool) $job->skip);
$this->assertCount(1, $job->onAfterExecute);

$job = $jobs[17];
$job = $jobs[20];
$this->assertSame("TestCase::testWhatever", $job->name);
$this->assertSame([$this, "testWhatever", ], $job->callback);
$this->assertSame([], $job->params);
Expand Down

0 comments on commit d335c23

Please sign in to comment.