Pull to refresh

PHPUnit+Netbeans

PHP *
Здравствуйте.

Не для кого не секрет, что каждый модуль системы необходимо тестировать прежде чем начать использовать его в реальной системе.

Тем самым уменьшается риск появления новых багов, критический дыр и так далее.

В крупных конторах для этого есть специальные люди, которые занимаются тем, что пишут unit-тесты.

Меньшие конторы, фрилансеры этим грешат, да и на маленьких проектах это не всегда нужно. Согласитесь, если класс на 100 строк, то писать тесты на 200 строк кажется лишней тратой времени.

Тем не менее, не буду вдаваться в подробности кому надо кому нет.

Я хочу показать как можно клево тестировать код на NetBeans с удобным GUI.


Оговорю сразу, это не мануал по всем функциям PHPUnit, тем не менее краткий обзор эта статья даст.

Итак, в среде NetBeans начиная, кажется с 6.7 добавили возможность тестирование кода… Точную версию не помню — посмотрите на сайте бинса.

Создание тест-класса осуществляется в пару кликов.

Но, все по порядку.

Для того чтобы тестировать, нам необходимо:
  1. Собственно NetBeans
  2. PHPUnit
  3. Желание разобраться

Установка PHPUnit


Установка PHPUnit идет через PEAR.

Мануал здесь.


Думаю проблем с этим не будет.

Перейдем к созданию класса, который будем тестировать.


А тестировать мы будем калькулятор. Да-да, классический примерчик.

Итак класс будет иметь вид:
<?php

class calc {
    
    /**
     * Хранит результат последней операции.
     * 
     * @var Double
     */
    protected $last;

    /**
     * Суммирует два числа.
     *
     * @param Double $a
     * @param Double $b
     * @assert (1,2) == 3
     * @assert (10,10) == 20
     * @assert (1,0) == 1
     * @assert (0,0) == 0
     */
    public function sum($a, $b)
    {
        $this->last = $a+$b;
        return $this->getLast();
    }

    /**
     * Делит число $a на число $b
     *
     * @param Double $a
     * @param Double $b
     * @return Double
     * @assert (6,3) == 2
     * @assert (10,5) == 2
     * @assert (15,3) == 5
     * @assert (15,0) == 0
     */
    public function div($a,$b)
    {
        if ( $b==0) throw new Exception("Division by zero");
        $this->last = $a/$b;
        return $this->getLast();
    }

    /**
     * Возвращает результат последней операции
     *
     * @return Double
     */
    public function getLast()
    {
        return $this->last;
    }

    /**
     * Вычитание
     *
     * @param double $a
     * @param double $b
     * @return double
     * @assert (1,2) == -1
     * @assert (10,2) == 8
     * @assert (15,2) == 13
     *
     */
    public function minus($a, $b)
    {
        $this->last = $a-$b;
        if($a<$b) $this->last=0; // Вот такая ошибка у нас будет (!!)
        return $this->getLast();
    }


    /**
     *
     * @param double $a
     * @param double $b
     * @return double
     * @assert (10,20) == 200
     * @assert (1,20) == 20
     * @assert (4,-3) == -12
     * @assert (10,0) == 0
     */
    public function umnojenie($a,$b)
    {

        $this->last = $a*$b;
        if( $this->last == 0 ) $this->last=1; // ОШИБКА
        return $this->getLast();
    }


    /**
     * Возведение в степень
     *
     * @param double $a
     * @param double $b
     * @assert (1,2) == 1
     * @assert (3,2) == 9
     * @assert (10,-1) == 0.1
     * @assert (10,0) == 1
     * @assert (0,0) == 0
     */
    public function power($a, $b)
    {
        $this->last = pow($a,$b);
    }
}
?>

В этом классе у нас описаны операции.
Документированный в стиле phpdoc.

В данном классе допущены специально.
В частности метод pow не возвращает значение. Забыли про return.

Что такое assert ?
assert позволяет заранее обозначит что мы подаем на вход и что хотим получить на выход.
То есть PHPUnit при создании тестируемого класса создаст для каждого такого assert свой тест-функцию.
Удобно — экономим время.

Переходим к созданию тест-класса


Теперь необходимо создать теск-класс.
Среда NetBeans позволяет это сделать в 2 клика(!)


С первого раза у вас спросят куда сохранять класс.
Выберите папку в проекте, у меня например это папка test.
Далее у вас откроется окно с созданным классом.
По сколько использовался assert методов получилось столько сколько на картинке:


Все тестирующие методы имеют префикс «test».
Методы setUp, tearDown вызываются до и после запуска каждого теста!
То есть в них можно подключатся к чему либо или еще что-то делать, в общем все что связано для успешной работы.

Запускаем SHIFT+F6 тест.
Должно получиться нечто как показано на картинке.


Получается каждый тест выполнен и 60% успешных.

Видно, что все тесты power FAILED, потому что нет return.
Исправляем.
    public function power($a, $b)
    {
        $this->last = pow($a,$b);
        return $this->getLast();
    }


Получаем 80% успешных тестов.


Исправляем полученные ошибки.
testDiv4 — выдает Exception который не ловится. Надо в тесте это словить.
Для этого перед методом public function testDiv4
необходимо добавить
@expectedException аннотацию.

то есть мы пишем так:
/**
     * Generated from @assert (15,0) == 0.
     * @expectedException Exception
     */
    public function testDiv4()
    {


        $this->assertEquals(
          0,
          $this->object->div(15,0)
        );
    }


Таким образом мы сообщаем PHPUnit что мы ожидаем Exception.

Далее функция testMinus, напомню мы насильно запретили возвращает ответ меньше 0.
Исправляем это.

Тоже самое делаем с методом umnojenie.
    /**
     * Вычитание
     *
     * @param double $a
     * @param double $b
     * @return double
     * @assert (1,2) == -1
     * @assert (10,2) == 8
     * @assert (15,2) == 13
     *
     */
    public function minus($a, $b)
    {
        $this->last = $a-$b;
        
        return $this->getLast();
    }


    /**
     *
     * @param double $a
     * @param double $b
     * @return double
     * @assert (10,20) == 200
     * @assert (1,20) == 20
     * @assert (4,-3) == -12
     * @assert (10,0) == 0
     */
    public function umnojenie($a,$b)
    {

        $this->last = $a*$b;
      
        return $this->getLast();
    }


то есть теперь должно пройти тест.

Запускаем заново.
После запуска у вас будет 95% PASSED.

Последние 4 процентов уходят на тест testPower5.
Почему? Потому что при написанни assert ошибся
и получилось что pow(0,0)==1 а мы ожидаем 0.
По этому меняем на 1 и запускам.

20 TESTS PASSED.
100% PASSED.

Все отлично!

На последок напишем пример:
5*5+5=30.

public function testClass()
    {
        $this->assertEquals(30, $this->object->sum( $this->object->umnojenie(5, 5), 5));
    }

Запускаем ОК.

Какие еще есть проверки


В данном примере использоваться примитивный assertEquals.
Но есть еще много разных методов.

Вот здесь есть краткое описание на русском: habrahabr.ru/blogs/php/56289

— В след раз будет сделан обзор более сложного примера, работа с бд, файлами.

Статья в моем блоге — anton.in.ua/2009/09/18/phpunit-netbeans

Всем спасибо.
Tags:
Hubs:
Total votes 69: ↑58 and ↓11 +47
Views 9.7K
Comments Comments 40