Ярлыки

.htaccess (4) тестирование (8) шаблоны проектирования (3) css (5) Debian (6) docker (2) Doctrine2 (6) Git (6) html (4) java (6) javascript (13) jquery (11) LFS (3) linux (23) mac os (4) mod_rewrite (2) MSSQL (4) MySQL (18) ORM Doctrine (17) patterns (3) PDO (3) perl (7) PHP (64) PHPUnit (8) Python (15) SEO (2) Silex (1) SimpleXML (1) SQL (14) ssh (4) Ubuntu (24) Yii1 (1) Zend Framework (19) ZendFramework2 (8)

понедельник, 4 октября 2010 г.

PHPUnit. Помощник инициализации базы данных для PHPUnit (Database helper for PHPUnit)

При тестировании кода, использующего базу данных, обычно мы хотим чтобы структура базы данных не менялась для каждого теста. Таблицы должны быть пустыми, данные должны соответствовать тестам.
Конечно мы можем написать класс, расширяющий ТestCase, который сделает это автоматически при инициализации, в методе setUp, и в конце, в методе tearDown, но уже существует ряд готовых решений.
Например, в Zend Framework и т.д.

Хорошая новость в том, что PHPUnit имеет механизм добавления слушателей, реагирующих на определенные события.

TestListener

 

Мы можем использовать интерфейс TestListener PHPUnit для создания класса - обработчика события, который будет работать до и после выполнения каждого теста. Так как мы используем Doctrine сброс базы данных - это очень простая задача: просто создадим в оперативной памяти SQLite базу данных и позволим Doctrine создать таблицы в ней из классов модели нашего приложения. Закрытие соединения приведет к уничтожению этой базы данных, так как она находится в памяти. Это самый простой вариант.

Теперь, как определить использует ли тестовое задание базу данных? Мы конечно же не заинтересованы в бессмысленной трате ресурсов на реинициализацию базы данных. Хорошим решением будет ввод интерфейса, который будут реализовывать наши тестовые задания и который будет проверятся слушателем.

Простая реализация

 

interface DbTest_Interface
{
}

class DbResetListener implements PHPUnit_Framework_TestListener 
{
    public function startTest(PHPUnit_Framework_Test $test) {
        if($test instanceof DbTest_Interface) {
            Doctrine_Manager::connection(new PDO('sqlite::memory:'));
            Doctrine::createTablesFromModels();
        }
    }
    
    public function endTest(PHPUnit_Framework_Test $test, $time) {
        if($test instanceof DbTest_Interface) {
            Doctrine_Manager::getInstance()
                ->closeConnection(Doctrine_Manager::connection());
        }
    }
    
    //Other methods needed for interface but nothing else
    public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {}
    public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {}
    public function addError(PHPUnit_Framework_Test $test,
        Exception $e, $time) {}
    public function addFailure(PHPUnit_Framework_Test $test, 
            PHPUnit_Framework_AssertionFailedError $e, $time) {}
    public function addIncompleteTest(PHPUnit_Framework_Test $test,
        Exception $e, $time) {}
    public function addSkippedTest(PHPUnit_Framework_Test $test,
        Exception $e, $time) {}
}


Все довольно просто, тестовые задания должны реализовывать интерфейс DbTest_Interface, в противном случае слушатель их проигнорирует.
Чтобы все это использовать мы должны сначала загрузить модель приложения
Doctrine::loadModels('/path/to/models');

И добавить слушатель ...
class AllTests
{
   public static function main()
   {
       $listener = new DbResetListener();
       PHPUnit_TextUI_TestRunner::run(self::suite(), array(
           'listeners' => array($listener)
       ));
   }

   /* other stuff here */
}

оригинал

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

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