PHPUnit

PHPUnitфреймворк для написания модульных (единичных) тестов на языке программирования PHP. Является одним из семейств средств для модульного тестирования, построенного на архитектуре xUnit.[2]

Что важно знать

Назначение

Модульные тесты являются одним из способов повышения общего качества программного обеспечения. Это наиболее базовый тип тестирования. Они помогают проверить корректность проектирования и выявить ошибки до того, как те проявятся при функциональном тестировании или даже у конечных пользователей. Кроме того, модульные тесты делают приложения более устойчивыми к внесению новых ошибок при последующей доработке или исправлении.

Модульные тесты

Модульные тесты выполняются на уровне отдельных классов и их методов. Целью является проверка того, что все методы класса работают так, как заявлено. При этом задача состоит не только в проверке, что при корректных входных данных метод возвращает ожидаемый правильный результат, но и в том, чтобы на некорректные входные данные возвращался правильный (предусмотренный) ошибочный результат.

В 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()

Каждый тестовый метод выполняется изолированно от других методов. То есть нельзя вызывать один тестовый метод для подготовки среды к другому методу. Поэтому требуется выделить место для подготовки определённого исходного состояния для одного или нескольких тестовых методов. Для этого используется метод setUp(), который вызывается перед выполнением каждого тестового метода и позволяет создать среду, в которой они будут выполняться.

tearDown()

Этот метод, напротив, вызывается в конце каждого тестового метода и служит для возврата среды тестирования к исходному состоянию.

testМетод()

Используется для выполнения собственно теста. Имя метода должно начинаться с префикса «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'. Далее указывается путь к тестовому примеру, в котором возникла ошибка.

Примечания

Ссылки