Юніт тести в php за допомогою phpUnit (частина друга)

Це продовження статті “Юніт тести в php за допомогою phpUnit (частина перша)“. В першій частині мені подякували за переклад частини мануалу :). Та будь-ласка. Хоча я не вважаю це просто перекладом. Це конспект в якому є як приклади наведені в мануалі, так і мої власні напрацювання. А про TDD як я вже казав можна почитати на agiledev, або на wikipedia, або в спеціалізованій літературі. Я ще не настільки компетентний, щоб писати власні статті про TDD.

“Я не волшебник. Я только учусь.”

Евгений Львович Шварц

setUp() & tearDown()

Ці методи викликаються відповідно перед початком і після виконання кожного тестового методу. Їх використовують для встановлення тестового класу в певний стан. Розглянемо наступний приклад з офіційного мануалу:

<?php
require_once 'PHPUnit/Framework.php';
 
class ArrayTest extends PHPUnit_Framework_TestCase
{
    protected $fixture;
 
    protected function setUp()
    {
        // Create the Array fixture.
        $this->fixture = array();
    }
 
    public function testNewArrayIsEmpty()
    {
        // Assert that the size of the Array fixture is 0.
        $this->assertEquals(0, sizeof($this->fixture));
    }
 
    public function testArrayContainsAnElement()
    {
        // Add an element to the Array fixture.
        $this->fixture[] = 'Element';
 
        // Assert that the size of the Array fixture is 1.
        $this->assertEquals(1, sizeof($this->fixture));
    }
}
?>

Як бачимо в методі setUp() в $this->fixture записується порожній масив. В testNewArrayIsEmpty() перевіряється чи він дійсно порожній, а в testArrayContainsAnElement() до масиву додається один елемент і запускається перевірка на число елементів в масиві. Можна придумати ще кілька тестів в яких будуть виконуватись певні маніпуляції над $this->fixture, але на початку кожного з них $this->fixture буде порожнім масивом.

–help

Команда phpunit –help виведе список додаткових ключів, які можна використовувати для запуску тестів. Нижче я розгляну декілька з них.

–skeleton-test

Ми написали каркас якогось класу. Наприклад такий (взято з слайду “Quality Assurance in PHP Projects“):

<?php
 
class BowlingGame
{
    public function roll($pins)
    {
 
    }
 
    public function score()
    {
        return 0;
    }
}

Якщо запустити phpunit з параметром –skeleton-test:

phpunit --skeleton-test BowlingGame.php

То отпримаємо пусту заготовку BowlingGameTest.php:

<?php
require_once 'PHPUnit/Framework.php';
 
require_once 'BowlingGame.php';
 
/**
 * Test class for BowlingGame.
 * Generated by PHPUnit on 2008-11-15 at 18:34:17.
 */
class BowlingGameTest extends PHPUnit_Framework_TestCase
{
    /**
     * @var    BowlingGame
     * @access protected
     */
    protected $object;
 
    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     *
     * @access protected
     */
    protected function setUp()
    {
        $this->object = new BowlingGame;
    }
 
    /**
     * Tears down the fixture, for example, closes a network connection.
     * This method is called after a test is executed.
     *
     * @access protected
     */
    protected function tearDown()
    {
    }
 
    /**
     * @todo Implement testRoll().
     */
    public function testRoll() {
        // Remove the following lines when you implement this test.
        $this->markTestIncomplete(
          'This test has not been implemented yet.'
        );
    }
 
    /**
     * @todo Implement testScore().
     */
    public function testScore() {
        // Remove the following lines when you implement this test.
        $this->markTestIncomplete(
          'This test has not been implemented yet.'
        );
    }
}
?>

Як бачимо в заготовці є два пустих методи testRoll() і testScore(). Запускаємо тест і бачимо, що в нас є два тести і обидва Incomplete.

phpunit BowlingGameTest.php
PHPUnit 3.3.4 by Sebastian Bergmann.
 
II
 
Time: 0 seconds
 
OK, but incomplete or skipped tests!
Tests: 2, Assertions: 0, Incomplete: 2.

Теоретично, за допомогою команди:

phpunit --skeleton-class BowlingGameTest.php

Можна зробити зворотне перетворення з BowlingGameTest.php в BowlingGame.php. Але в мене чомусь створюється тільки пустий клас BowlingGame…

–testdox

Імена тестових методів повинні говорити самі за себе. Приведу приклад тесту для класу Visitors.php (який рахує відвідувачів):

<?php
require 'Visitors.php';
 
class VisitorsTest extends PHPUnit_Framework_TestCase
{
    protected $visitors;
 
    protected function setup()
    {
        $this->visitors = new Visitors;
    }
 
    public function testCountOfVisitorsIs0()
    {
        $this->assertEquals(0, $this->visitors->count);
    }
}

Подивившись на тестовий метод testCountOfVisitorsIs0() можна зразу зрозуміти, що в ньому відбувається перевірка “чи дорівнює кількість відвідувачів нулю”. А якщо цей тест запустити з ключем –testdox, то отримаємо наступний результат:

phpunit --testdox VisitorsTest
PHPUnit 3.3.4 by Sebastian Bergmann.
 
Visitors
 [x] Count of visitors is 0

Зразу видно, який тест виконався і що в ньому перевіряється.

–filter

Якщо запустити тест з ключем –filter testSomething, то будуть запускатися тільки ті тестові методи в назві яких зустрічається testSomething.

–group

Якщо запустити тест з ключем –group newbag, то будуть запускатися тільки ті тестові методи в докблоках яких є тег @group newbag.

Взагалі я дуже раджу подивитись наступні слайди:

Тут Себастіан наглядно і зрозуміло показує як можна створювати і використовувати юніт тести (всі ці приклади є в мануалі, але слайди дивитися все ж цікавіше).

На сьогодні все. Дякую за увагу.

2 thoughts on “Юніт тести в php за допомогою phpUnit (частина друга)

  1. Stepan ты писал: “А про TDD як я вже казав можна почитати на agiledev, або на wikipedia, або в спеціалізованій літературі. Я ще не настільки компетентний, щоб писати власні статті про TDD.”
    Ну так у тебя же статья раньше называлась: “TDD в php за допомогою phpUnit (основи)”, а теперь “Юніт тести в php за допомогою phpUnit (частина перша)”.
    А что ты ожидал так назвать статью и ничего не писать про TDD, а теперь говоришь, что ты всем все объяснил где им искать TDD и TDD это не твое дело.

  2. Нажаль я стер Ваш попередній коммент. Ви абсолютно праві. Дякую вам за Ваше зауваження я його врахував і змінив назву статті.

Leave a Reply

Your email address will not be published. Required fields are marked *