如何在内存数据库中使用Laravel中的完整测试套件迁移和播种?

Fra*_*ero 9 php phpunit laravel laravel-5.2

我正在尝试在我的Laravel项目中设置测试环境.我正在使用http://packalyst.com/packages/package/mayconbordin/l5-fixtures与json一起在内存数据库中使用sqlite进行播种并调用:

Artisan::call('migrate');
Artisan::call('db:seed');
Run Code Online (Sandbox Code Playgroud)

在我的setUp函数中,这是在每个测试之前执行的,它可以在这个项目中增长到数千个.

我尝试了setUpBeforeClass,但它没有用.我认为是因为createApplication方法在每次测试中被调用并且重置整个应用程序,并且也没有从json加载灯具可能是出于同样的原因.

Fra*_*ero 9

这是我如何做到这一点以防万一其他人正在努力相同,我创建了一个testClase继承自Laravel的基类,并做到了这一点:

/**
 * Creates the application.
 *
 * @return \Illuminate\Foundation\Application
 */
public function createApplication()
{
    return self::initialize();
}

private static $configurationApp = null;
public static function initialize(){

    if(is_null(self::$configurationApp)){
        $app = require __DIR__.'/../bootstrap/app.php';

        $app->loadEnvironmentFrom('.env.testing');

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

        if (config('database.default') == 'sqlite') {
            $db = app()->make('db');
            $db->connection()->getPdo()->exec("pragma foreign_keys=1");
        }

        Artisan::call('migrate');
        Artisan::call('db:seed');

        self::$configurationApp = $app;
        return $app;
    }

    return self::$configurationApp;
}

public function tearDown()
{
    if ($this->app) {
        foreach ($this->beforeApplicationDestroyedCallbacks as $callback) {
            call_user_func($callback);
        }

    }

    $this->setUpHasRun = false;

    if (property_exists($this, 'serverVariables')) {
        $this->serverVariables = [];
    }

    if (class_exists('Mockery')) {
        Mockery::close();
    }

    $this->afterApplicationCreatedCallbacks = [];
    $this->beforeApplicationDestroyedCallbacks = [];
}
Run Code Online (Sandbox Code Playgroud)

我覆盖了createApplication()tearDown()方法.我更改了第一个使用相同的$app配置并删除了teardown()它冲洗的部分$this->app.

我的测试中的每一个都必须继承这个TestClass,就是这样.

其他一切都不起作用.这甚至可以在内存数据库中使用,速度提高了100倍.

如果您正在处理用户会话,一旦您登录用户,您将不得不将其记录下来,否则用户将登录,因为应用程序环境永远不会重建或者您可以使用这样的东西刷新应用程序每次你想要:

protected static $applicationRefreshed = false;

/**
 * Refresh the application instance.
 *
 * @return void
 */
protected function forceRefreshApplication() {
    if (!is_null($this->app)) {
        $this->app->flush();
    }
    $this->app = null;
    self::$configurationApp = null;
    self::$applicationRefreshed = true;
    parent::refreshApplication();
}
Run Code Online (Sandbox Code Playgroud)

并将此添加到tearDown()之前$this->setUphasRun = false;:

if (self::$applicationRefreshed) {
        self::$applicationRefreshed = false;
        $this->app->flush();
        $this->app = null;
        self::$configurationApp = null;
}
Run Code Online (Sandbox Code Playgroud)