2015-01-03 4 views
3

В настоящее время мы пытаемся установить интеграционные тесты в рамках пакета, который я пишу.Настройка тестов интеграции в пакете laravel

Для тестов интеграции я должен иметь доступ к среде Laravel, чтобы я мог обращаться к вещам, таким как Artisan :: call ('migrate') и обращаться к базе данных.

В настоящее время я предполагаю, что мне нужно, чтобы любые тесты расширяли класс Laravel TestCase, загружая среду Laravel. Хотя я не могу тренироваться, как я могу назвать этот файл в своем пакете.

Во-вторых, при разработке пакетов в верстаке мне нужно будет использовать Artisan :: call ('migrate', '--bench = "vendor/package"') или Artisan :: call ('migrate', '--package = "vendor/package" '), это сбивает с толку.

ответ

7

Нам нужно создать экземпляр Laravel вместе с базой данных, доступной для PHPUnit для запуска тестов с использованием реальных наборов данных. Не хрупкие насмешки. Во-первых, вы должны начинать ваши пакеты в изоляции по целому ряду причин, одна из которых верстак теперь осуждается в Laravel 5.

Итак, во-первых, мы должны dev-require рамки Laravel в наш проект:

"require-dev": { 
    "phpunit/phpunit": "~4.0", 
    "phpspec/phpspec": "~2.1", 
    "laracasts/testdummy": "~2.0", 
    "laravel/laravel": "dev-develop" 
}, 

сейчас мы можем создать абстрактный класс под названием DbTestCase, из которого будут проходить все наши тесты. В этом классе мы будем разворачивать экземпляр Laravel и в памяти База данных SQLite для скорости.

Если мы продлим родной класс Laravel test Illuminate\Foundation\Testing\TestCase, то некоторая работа уже была нами сделана. Нам просто нужно создать метод, который возвращает экземпляр Illuminate\Foundation\Application.

/** 
* Boots the application. 
* 
* @return \Illuminate\Foundation\Application 
*/ 
public function createApplication() 
{ 
    $app = require __DIR__.'/../vendor/laravel/laravel/bootstrap/app.php'; 

    $app->register('Path\To\Your\PackageServiceProvider'); 

    $app->make('Illuminate\Contracts\Console\Kernel')->bootstrap(); 

    return $app;   
} 

Обратите внимание на строку $app->register('Path\To\Your\PackageServiceProvider'); Это важно. Включите здесь путь поставщика пакетов услуг, поэтому мы зарегистрируем его с помощью нашего экземпляра Laravel, который находится в папке /vendor.

Теперь у нас есть приложение Laravel, нам нужно настроить базу данных SQLite в памяти. Простой, Laravel-х TestCase имеет setUp() функцию, выполняемую перед тем когда-либо тест, позволяет сделать это там:

/** 
* Setup DB before each test. 
* 
* @return void 
*/ 
public function setUp() 
{ 
    parent::setUp(); 

    $this->app['config']->set('database.default','sqlite'); 
    $this->app['config']->set('database.connections.sqlite.database', ':memory:'); 

    $this->migrate(); 
} 

Я не буду давать много объяснений, как его вполне читаемым. Как вы можете видеть на последней строке, мы также вызываем $this->migrate(), который, очевидно, выполняет наши миграции каждый раз, когда мы запускаем тест, давая нам новую БД для тестирования. Давайте посмотрим, как это работает:

/** 
* run package database migrations 
* 
* @return void 
*/ 
public function migrate() 
{ 
    $fileSystem = new Filesystem; 
    $classFinder = new ClassFinder; 

    foreach($fileSystem->files(__DIR__ . "/../src/Migrations") as $file) 
    { 
     $fileSystem->requireOnce($file); 
     $migrationClass = $classFinder->findClass($file); 

     (new $migrationClass)->up(); 
    } 
} 

не вдаваться в подробности, в основном то, что мы делаем здесь, смотрит в src/Migrations папку упаковки, требующей все файлы и затем запустить их миграции. Его грубая ситуация и требует больше проверок безопасности (я буду делать это в будущем), но она работает.

Почему бы не Artisan :: call ('migrate') ??

Простой! В Laravel 5 команда php artisan migrate --package='vendor/package' устарела. Теперь ожидается, что разработчики создадут свои собственные команды для создания и перемещения файлов миграции в нужное место в приложении. Это гораздо более гибкий подход.

+1

Я не могу использовать ClassFinder в Laravel 5.4. Есть ли альтернатива этому в 5.4? Я получаю ошибку Class 'Illuminate \ Filesystem \ ClassFinder' не найден –

7

Хотя этот вопрос уже имеет принятый ответ, я настоятельно рекомендую использовать пакет orchestra/testbench.

Добавьте этот пакет в раздел require-dev вашего пакета composer.json и не забудьте расширить любой класс испытаний из TestCase этого пакета, как описано в README.

Этот пакет может загружать пользовательских поставщиков услуг, регистрировать пользовательские псевдонимы и т. Д., А также создавать полную среду Laravel для тестирования.

+0

Хороший ответ, я буду исследовать и, возможно, пометить ваш как правильный – AndrewMcLagan

Смежные вопросы