Когда тестов и файлов с тестами становится много, возникают новые вопросы. Как группировать тесты? Как запустить на выполнение все тесты из одной директории? Если их очень много и они долгие, можно ли запустить их параллельно?
Для решения этих вопросов используют специальные тестовые фреймворки. Они помогают организовать структуру тестов и дают много полезного, например, удобный вывод. С большинством из этих возможностей мы познакомимся далее по курсу. В PHP мире наиболее популярен фреймворк PHPUnit. К слову, с помощью него мы тестируем все практики на Хекслете.
Ниже находится инструкция, в которой мы создадим с нуля php-проект и добавим в него тесты.
PHPUnit сильно опирается на работу с классами, которая еще не изучалась. Поэтому по пути повествования будут небольшие вставки-объяснения некоторых моментов. Сильно погружаться в них не нужно, они не влияют на принципы работы с тестами.
Настройка и запуск
Создание каркаса проекта с нуля в PHP довольно утомительное занятие. Поэтому для простоты воспользуемся заготовкой Хекслета. Склонируйте к себе на компьютер репозиторий php-package
git clone git@github.com:hexlet-boilerplates/php-package.git hexlet-phpunit
cd hexlet-phpunit
make install # устанавливаем зависимости
# Удаляем .git чтобы сделать свой репозиторий
rm -rf .git
# Создаем свой репозиторий
git init
git add .
git commit -m 'init hexlet-phpunit project'
Создайте репозиторий hexlet-phpunit у себя на гитхабе. Соедините удаленный репозиторий с локальным опираясь на инструкцию гитхаба. Эта инструкция доступна сразу после создания репозитория на его странице. Залейте проект на гитхаб.
Теперь добавим немного исходного кода. Создайте файл src/Utils.php с таким содержимым:
<?php
namespace Hexlet\Phpunit\Utils;
// Эта функция переворачивает переданную строку
function reverseString($string)
{
return implode(array_reverse(str_split($string)));
}
Добавьте в файл composer.json в секцию autoload
следующий код:
"files": [
"src/Utils.php"
]
После изменения секции autoload
не забудьте запустить команду composer dump-autoload
.
Напишем наш первый тест. Создайте файл tests/UtilsTest.php со следующим содержимым:
<?php
namespace Hexlet\Phpunit\Tests;
use PHPUnit\Framework\TestCase;
use function Hexlet\Phpunit\Utils\reverseString;
// класс UtilsTest наследует класс TestCase
// имя класса совпадает с именем файла
class UtilsTest extends TestCase
{
// Метод, функция определенная внутри класса
// Должна начинаться со слова test
// public – чтобы PHPUnit мог вызвать этот тест снаружи
public function testReverse(): void
{
// Сначала идет ожидаемое значение (expected)
// И только потом актуальное (actual)
$this->assertEquals('', reverseString(''));
$this->assertEquals('olleh', reverseString('hello'));
}
}
Далее мы разберем структуру этого файла, а пока попробуем запустить тест на выполнение:
# или проще: make test
composer exec --verbose phpunit tests
PHPUnit 9.5.0 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 00:00.019, Memory: 6.00 MB
OK (1 test, 2 assertions)
https://replit.com/@hexlet/php-testing-phpunit#tests/UtilsTest.php
Ура! Тесты прошли успешно.
Структура
Давайте еще раз посмотрим на файл с тестом:
<?php
// Тут импорты
class UtilsTest extends TestCase
{
public function testReverse(): void
{
$this->assertEquals('', reverseString(''));
$this->assertEquals('olleh', reverseString('hello'));
}
}
Тест в PHPUnit это класс с именем оканчивающимся на Test и совпадающим с именем файла. Класс пока можно воспринимать как способ объединения функций в одну "упаковку". Функции находящиеся внутри классов называют методами. Методы, в отличие от функций, предваряются ключевым словом public
, только в этом случае их можно вызвать снаружи класса. У тестовых методов имена должны начинаться с префикса "test". Самих тестовых методов может быть сколько угодно. Тестовый фреймворк ищет функции с подобными именами и запускает их на выполнение. Если забыть добавить префикс, то метод не будет вызван. Внутри тестового метода пишется любой код необходимый для тестирования.
Утверждения в PHPUnit не обычные функции, это методы определенные в классе TestCase. Поэтому их вызов идет через синтаксис $this->
. Пока просто запомните его и используйте для вызова утверждений. Подробнее $this
разбирается в курсе по ООП.
Самостоятельная работа
- Выполните все шаги из этого урока
- Залейте код на Гитхаб
Дополнительные материалы

Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Урок «Как эффективно учиться на Хекслете»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.