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