Что такое модульный тест
Модульный тест — это небольшая программа, которая проверяет один фрагмент вашего кода, обычно одну функцию. Тесты запускают после каждого изменения; если изменение что-то ломает, тест сообщает об этом сразу, раньше ваших пользователей.
Стандартный инструмент в мире PHP — PHPUnit. Он устанавливается один раз для проекта с помощью Composer — composer require --dev phpunit/phpunit — и исполняемый файл появляется в проекте по пути ./vendor/bin/phpunit.
Тесты также делают изменения безопасными: с хорошими тестами вы можете переписать функцию и за секунды узнать, ведёт ли она себя по-прежнему.
Файлы, классы и методы тестов
Тест становится тестом благодаря трём правилам именования:
1. Имя файла заканчивается на Test.php — для calc.php вы пишете CalcTest.php. PHPUnit ищет файлы с такими именами.
2. Класс в файле наследует TestCase, базовый класс PHPUnit, который подключается через use PHPUnit\Framework\TestCase;.
3. Имя метода начинается с test — например, testAdd. Методы без этого префикса не запускаются как тесты, поэтому вспомогательные методы могут находиться в том же классе.
Внутри теста вы вызываете функцию и передаёте ожидаемое значение и то, что получили на самом деле, в проверку (assertion) вида $this->assertSame(5, add(2, 3)). Непройденная проверка помечает тест как провалившийся; если провалов нет, тест пройден.
Первый успешный тест
testAdd вызывает add(2, 3) и сравнивает результат с 5 одной проверкой assertSame. Значения совпадают, поэтому ничего не падает и запуск завершается строкой OK (1 test, 1 assertion).
Вывод: PHP-скрипт
<?php
use PHPUnit\Framework\TestCase;
function add(int $a, int $b): int {
return $a + $b;
}
final class AddTest extends TestCase {
public function testAdd(): void {
$this->assertSame(5, add(2, 3));
}
}
Провалившийся тест
В этой функции add есть ошибка — она умножает. Тест это обнаруживает: PHPUnit называет тест AddTest::testAdd, сообщает причину — Failed asserting that 6 is identical to 5. — с файлом и строкой непройденной проверки, и запуск завершается словом FAILURES!
Вывод: PHP-скрипт
<?php
use PHPUnit\Framework\TestCase;
// В add есть ошибка: она умножает вместо сложения.
function add(int $a, int $b): int {
return $a * $b;
}
final class AddTest extends TestCase {
public function testAdd(): void {
$this->assertSame(5, add(2, 3));
}
}
Запуск тестов
./vendor/bin/phpunit AddTest.php запускает все тесты из файла; вызванный без имени файла, PHPUnit запускает весь набор тестов проекта. Вывод по умолчанию краткий: по точке на каждый пройденный тест, F на каждый провал и итоговая строка.
Добавьте --testdox, чтобы получить список всех тестов по именам, каждый на отдельной строке с галочкой под именем класса. Используйте это, чтобы увидеть, что действительно было запущено.
Два теста, перечисленные по именам
В файле два тестовых метода, по одному на каждую проверяемую функцию. С --testdox каждый выводится на отдельной строке под именем класса Calc — видно, что оба запустились и оба прошли, а итоговая строка сообщает OK (2 tests, 2 assertions).
Вывод: PHP-скрипт
<?php
use PHPUnit\Framework\TestCase;
function double(int $n): int {
return $n * 2;
}
function half(int $n): int {
return intdiv($n, 2);
}
final class CalcTest extends TestCase {
public function testDouble(): void {
$this->assertSame(8, double(4));
}
public function testHalf(): void {
$this->assertSame(4, half(8));
}
}