Когда тестов и файлов с тестами становится много, возникают новые вопросы. Как группировать тесты? Как запустить на выполнение все тесты из одной директории? Если у нас есть много долгих тестов, можно ли запустить их параллельно?
Для решения этих вопросов используют специальные тестовые фреймворки. Они помогают организовать структуру тестов и дают много полезного — например, удобный вывод. С большинством из этих возможностей мы познакомимся далее по курсу. В 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 у себя на GitHub. Соедините удаленный репозиторий с локальным, опираясь на инструкцию GitHub, которая станет доступна сразу после создания репозитория на его странице. Залейте проект на GitHub.
Теперь добавим немного исходного кода. Создайте файл 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
разбирается в курсе по ООП.
Самостоятельная работа
- Выполните все шаги из этого урока
- Залейте код на GitHub
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.