Тестирование
После каждой правки нужно убедиться, что ничего не сломалось. Проверять сайт руками долго, и что-нибудь обязательно будет забыто. Автоматический тест — это код, который вызывает вашу функцию и сверяет результат с ожидаемым. Сотни таких проверок выполняются за секунды.
Примеры с PHPUnit требуют установленной библиотеки и здесь не запускаются.
Идея теста
Тест состоит из трёх шагов: подготовить данные, выполнить действие, сравнить результат. Это можно сделать и без библиотек:
<?php
function applyDiscount(float $price, int $percent): float
{
return $price * (100 - $percent) / 100;
}
$result = applyDiscount(200, 25);
echo $result === 150.0 ? 'тест пройден' : 'тест не пройден';Библиотека для тестов делает то же самое, но сама находит тесты, запускает их и показывает понятный отчёт.
Установка PHPUnit
PHPUnit — стандартная библиотека для тестов в PHP. Её ставят как зависимость для разработки:
composer require --dev phpunit/phpunitТесты кладут в папку tests, а запускают командой:
vendor/bin/phpunit testsПервый тест
Тест — это класс, который наследует TestCase. Каждый метод с именем на test — отдельная проверка:
<?php
// tests/DiscountTest.php
use PHPUnit\Framework\TestCase;
final class DiscountTest extends TestCase
{
public function testAppliesDiscount(): void
{
$this->assertSame(150.0, applyDiscount(200, 25));
}
public function testZeroDiscountKeepsPrice(): void
{
$this->assertSame(200.0, applyDiscount(200, 0));
}
}assertSame() сравнивает ожидаемое значение с полученным строго — и по значению, и по типу.
Основные проверки
| Метод | Что проверяет |
|---|---|
assertSame($expected, $actual) | Значения равны и одного типа |
assertTrue($value) | Значение равно true |
assertCount(3, $array) | В массиве три элемента |
assertContains('a', $array) | В массиве есть значение |
assertNull($value) | Значение равно null |
Проверка исключений
Нужно проверять и то, что функция правильно отказывает при неверных данных:
<?php
// tests/AccountTest.php
use PHPUnit\Framework\TestCase;
final class AccountTest extends TestCase
{
public function testCannotWithdrawMoreThanBalance(): void
{
$account = new BankAccount();
$account->deposit(100);
$this->expectException(InvalidArgumentException::class);
$account->withdraw(500);
}
}Тест пройдёт, только если после expectException() действительно возникнет исключение указанного типа.
Отчёт
Если проверка не прошла, PHPUnit покажет, в каком тесте и чем ожидаемое отличается от полученного:
There was 1 failure:
1) DiscountTest::testAppliesDiscount
Failed asserting that 160.0 is identical to 150.0.Что тестировать
В первую очередь — код с логикой: расчёты, проверки, преобразование данных. Такой код удобно тестировать, когда функция получает всё нужное через параметры и возвращает результат, а не читает глобальные переменные и не выводит на экран.
Частая ошибка
Тест, который проверяет только «счастливый путь», пропускает главные ошибки. Проверяйте границы: ноль, пустую строку, пустой массив, отрицательное число, слишком большое значение. Именно там код ломается чаще всего.