PHPUnit9.0 編寫PHPUnit測試-數(shù)據(jù)供給器

2022-03-22 11:05 更新

測試方法可以接受任意參數(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ù)量。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號