測試方法可以接受任意參數(shù)。這些參數(shù)由一個或多個數(shù)據(jù)供給器方法(在示例 2.5 中,是 ?additionProvider()
? 方法)提供。用 ?@dataProvider
?標注來指定要使用的數(shù)據(jù)供給器方法。
數(shù)據(jù)供給器方法必須聲明為 ?public
?,其返回值要么是一個數(shù)組,其每個元素也是數(shù)組;要么是一個實現(xiàn)了 ?Iterator
?接口的對象,在對它進行迭代時每步產(chǎn)生一個數(shù)組。每個數(shù)組都是測試數(shù)據(jù)集的一部分,將以它的內(nèi)容作為參數(shù)來調(diào)用測試方法。
示例 2.5 使用返回數(shù)組的數(shù)組的數(shù)據(jù)供給器
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class DataTest extends TestCase
{
/**
* @dataProvider additionProvider
*/
public function testAdd(int $a, int $b, int $expected): void
{
$this->assertSame($expected, $a + $b);
}
public function additionProvider(): array
{
return [
[0, 0, 0],
[0, 1, 1],
[1, 0, 1],
[1, 1, 3]
];
}
}
$ phpunit DataTest
PHPUnit latest.0 by Sebastian Bergmann and contributors.
...F
Time: 0 seconds, Memory: 5.75Mb
There was 1 failure:
1) DataTest::testAdd with data set #3 (1, 1, 3)
Failed asserting that 2 is identical to 3.
/home/sb/DataTest.php:9
FAILURES!
Tests: 4, Assertions: 4, Failures: 1.
當(dāng)使用到大量數(shù)據(jù)集時,最好逐個用字符串鍵名對其命名,避免用默認的數(shù)字鍵名。這樣輸出信息會更加詳細些,其中將包含打斷測試的數(shù)據(jù)集所對應(yīng)的名稱。
示例 2.6 將數(shù)據(jù)供給器與命名數(shù)據(jù)集一起使用
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class DataTest extends TestCase
{
/**
* @dataProvider additionProvider
*/
public function testAdd(int $a, int $b, int $expected): void
{
$this->assertSame($expected, $a + $b);
}
public function additionProvider(): array
{
return [
'adding zeros' => [0, 0, 0],
'zero plus one' => [0, 1, 1],
'one plus zero' => [1, 0, 1],
'one plus one' => [1, 1, 3]
];
}
}
$ phpunit DataTest
PHPUnit latest.0 by Sebastian Bergmann and contributors.
...F
Time: 0 seconds, Memory: 5.75Mb
There was 1 failure:
1) DataTest::testAdd with data set "one plus one" (1, 1, 3)
Failed asserting that 2 is identical to 3.
/home/sb/DataTest.php:9
FAILURES!
Tests: 4, Assertions: 4, Failures: 1.
示例 2.7 使用返回 Iterator 對象的數(shù)據(jù)供給器
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class DataTest extends TestCase
{
/**
* @dataProvider additionProvider
*/
public function testAdd(int $a, int $b, int $expected): void
{
$this->assertSame($expected, $a + $b);
}
public function additionProvider(): CsvFileIterator
{
return new CsvFileIterator('data.csv');
}
}
$ phpunit DataTest
PHPUnit latest.0 by Sebastian Bergmann and contributors.
...F
Time: 0 seconds, Memory: 5.75Mb
There was 1 failure:
1) DataTest::testAdd with data set #3 ('1', '1', '3')
Failed asserting that 2 is identical to 3.
/home/sb/DataTest.php:11
FAILURES!
Tests: 4, Assertions: 4, Failures: 1.
示例 2.8 CsvFileIterator 類
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class CsvFileIterator implements Iterator
{
private $file;
private $key = 0;
private $current;
public function __construct(string $file)
{
$this->file = fopen($file, 'r');
}
public function __destruct()
{
fclose($this->file);
}
public function rewind(): void
{
rewind($this->file);
$this->current = fgetcsv($this->file);
$this->key = 0;
}
public function valid(): bool
{
return !feof($this->file);
}
public function key(): int
{
return $this->key;
}
public function current(): array
{
return $this->current;
}
public function next(): void
{
$this->current = fgetcsv($this->file);
$this->key++;
}
}
如果測試同時從 ?@dataProvider
? 方法和一個或多個 ?@depends
? 測試接收數(shù)據(jù),那么來自于數(shù)據(jù)供給器的參數(shù)將先于來自所依賴的測試的。來自于所依賴的測試的參數(shù)對于每個數(shù)據(jù)集都是一樣的。參見示例 2.9
示例 2.9 在同一個測試中組合 ?@depends
? 和 ?@dataProvider
?
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class DependencyAndDataProviderComboTest extends TestCase
{
public function provider(): array
{
return [['provider1'], ['provider2']];
}
public function testProducerFirst(): void
{
$this->assertTrue(true);
return 'first';
}
public function testProducerSecond(): void
{
$this->assertTrue(true);
return 'second';
}
/**
* @depends testProducerFirst
* @depends testProducerSecond
* @dataProvider provider
*/
public function testConsumer(): void
{
$this->assertSame(
['provider1', 'first', 'second'],
func_get_args()
);
}
}
$ phpunit --verbose DependencyAndDataProviderComboTest
PHPUnit latest.0 by Sebastian Bergmann and contributors.
...F
Time: 0 seconds, Memory: 3.50Mb
There was 1 failure:
1) DependencyAndDataProviderComboTest::testConsumer with data set #1 ('provider2')
Failed asserting that two arrays are identical.
--- Expected
+++ Actual
@@ @@
Array &0 (
- 0 => 'provider1'
+ 0 => 'provider2'
1 => 'first'
2 => 'second'
)
/home/sb/DependencyAndDataProviderComboTest.php:32
FAILURES!
Tests: 4, Assertions: 4, Failures: 1.
示例 2.10 對單個測試使用多個數(shù)據(jù)供給器
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class DataTest extends TestCase
{
/**
* @dataProvider additionWithNonNegativeNumbersProvider
* @dataProvider additionWithNegativeNumbersProvider
*/
public function testAdd(int $a, int $b, int $expected): void
{
$this->assertSame($expected, $a + $b);
}
public function additionWithNonNegativeNumbersProvider(): void
{
return [
[0, 1, 1],
[1, 0, 1],
[1, 1, 3]
];
}
public function additionWithNegativeNumbersProvider(): array
{
return [
[-1, 1, 0],
[-1, -1, -2],
[1, -1, 0]
];
}
}
$ phpunit DataTest
PHPUnit latest.0 by Sebastian Bergmann and contributors.
..F... 6 / 6 (100%)
Time: 0 seconds, Memory: 5.75Mb
There was 1 failure:
1) DataTest::testAdd with data set #3 (1, 1, 3)
Failed asserting that 2 is identical to 3.
/home/sb/DataTest.php:12
FAILURES!
Tests: 6, Assertions: 6, Failures: 1.
如果一個測試依賴于另外一個使用了數(shù)據(jù)供給器的測試,僅當(dāng)被依賴的測試至少能在一組數(shù)據(jù)上成功時,依賴于它的測試才會運行。使用了數(shù)據(jù)供給器的測試,其運行結(jié)果是無法注入到依賴于此測試的其他測試中的。
所有數(shù)據(jù)供給器方法的執(zhí)行都是在對 ?setUpBeforeClass()
? 靜態(tài)方法的調(diào)用和第一次對 ?setUp()
?方法的調(diào)用之前完成的。因此,無法在數(shù)據(jù)供給器中使用創(chuàng)建于這兩個方法內(nèi)的變量。這是必須的,這樣 PHPUnit 才能計算測試的總數(shù)量。
更多建議: