Laravel phpunit多个数据库测试没有运行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Laravel phpunit多个数据库测试没有运行相关的知识,希望对你有一定的参考价值。

我们有一个多租户设置与一个主要和其他租户数据库,并在运行非sqlite测试时遇到一些问题。数据库是mysql

目前正在尝试对主数据库和一个租户数据库运行测试。模型构造函数中的连接设置如下:

BaseMainModel

$this->connection = config('database.main');

租客基本型号

$this->connection = config('database.tenant');

我观察到以下内容:

使用phpunit.xml中的以下设置在内存数据库中使用sqlite正常运行测试:

<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="APP_DEBUG" value="true"/>
<env name="DB_CONNECTION" value="testing"/>
<env name="DB_CONNECTION_TENANT" value="testing"/>

config.database.connections

    'testing' => [
        'driver' => 'sqlite',
        'database' => ':memory:',
        'prefix' => '',
    ],

但是,当在内存数据库中没有sqlite的情况下运行时(所以在<env name="DB_CONNECTION" value="testing"/><env name="DB_CONNECTION_TENANT" value="testing"/>中注释掉我的两个phpunit行)并在我的普通数据库上运行时,测试在第一次测试后开始挂起。

因此,例如,如果我在文件SomeTests.php中有5个测试,则第一个完成,并且该过程挂起在第二个上。

如果我将protected $connectionsToTransact = ['main', 'tenant'];添加到我的TestCase类,即使第一次测试也没有完成。

另一件需要注意的事情是,我通过创建自己的特性并使用laravel的特性来覆盖refreshTestDatabase()特征的RefreshDatabase方法。我的特点看起来像这样:

trait RefreshDatabase
{
use BaseRefreshDatabase;

/**
 * Refresh the in-memory database.
 *
 * @return void
 */
protected function refreshInMemoryDatabase()
{
    $this->artisan('migrate');

    $path = 'database' . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR . 'tenants';

    Artisan::call('migrate', [
        '--database' => 'testing',
        '--path' => $path
    ]);

    $this->app[Kernel::class]->setArtisan(null);
}

/**
 * Refresh a conventional test database.
 *
 * @return void
 */
protected function refreshTestDatabase()
{
    if (!RefreshDatabaseState::$migrated) {

        $this->artisan('migrate:fresh');

        $path = 'database' . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR . 'tenants';

        $this->artisan('migrate:fresh', [
            '--path' => $path,
            '--database' => config('database.tenant')
        ]);

        $this->app[Kernel::class]->setArtisan(null);

        RefreshDatabaseState::$migrated = true;
    }

    $this->beginDatabaseTransaction();
}
}

我尝试在我的测试的setUp函数中转储:

class RelationsTest extends TestCase
{
use RefreshDatabase;

protected function setUp()
{
    parent::setUp();
    dump("here");  // this is logged
    $this->product = factory(Product::class)->create();
    dump("product created"); // this is not. However I dumped in the model constructors and it did enter the Product constructor
    $this->someClass= factory(SomeClass::class)->create();
    $this->user = factory(User::class)->create();
    $this->otherClass = factory(OtherClass::class)->create();

    $this->yetAnotherClass= factory(YetAnotherClass::class)->create([
        'owner_id' => $this->user->id,
        'product_id' => $this->product->id,
        'someClass_id' => $this->someClass->id,
    ]);
}

有趣的是,如果我单独运行文件中的每个测试,它们运行正常。所以在我不理解的测试之间发生了一些事情!

我觉得它与我的模型连接(或某些东西)有关。因为如果我只使用assertTrue(true)(不使用工厂或触摸数据库)运行两个基本测试,它们运行正常。

非常感谢帮助!谢谢 :)

答案

从php 7.1升级到php 7.2并添加此行

protected $connectionsToTransact = ['tenant'];

我的基本测试用例似乎已经部分解决了这个问题,我可以运行一个测试类。

但是,如果我添加主连接,则测试未运行

protected $connectionsToTransact = ['main', 'tenant'];

如果我运行我的整个测试套件,即使只有protected $connectionsToTransact = ['tenant'];,我也会收到错误“Too many connections”。我认为这是因为main在每次测试后都没有断开连接。

以上是关于Laravel phpunit多个数据库测试没有运行的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 8 中运行多个 PHPUnit 测试时出错

Laravel多个数据库PHPUnit [重复]

PHPUnit 似乎没有运行 Laravel 迁移

Laravel 5:处理多个连接和测试

Laravel / PHPUnit:运行测试时没有模拟类

Laravel 4 phpunit 测试:测试标记为“风险”,因为没有关闭自己的输出缓冲区