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

2022-08-30 22:19:55

我正在尝试在我的Laravel项目中设置测试环境。我正在使用带有json的 http://packalyst.com/packages/package/mayconbordin/l5-fixtures 来在内存数据库中使用sqlite进行种子设定,并调用:

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

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

我尝试了setUpBeforeClass,但它不起作用。我认为这是因为每次测试中都调用了createApplication方法,并且重置了整个应用程序,并且可能出于同样的原因没有从json加载夹具。


答案 1

这就是我这样做的方式,以防其他人也在为同样的事情而苦苦挣扎,我创建了一个从Laravel的基类继承并执行以下操作:testClase

/**
 * 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 = [];
}

我覆盖了 和 方法。我更改了第一个以使用相同的配置,并删除了它冲洗的部分。createApplication()tearDown()$appteardown()$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();
}

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

if (self::$applicationRefreshed) {
        self::$applicationRefreshed = false;
        $this->app->flush();
        $this->app = null;
        self::$configurationApp = null;
}

答案 2

在项目中使用此内容创建文件(也准备带有测试环境变量的文件):testrunner.env.testing

php artisan migrate:rollback --env=testing
php artisan migrate --env=testing --seed
vendor/bin/phpunit

并授予通过命令执行的权限,并通过 .这就是:)chmod +x testrunner./testrunner


推荐