Один тест, много случаев
Большинству функций нужна одна и та же проверка для многих входных данных: обычные значения, отрицательные значения, ноль, граничные случаи. Если скопировать тест пять раз, получится пять мест, которые придётся поддерживать.
В PHPUnit для этого есть провайдер данных: складываем случаи в одну таблицу — каждая строка содержит имя, входные данные и ожидаемый результат — а исполнитель вызывает один тестовый метод по одному разу на строку.
Добавление нового случая превращается в одну новую строку таблицы. Это самый частый шаблон тестов, который вы встретите в реальном коде на PHPUnit.
Провайдер данных
Провайдер — это метод public static, который возвращает таблицу: массив строк с ключами — именами случаев. Тестовый метод принимает значения строки как параметры и связывается с провайдером через атрибут #[DataProvider('addCases')] (импортируется из PHPUnit\Framework\Attributes).
PHPUnit вызывает метод по одному разу на строку, и каждая строка считается отдельным тестом — сломанная строка падает сама по себе, поэтому видны все сломанные случаи, а не только первый.
Четыре случая в одной таблице
Четыре строки, один тестовый метод, одно утверждение. Все проходят — итог сообщает OK (4 tests, 4 assertions). Чтобы проверить пятую ситуацию, вы добавили бы в таблицу одну строку — метод остался бы нетронутым.
Вывод: PHP-скрипт
<?php
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
function add(int $a, int $b): int {
return $a + $b;
}
final class AddTest extends TestCase {
public static function addCases(): array {
return [
"one plus one" => [1, 1, 2],
"positive and negative" => [5, -3, 2],
"both negative" => [-2, -4, -6],
"zeros" => [0, 0, 0],
];
}
#[DataProvider('addCases')]
public function testAdd(int $a, int $b, int $want): void {
$this->assertSame($want, add($a, $b));
}
}
Именованные случаи с --testdox
--testdox показывает, что сделали строки: каждый случай выводится с именем своего набора данных, например Add with data set "both negative".
Каждая строка проходит или падает сама по себе, поэтому сломанный случай легко заметить в длинной таблице.
У каждого случая есть имя
Та же таблица, запущенная с --testdox. Теперь вывод перечисляет все четыре случая по отдельности — видно точно, какие случаи выполнились и прошли.
Вывод: PHP-скрипт
<?php
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
function add(int $a, int $b): int {
return $a + $b;
}
final class AddTest extends TestCase {
public static function addCases(): array {
return [
"one plus one" => [1, 1, 2],
"positive and negative" => [5, -3, 2],
"both negative" => [-2, -4, -6],
"zeros" => [0, 0, 0],
];
}
#[DataProvider('addCases')]
public function testAdd(int $a, int $b, int $want): void {
$this->assertSame($want, add($a, $b));
}
}
Запуск одного случая отдельно
Случаи можно выбирать из командной строки с помощью --filter, указав имя набора данных в кавычках:
./vendor/bin/phpunit --testdox --filter '"both negative"' AddTest.php
Выполняется только подходящий случай. Это идеально, когда вы исправляете один сломанный случай: перезапускайте только его, пока он не станет зелёным, а затем снова запустите всё.
Фильтр по одному набору данных
Тот же файл, что и выше, запущенный с --filter '"both negative"'. Выполняется только один из четырёх случаев — остальные даже не запускаются: итог сообщает OK (1 test, 1 assertion).
Вывод: PHP-скрипт
<?php
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
function add(int $a, int $b): int {
return $a + $b;
}
final class AddTest extends TestCase {
public static function addCases(): array {
return [
"one plus one" => [1, 1, 2],
"positive and negative" => [5, -3, 2],
"both negative" => [-2, -4, -6],
"zeros" => [0, 0, 0],
];
}
#[DataProvider('addCases')]
public function testAdd(int $a, int $b, int $want): void {
$this->assertSame($want, add($a, $b));
}
}