在套件中的每个测试之前运行设置代码

时间:2016-12-16 19:44:21

标签: php laravel unit-testing testing laravel-5

我开发的Laravel 5应用程序有两套测试服:UnitFunctional。我在phpunit.xml

中定义了这些内容
<testsuite name="Unit">
    <directory>./tests/unit</directory>
</testsuite>
<testsuite name="Functional">
    <directory>./tests/functional</directory>
</testsuite>

要使功能测试正确运行,他们需要有一个有效的数据库来对抗。这意味着在运行功能测试之前执行一些设置以迁移数据库。

通常我会在测试中使用DatabaseMigrations特征来确保在每次测试之前迁移数据库。不幸的是,这会大大减慢我们的测试速度(我们有数百个)。我将测试切换为使用DatabaseTransactions特征,这使得它们运行得更快,但现在在运行测试之前不迁移数据库。如果我在项目的新克隆上运行测试套件,它会失败,因为我还没有在运行功能测试套件之前迁移数据库。

明显的解决方案是将$this->artisan('migrate');添加到setUp的{​​{1}}方法中。但这有两个问题:

  1. 这导致在每次测试之前迁移数据库,这是我首先想要避免的。

  2. 这也会在运行单元测试套件时尝试迁移数据库,这显然不太理想。

  3. 对于我来说,最好的方法是确保在运行任何测试之前迁移功能测试的数据库,但仅限于功能测试?

1 个答案:

答案 0 :(得分:1)

您可以创建一个继承自Laravel的TestCase的基础testClase类,只有您的Functional套件类可以继承新的类,并且在您的新类中添加:

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

即使在内存数据库中也能正常工作,它的速度提高了100倍。

PS:为Laravel而不是Lumen应用程序工作。