Генератор каркаса в PHPUnit это утилита, позволяющая создавать каркасы классов тестов исходя из рабочих классов и наоборот. Его можно установить с помощью следующей команды:
pear install phpunit/PHPUnit_SkeletonGenerator
Когда тестируется уже готовый код приходится писать одинаковые фрагменты теста, такие как
public function testMethod() { }
Генератор каркасов PHPUnit может помочь в этом. он создаёт шаблон для класса теста, анализируя код существующего класса .
Пример 16.1. Класс Calculator
<?php class Calculator { public function add($a, $b) { return $a + $b; } } ?>
Следующий пример показывает как создать шаблон тестового класса Calculator
(см. Пример 16.1, «Класс Calculator»).
phpunit-skelgen --test Calculator
PHPUnit Skeleton Generator 1.0.0 by Sebastian Bergmann.
Wrote skeleton for "CalculatorTest" to "/home/sb/CalculatorTest.php".
Для каждого метода исходного класса будут созданы незаконченные (incomplete) тест кейсы (см. Глава 9, Incomplete and Skipped Tests ) в созданном генератором классе.
Когда PHPUnit создает каркас для класса, который объявлен в пространстве имён, необходимо предоставить полное имя класса и путь к файлу исходного класса.
Например, для класса Calculator
, который объявлен в пространстве имён project
следует вызвать генератор каркаса следующим образом:
phpunit-skelgen --test -- "project\Calculator" Calculator.php
PHPUnit Skeleton Generator 1.0.0 by Sebastian Bergmann.
Wrote skeleton for "project\CalculatorTest" to "/home/sb/CalculatorTest.php".
Ниже представлен вывод запуска тестирования для нового созданного класса:
phpunit --bootstrap Calculator.php --verbose CalculatorTest
PHPUnit 3.7.0 by Sebastian Bergmann.
I
Time: 0 seconds, Memory: 3.50Mb
There was 1 incomplete test:
1) CalculatorTest::testAdd
This test has not been implemented yet.
/home/sb/CalculatorTest.php:38
OK, but incomplete or skipped tests!
Tests: 1, Assertions: 0, Incomplete: 1.
Используя аннотацию @assert
в блоке документации исходного метода можно создать простой, но все же работающий тест вместо незавершённого тест кейса. Пример 16.2, «Класс Calculator c аннотациями @assert» показывает пример использования аннотации.
Пример 16.2. Класс Calculator c аннотациями @assert
<?php class Calculator { /** * @assert (0, 0) == 0 * @assert (0, 1) == 1 * @assert (1, 0) == 1 * @assert (1, 1) == 2 */ public function add($a, $b) { return $a + $b; } } ?>
Каждый метод исходного класса проверяется на наличие аннотации @assert
, и они преобразуются в тестовый код, такой как
/** * Generated from @assert (0, 0) == 0. */ public function testAdd() { $o = new Calculator; $this->assertEquals(0, $o->add(0, 0)); }
Ниже представлен пример запуска созданного класса тест кейса.
phpunit --bootstrap Calculator.php --verbose CalculatorTest
PHPUnit 3.7.0 by Sebastian Bergmann.
....
Time: 0 seconds, Memory: 3.50Mb
OK (4 tests, 4 assertions)
Таблица 16.1, «Поддерживаемые варианты аннотации @assert» показывает все возможные варианты аннотации @assert
и то как они преобразуются в код теста.
Таблица 16.1. Поддерживаемые варианты аннотации @assert
Аннотация | Преобразуется в |
---|---|
@assert (...) == X |
assertEquals(X, method(...)) |
@assert (...) != X |
assertNotEquals(X, method(...)) |
@assert (...) === X |
assertSame(X, method(...)) |
@assert (...) !== X |
assertNotSame(X, method(...)) |
@assert (...) > X |
assertGreaterThan(X, method(...)) |
@assert (...) >= X |
assertGreaterThanOrEqual(X, method(...)) |
@assert (...) < X |
assertLessThan(X, method(...)) |
@assert (...) <= X |
assertLessThanOrEqual(X, method(...)) |
@assert (...) throws X |
@expectedException X |
Когда вы используете Test-Driven Development (см. Глава 12, Test-Driven Development ) и пишете тесты перед тем как писать код, который выполняется тестами, PHPUnit может помочь создать каркасы рабочих классов из классов тест кейсов.
Соглашение подразумевает что тесты для класса Unit
реализованы в классе UnitTest
. В этом классе генератор ищет все переменные, которые ссылаются на класс Unit
и анализирует все методы, вызываемые этими объектами. Например, взгляните на код Пример 16.4, «Сгенерированный каркас класса BowlingGame», который был создан при анализе Пример 16.3, «Класс BowlingGameTest».
Пример 16.3. Класс BowlingGameTest
<?php class BowlingGameTest extends PHPUnit_Framework_TestCase { protected $game; protected function setUp() { $this->game = new BowlingGame; } protected function rollMany($n, $pins) { for ($i = 0; $i < $n; $i++) { $this->game->roll($pins); } } public function testScoreForGutterGameIs0() { $this->rollMany(20, 0); $this->assertEquals(0, $this->game->score()); } } ?>
phpunit-skelgen --class BowlingGameTest
PHPUnit Skeleton Generator 1.0.0 by Sebastian Bergmann.
Wrote skeleton for "BowlingGame" to "./BowlingGame.php".
Пример 16.4. Сгенерированный каркас класса BowlingGame
<?php /** * Generated by PHPUnit_SkeletonGenerator on 2012-01-09 at 16:55:58. */ class BowlingGame { /** * @todo Implement roll(). */ public function roll() { // Remove the following line when you implement this method. throw new RuntimeException('Not yet implemented.'); } /** * @todo Implement score(). */ public function score() { // Remove the following line when you implement this method. throw new RuntimeException('Not yet implemented.'); } } ?>
Ниже приведён вывод запуска тестов для созданного класса
phpunit --bootstrap BowlingGame.php BowlingGameTest
PHPUnit 3.7.0 by Sebastian Bergmann.
E
Time: 0 seconds, Memory: 3.50Mb
There was 1 error:
1) BowlingGameTest::testScoreForGutterGameIs0
RuntimeException: Not yet implemented.
/home/sb/BowlingGame.php:13
/home/sb/BowlingGameTest.php:14
/home/sb/BowlingGameTest.php:20
FAILURES!
Tests: 1, Assertions: 0, Errors: 1.