Загружаем фикстуры в базу данных без тестирования в Yii

1 августа 2011

Введение

Иногда, при работе над каким-нибудь Yii-проектом бывает необходимо по-быстрому загрузить фикстуры без запуска тестов приложения. Тесты, например, могут быть очень тяжелыми и сложными, и, в следствие чего, выполняться будут сравнительно долго, а ждать не хочется. В стандартной поставке Yii возможности загрузить фикстуры без запуска тестов не предусмотрено, но можно самому себе упростить жизнь.

Подготовка

  • скачиваем последнюю актуальную версию ветки 1.* фреймворка;
  • создаем и настраиваем виртуальный хост приложения на локальном веб-сервере;
  • распаковываем содержимое архива фреймворка в document root нового виртуального хоста;
  • генерируем стандартное свежее Yii-приложение, выполнив команду framework\yiic webapp . в document root директории;
  • открываем в браузере наше свежее приложение по ссылке http://domain.com/.

Теперь нужно создать таблицу, в которую мы будет загружать фикстуры:

  • создайте в базе данных таблицу tbl_post с тремя столбцами: id, title, content;
  • установите правильные настройки соединения с базой данных в конфигурационных файлах protected/config/main.php и protected/config/console.php (компонент db в разделе components);
  • включите в конфигурационном файле protected/config/main.php кодогенератор gii и установите пароль на доступ к нему;
  • сгенерируйте модель для таблицы tbl_post при помощи gii, который находится по адресу http://domain.com/index.php?r=gii, а внутри раздел Model Generator.

Фикстуры и их загрузка

Создаем файл с фикстурами tbl_post.php в директории protected/tests/fixtures и пишем туда тестовые данные, которые мы хотим хранить в фикстурах и в будущем загружать в наши таблицы.

return array(
    'post1'=>array(
        'id'=>1,
        'title'=>'First testing post',
        'content'=>'<p>Content</p>',
    ),
    'post2'=>array(
        'id'=>2,
        'title'=>'Второй пост',
        'content'=>'<p>Контент</p>',
    ),
    'post3'=>array(
        'id'=>3,
        'title'=>'3rd post',
        'content'=>'<p>Еще немного контента</p>',
    ),
);

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

'components'=>array(
    // другие компоненты
 
    'fixture'=>array(
        'class'=>'system.test.CDbFixtureManager',
        'basePath'=>dirname(__FILE__).'/../tests/fixtures',
    ),
),

Исходный код консольной команды для работы с базой данных и фикстурами выглядит следующим образом:

// файл protected/commands/DbCommand.php
 
class DbCommand extends CConsoleCommand
{
    public function actionFixture($all=true, $tables='')
    {
        $fm=Yii::app()->fixture;
        $fm->checkIntegrity(false);
 
        // читаем список таблиц из директории с фикстурами
        if($all && !$tables)
        {
            echo 'Loading fixtures for all tables...'."\n";
 
            $handle=opendir($fm->basePath);
            while($file=readdir($handle))
            {
                if($file=='.' || $file=='..')
                    continue;
                $tables.=mb_substr($file, 0, -4).',';
            }
            closedir($handle);
 
            $tables=mb_substr($tables, 0, -1);
        }
        else
            echo 'Loading fixtures for specified tables...'."\n";
 
        // грузим данные в таблицы
        $tableNames=explode(',', $tables);
        foreach($tableNames as $tableName)
        {
            echo $tableName."\n";
            $fm->resetTable($tableName);
            $fm->loadFixture($tableName);
        }
 
        $fm->checkIntegrity(true);
        echo 'Done.';
    }
}

Файл консольной команды должен находиться в директории protected/commands. DbCommand можно расширить на свой вкус различными плюшками. Например, можно добавить действие, которое очищает все или указанные таблицы в базе данных или действие, которое создает дамп всех таблиц базы данных в файл.

Все, осталось только запустить нашу новую команду для работы с фикстурами:

C:\domain.com\www\protected>yiic db fixture
Loading fixtures for all tables...
tbl_post
Done.

C:\domain.com\www\protected>yiic db fixture --all
Loading fixtures for all tables...
tbl_post
Done.

C:\domain.com\www\protected>yiic db fixture --tables=tbl_post
Loading fixtures for specified tables...
tbl_post
Done.

Полноценное приложение-пример со всем исходным кодом из рецепта можно скачать тут.