вторник, 18 октября 2011 г.

Как подружить SimpleTest и lime

Штатный симфонивский unit-testing framework lime, конечно, имеет свои преимущества, но для сложных юнит-тестов он не годится ввиду своей простоты.
Если нужно протестировать, что-то сложное, то тут лучше подходит какой-нибудь более xUnit фреймворк, например SimpleTest или PHPUnit. Я использую SimpleTest (так исторически сложилось). Он работает замечательно, но есть одна проблема. Он не дружит с командой:
./symfony test:unit 
которая запускает все тесты разом.


Очевидным способом решения может быть отказа от данной команды вообще и использование TestSuite для запуска всех тестов.
Так все у меня и работало, пока не начали возникать неуловимые плавающие баги.
Поэтому был выбран второй способ: подружить SimpleTest и lime.

Изучение, кода lime дало понять, что при запуске пресловутой команды «test:unit», для каждого теста делается следующее:
  • Создается временный php файл с хитрым содержанием.
  • При помощи passthru запускается временный файл, который запускает тест и сохраняет результат его работы (сериализоаванный массив) в другой временный файл.
  • Читается фаил с результатами работы теста.
  • Удаляются все созданные временные файлы.
  • Вывод результатов
Самая сложность заключается в сериализованном массиве, который выдает класс lime_test. Чтобы все это работало, мы должны заставить SimpleTest записать результат своей работы в массив правильного формата и передать lime.
Получилось примерно следующее:


// делаем защищенную переменную открытой для записи из вне
class public_morozov_lime_test extends lime_test
{
    public static function setResultArray($array)
    {
        parent::$all_results = $array;
    }
}

class LimeReporter extends TextReporter
{
    protected $lime_test;

    public function __construct()
    {
        $this->lime_test = new lime_test();

        return parent::__construct();
    }

    function paintFooter($test_name) {

        // делаем статиску для лайма
        $lime_result = public_morozov_lime_test::to_array();

        $lime_result[count($lime_result) - 1]['stats']['plan'] = $this->getPassCount() + $this->getFailCount();
        $lime_result[count($lime_result) - 1]['stats']['total'] = $this->getPassCount() + $this->getFailCount();

        $lime_result[count($lime_result) - 1]['stats']['failed'] = $this->makeLimeArray($this->getFailCount());
        $lime_result[count($lime_result) - 1]['stats']['passed'] = $this->makeLimeArray($this->getPassCount());

        public_morozov_lime_test::setResultArray($lime_result);


    }

    protected function makeLimeArray($count)
    {
        $result = array();

        for ($i = 1; $i <= $count; ++$i) $result[] = $i;

        return $result;
    } 


Вызывается в тесте примерно так:

// код теста
.....
// вызов нашего теста
$test = new SomethingTest();
$test->run(new LimeReporter());


В чем соль? При помощи анти-паттерна «Паблик Морозов», мы «ломаем» lime_test, передавая результаты работа тестов на SimpleTest в lime. Как говорится в каждой шутке, есть доля правды.

Комментариев нет:

Отправить комментарий