Как падает тест
Каждая проверка в тесте PHPUnit — это утверждение (assertion): assertSame, assertTrue, assertCount и многие другие. То, что происходит после неудачной проверки, определяет, как вы строите тест:
Неудачное утверждение немедленно прерывает свой тестовый метод — строки после него уже не выполняются. На остальные тестовые методы класса это не влияет: каждый из них выполняется и падает сам по себе.
Это даёт вам два инструмента. Помещайте независимые проверки в отдельные методы, чтобы сообщалось о каждой сломанной. Помещайте зависимые проверки одну за другой в один метод, чтобы тест падал сразу на первом сломанном шаге.
Сообщить обо всём: отдельные методы
Когда за один запуск нужно проверить несколько случаев, отведите каждому свой тестовый метод. Сломанный случай приводит к падению только своего метода — остальные методы всё равно выполняются, и перечисляется каждое падение.
Так один запуск PHPUnit показывает вам весь ущерб, а не только первый сломанный случай.
Увидеть все сломанные случаи сразу
Эта функция add игнорирует $b, поэтому все три проверки падают. Так как каждая проверка — это отдельный тестовый метод, все три сообщения о падении появляются в одном запуске; внутри одного метода вы увидели бы только первое.
Вывод: PHP-скрипт
<?php
use PHPUnit\Framework\TestCase;
// В add есть ошибка: она игнорирует $b.
function add(int $a, int $b): int {
return $a;
}
final class AddTest extends TestCase {
public function testAddTwoAndTwo(): void {
$this->assertSame(4, add(2, 2));
}
public function testAddTwoAndThree(): void {
$this->assertSame(5, add(2, 3));
}
public function testAddTenAndOne(): void {
$this->assertSame(11, add(10, 1));
}
}
Падать быстро: утверждения одно за другим
Иногда неудачная проверка означает, что остальная часть теста работать не может. Типичный случай: тест сначала готовит значение, а затем его изучает. Если подготовка уже прошла неверно, изучение было бы бесполезным или даже привело бы к аварии.
Утверждения одно за другим внутри одного метода делают именно это: первое же падение прерывает метод на этом самом месте. Проверки после него не выполняются — и в этом весь смысл.
Остановиться перед бесполезными проверками
В splitWords есть ошибка (она разделяет строку по неверному символу), поэтому возвращается 1 часть вместо 3. assertCount сообщает об этом и прерывает метод — расположенная ниже проверка первой части так и не достигается. Итог это доказывает: Assertions: 1, выполнилось всего одно утверждение.
Вывод: PHP-скрипт
<?php
use PHPUnit\Framework\TestCase;
// В splitWords есть ошибка: она разделяет по ";" вместо ",".
function splitWords(string $s): array {
return explode(";", $s);
}
final class SplitTest extends TestCase {
public function testSplit(): void {
$parts = splitWords("one,two,three");
$this->assertCount(3, $parts);
// Не достигается, пока есть ошибка.
$this->assertSame("one", $parts[0]);
}
}
Сообщения у утверждений
Каждое утверждение принимает необязательный последний аргумент: простое сообщение, которое печатается только тогда, когда проверка падает. $this->assertTrue(isEven(4), "4 should be even") молчит, пока проверка проходит, и объясняет себя, когда она не проходит.
Простые сообщения
Две логические проверки с простыми сообщениями. Здесь обе проходят, поэтому сообщения остаются безмолвными, и запуск печатает OK (1 test, 2 assertions).
Вывод: PHP-скрипт
<?php
use PHPUnit\Framework\TestCase;
function isEven(int $n): bool {
return $n % 2 === 0;
}
final class IsEvenTest extends TestCase {
public function testIsEven(): void {
$this->assertTrue(isEven(4), "4 должно быть чётным");
$this->assertFalse(isEven(3), "3 не должно быть чётным");
}
}