PHPUnit быстрый старт
PHPUnit — это фреймворк для тестирования кода на PHP.
Установка через composer проста, в корне директории с php скриптами необходимо ыполнить команду:
composer require --dev phpunit/phpunit
При использование автозагрузки классов PSR-4, в composer.json необходимо добавить ключ autoload для указания корневого пространства имен, откуда будут грузится классы:
"autoload-dev": {
"psr-4": {
"MyApp\\": "src/",
"MyApp\\Tests\\": "tests/"
}
}
Если в процессе менялось пространство имен, необходимо изменить его в composer.json и пересобрать:
composer update
Написание тестов
Создаем пример для теста в папке src:
src/Duck.php<?php
namespace MyApp;
class Duck {
public function say(): string {
return 'hmarketing.ru';
}
}
Создаем папку tests, добавляем туда тестируем класс DuckTest.php, по умолчанию PHPUnit смотрит на все файлы, которые заканчиваются на Test.php:
tests/DuckTest.php<?php
namespace MyApp\Tests;
class DuckTest extends \PHPUnit\Framework\TestCase {
public function testSay() {
$krya = new \MyApp\Duck();
$this->assertSame('hmarketing.ru', $krya->say() );
}
}
Запускаем тесты командой, в которую передаем папку с тестами:
vendor/bin/phpunit tests/
Если вы увидели такое сообщение, то все сделано верно:
Фикстуры (Fixture)
Настройка и возврат в исходное состояние, простыми словами есть ряд методов которые включаются автоматически на разных этапах тестов:
tests/DuckTest.php<?php
namespace MyApp\Tests;
class DuckTest extends \PHPUnit\Framework\TestCase {
// выполняются перед каждым тестом тестового класса
protected function setUp() {}
// выполняются после каждого теста тестового класса
protected function tearDown() {}
// выполняется перед первым тестом в тестовом классе
protected function setUpBeforeClass() {}
// выполняется после запуска последнего теста тестового класса
protected function tearDownAfterClass() {}
public function testSay() {
$krya = new \MyApp\Duck();
$this->assertSame('hmarketing.ru', $krya->say() );
}
}
Утверждение (Asserts)
Методы класса TestCase, которые помогают проверить тест. Методов много, все начинаются с assert:
Базовые методы сравнения
assertTrue() / assertFalse()assertEquals() / assertNotEquals()assertGreaterThan()assertGreaterThanOrEqual()assertLessThan()assertLessThanOrEqual()assertNull() / assertNotNull()assertType() / assertNotType()assertSame() / assertNotSame()assertRegExp() / assertNotRegExp()
Методы сравнения массивов
assertArrayHasKey() / assertArrayNotHasKey()assertContains() / assertNotContains()assertContainsOnly() / assertNotContainsOnly()
ООП специфичные методы
assertClassHasAttribute() / assertClassNotHasAttribute()assertClassHasStaticAttribute() / assertClassNotHasStaticAttribute()assertAttributeContains() / assertAttributeNotContains()assertObjectHasAttribute() / assertObjectNotHasAttribute()assertAttributeGreaterThan()assertAttributeGreaterThanOrEqual()assertAttributeLessThan()assertAttributeLessThanOrEqual()
Методы сравнения файлов
assertFileEquals() / assertFileNotEquals()assertFileExists() / assertFileNotExists()assertStringEqualsFile() / assertStringNotEqualsFile()
Методы сравнения XML
assertEqualXMLStructure()assertXmlFileEqualsXmlFile() / assertXmlFileNotEqualsXmlFile()assertXmlStringEqualsXmlFile() / assertXmlStringNotEqualsXmlFile()assertXmlStringEqualsXmlString() / assertXmlStringNotEqualsXmlString()
Разное
assertTag()assertThat()
Заглушки (Stubs, Mocks)
Stub используется для возвращения ложных тестовых данных:
tests/DuckTest.php<?php
class StubTest extends PHPUnit\Framework\TestCase {
public function testStub() {
$headdress = $this->createMock(Headdress::class);
$duck = new Duck( $headdress );
$this->assertSame('foo', $duck->quack() );
}
}
Mock используется для проверки состояния объекта, например, чтобы проверить был ли вызван метод:
tests/DuckTest.phpcreateMock(Headdress::class);
$headdress
// ожидаем, что метод вызовется один раз
->expects( $this->once() )
// указываем, какой метод должен быть вызван
->method( ‘back’ );
$duck = new Duck( $headdress );
$this->assertTrue( $duck->run() );
}
}
В нашем примере мы еще описали, что ожидаем, что Duck при вызове метод run вызовет внутри себя метод back объекта Headdress.
Настройка окружения для тестов (Bootstrap)
Для настройки окружения всех тестов, можно создать файл bootstrap.php и объявить там необходимые данные. Например в этом файле мы можем подключить библиотеки необходимые для тестирования, изменить глобальные переменные, объявить константы и т.д:
bootstrap.phpdefine( 'PLUGIN_PATH', __DIR__ '/../' );
require_once PLUGIN_PATH . '/vendor/autoload.php';
Конфигурационный XML-файл
Мы можем настроить выполнение команд с помощью конфигурационного XML-файла, в котором можно изменить стандартные настройки phpunit, указать папку с тестами, путь к бутстап файлу, настроить фильтры и другое:
phpunit.xml<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./bootstrap.php" colors="true">
<testsuites>
<testsuite name="Config-example-for-tests">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">../../</directory>
<exclude>
<directory>../../src</directory>
<directory>../../tests</directory>
<directory>../../vendor</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
Атрибутами или вложенными тегами, могут быть любые команды, которые есть в phpunit.xml.
Обычный вызов:
vendor/bin/phpunit tests/ --bootsrap /tests/bootsrap.php --colors --test-suffix=".php"
Меняется на:
vendor/bin/phpunit --configuration phpunit.xml
Покрытие тестами (Tests coverage)
С помощью инструмента, очень легко понять насколько качественно написаны тесты, сколько файлов покрыты тестами и какие строки в них покрыты. Данный инструмент очень сильно помогает отслеживать качество ваших тестов.
Необходимо к вашему php-cli подключить xdebug иначе coverage будет недоступен и вы получите уведомление об отсутствии модуля для тестирования.
Для использования, достаточно дописать к phpunit атрибут —coverage-{type}, очень удобно использовать HTML-формат покрытия:
vendor/bin/phpunit tests/ --coverage-html coverage
