PHPUnit
PHPUnit — фреймворк для написания модульных (единичных) тестов на языке программирования PHP. Является одним из семейств средств для модульного тестирования, построенного на архитектуре xUnit.[2]
Что важно знать
| PHPUnit | |
|---|---|
| Тип | единичное тестирование |
| Написана на | PHP |
| Интерфейс | командная строка |
| Операционная система | кроссплатформенное ПО |
| Языки интерфейса | английский |
| Первый выпуск | 15 марта 2004 |
| Аппаратная платформа | кроссплатформенность |
| Последняя версия |
|
| Репозиторий | github.com/sebastianberg… |
| Лицензия | BSD |
| Сайт | phpunit.de |
Назначение
Модульные тесты являются одним из способов повышения общего качества программного обеспечения. Это наиболее базовый тип тестирования. Они помогают проверить корректность проектирования и выявить ошибки до того, как те проявятся при функциональном тестировании или даже у конечных пользователей. Кроме того, модульные тесты делают приложения более устойчивыми к внесению новых ошибок при последующей доработке или исправлении.
Модульные тесты
Модульные тесты выполняются на уровне отдельных классов и их методов. Целью является проверка того, что все методы класса работают так, как заявлено. При этом задача состоит не только в проверке, что при корректных входных данных метод возвращает ожидаемый правильный результат, но и в том, чтобы на некорректные входные данные возвращался правильный (предусмотренный) ошибочный результат.
В PHPUnit для каждого тестируемого класса должна быть своя тестовая «TestCase», то есть класс-контейнер отдельных тестовых методов. В данном случае PHPUnit вводит определённую неоднозначность в понятии «test case» (тестовый случай, тестовый пример). Обычно под тестовым примером подразумевается один метод, тестирующий определённую функциональность. В PHPUnit тестовым кейсом считается целый набор тестовых методов в одном классе.
TestCase
use PHPUnit\Framework\TestCase;
class UserStoreTest extends TestCase {
public function setUp() {
}
public function tearDown() {
}
public function testGetUser (){
}
// …
}
Каждый класс тестового примера должен наследоваться от класса «PHPUnit\Framework\TestCase», который входит в состав пакета PHPUnit. Название тестового класса должно складываться из названия тестируемого класса и слова «Test». Использование названия класса в имени теста не обязательно, однако это стиль наименования, принятый в рамках PHPUnit, и рекомендуется его соблюдать. Структура классов тестовых примеров также должна отражать структуру тестируемых классов, что позволяет легче ориентироваться между тестами и запускать их, в том числе из командной строки.
Каждый тестовый метод выполняется изолированно от других методов. То есть нельзя вызывать один тестовый метод для подготовки среды к другому методу. Поэтому требуется выделить место для подготовки определённого исходного состояния для одного или нескольких тестовых методов. Для этого используется метод setUp(), который вызывается перед выполнением каждого тестового метода и позволяет создать среду, в которой они будут выполняться.
Этот метод, напротив, вызывается в конце каждого тестового метода и служит для возврата среды тестирования к исходному состоянию.
Используется для выполнения собственно теста. Имя метода должно начинаться с префикса «test», а его объявление не должно содержать входных параметров.
Используются для проверки предположений (assertions). Типичное предположение — метод тестируемого класса возвращает ожидаемое значение. Следующий пример демонстрирует ситуацию, когда метод должен вернуть массив с данными пользователя:
use PHPUnit\Framework\TestCase;
class UserStoreTest extends TestCase {
private $store;
public function setUp() {
$this->store = new UserStore();
}
public function tearDown() {
}
public function testGetUser() {
$this->store->addUser( "bob williams","a@b.com", "12345" );
$user = $this->store->getUser( "a@b.com" );
$this->assertEquals( $user['mail'], "a@b.com");
$this->assertEquals( $user['name'], "bob williams" );
$this->assertEquals( $user['pass'], "12345" );
}
}
Разумеется, метод assertEquals — не единственная поддерживаемая ассертационная функция в PHPUnit. Полный список ассертационных методов представлен в официальной документации.
Проведение тестирования
Запуск модульных тестов осуществляется через командную строку:
$ phpunit UnitTest
UnitTest — это имя класса тестового примера, находящегося в файле UnitTest.php. Тесты можно запускать и массово — вместо имени одного тестового примера указывается путь к папке с наборами тестов.
PHPUnit 4.5.0 by Sebastian Bergmann and contributors.
..
Time: 50 ms, Memory: 4.00Mb
OK (2 tests, 2 assertions)
В данном выводе указано, что успешно проведено 2 теста и 2 проверки (assertions). О прохождении двух тестов и их успешном результате также свидетельствуют две точки, расположенные над временем и потреблённой памятью. Символ «.» обозначает успешное выполнение теста. Тест, завершившийся неудачно, отмечается буквой F. Не только успех и неудача различаются в выводе PHPUnit — перечень всех состояний приведён в таблице:
| Символ | Результат операции |
|---|---|
| . | Успешное выполнение тестового метода |
| F | Ошибка в ассертационном методе внутри теста |
| E | Если во время выполнения теста возникла ошибка |
| R | Если тест помечен как рискованный |
| S | Если тест был пропущен |
| I | Если тест помечен как неполный |
PHPUnit также старается предоставить подробный отчёт о причинах неудачного прохождения тестов:
PHPUnit 4.5.0 by Sebastian Bergmann and contributors.
F.
Time: 60 ms, Memory: 4.00Mb
There was 1 failure:
1) UserStoreTest::testFail
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'sebastian.bergmann@phpunit.de'
+'sebastian@bergmann.phpunit'
\путь\к\тестовому_примеру\UserStoreTest.php:16
FAILURES!
Tests: 2, Assertions: 2, Failures: 1.
Здесь первый тест завершился неудачно из-за несовпадения двух строк. Ожидалось значение 'sebastian.bergmann@phpunit.de', однако фактически был получен 'sebastian@bergmann.phpunit'. Далее указывается путь к тестовому примеру, в котором возникла ошибка.


