2016-12-16 49 views
0

我有一个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方法tests/TestCase.php。但这有两个问题:

  1. 这会导致数据库在每次测试之前迁移,这正是我试图避免的原因。

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

什么是对我最好的方式,以确保为功能测试数据库迁移任何测试运行之前,但只适用于功能测试?

回答

1

您可以创建创建从Laravel的TestCase继承,只有你Functional套件类可以继承新的,在你的新类的基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 = []; 
} 

这个工程即使在内存数据库,它快100倍。 PS:为Laravel工作,而不是Lumen应用。

+0

好主意。我最终创建了一个FunctionalTestCase,只有我的功能测试可以扩展,它负责处理任何数据库设置。谢谢! –

相关问题