【问题标题】:How to use parallel testing in multi tenant laravel application?如何在多租户 laravel 应用程序中使用并行测试?
【发布时间】:2021-12-08 08:19:12
【问题描述】:

我正在为多租户 Laravel 8 应用程序使用 Stancl Tenancy。我在单核中进行了很好的测试,但是我想利用 run tests in parallel 的新功能。

我认为明智地这样做我应该为并行化创建的每个数据库创建一个新租户。我一直在尝试使用 ParallelTesting::setUpTestDatabase 回调来做到这一点,但我遇到了一些奇怪的行为。

当我继续并行运行测试时,只有 7 个数据库中的 5 个(并且始终是这个)为它创建了一个租户:

AppServiceProvider

ParallelTesting::setUpTestDatabase(function ($database, $token) {
            $tenant = Tenant::create(['id'=>"testTenant$token",'name'=>"PHPUnit Process $token"]);
});

无需调用创建模型,即可正确设置数据库:

ParallelTesting::setUpTestDatabase(function ($database, $token) {
            //$tenant = Tenant::create(['id'=>"testTenant$token",'name'=>"PHPUnit Process $token"]);
            Log::info("Setup called by $token My database connection is ".DB::connection()->getDatabaseName());
});
[2021-10-21 14:45:32] testing.INFO: Setup called by 4 My database connection is project_test_4
[2021-10-21 14:45:32] testing.INFO: Setup called by 3 My database connection is project_test_3
[2021-10-21 14:45:32] testing.INFO: Setup called by 7 My database connection is project_test_7
[2021-10-21 14:45:32] testing.INFO: Setup called by 6 My database connection is project_test_6
[2021-10-21 14:45:34] testing.INFO: Setup called by 5 My database connection is project_test_5

创建模型的行未注释,没有任何记录,只有最后一个连接 5 获得为其创建的租户。随后的测试似乎使用了正确的连接,因为其中 4/5 的 TenantNotIdentified 测试失败(因为它们没有租户或域)。

谁能发现问题?

【问题讨论】:

  • 将错误直接转储到控制台后,静默失败是由于尝试添加租户时数据库尚未迁移造成的。

标签: laravel laravel-8


【解决方案1】:

setupTestDatabase 回调对此没有帮助,因为数据库尚未迁移。如果满足以下条件,多租户可以与并行测试一起使用(经过大量工作!):

  1. 使用DatabaseTransactions 而不是RefreshDatabbase
  2. 您为租户测试手动处理重新启动数据库事务
  3. 您需要手动进行一些清理工作

注册一个新的服务提供商

class ParallelTestingMultiTenantProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        ParallelTesting::setUpTestCase(function ($token, $testCase) {
            $tenant = Tenant::firstOrCreate(['id' => "test_{$token}_tenant", 'name' => "testTenant$token"]);
            $tenant->domains()->firstOrCreate(['domain'=>"testtenant$token.site.test"]);
        });

        ParallelTesting::tearDownProcess(function ($token) {
            try {
                DB::disconnect();
                config(['database.connections.mysql.database'=>"site_test_{$token}"]);
                DB::reconnect();
                if($tenant = Tenant::find("test_{$token}_tenant")){
                    $tenant->delete();
                }
            }
            catch(\Exception $e){
                if($e->getCode() !== 1049){ //Intercepts database does not exist errors - where tests do not use Database traits
                    throw $e;
                }
            }
        });
    }
}

在你的基础测试类中添加setup()

class TenantTestCase extends TestCase
{
    use DatabaseTransactions;

    public function setUp(): void
    {
        parent::setUp();
        if($this->isTestingInParallel()){
            $token = ParallelTesting::token();
            tenancy()->initialize(Tenant::find("test_{$token}_tenant"));
            DB::beginTransaction(); //Needed as otherwise database transactions don't work on the tenant database
            URL::forceRootUrl("https://testtenant$token.site.test");
        }
        else {
            //Test setup for when not running in parallel 
        }
    }

    protected function tearDown(): void
    {
        if($this->isTestingInParallel()){
            DB::rollBack();
        }
        else {
            //Tear down if not testing in parallel
        }
        parent::tearDown();
    }

    protected function isTestingInParallel() : bool
    {
        return (bool)ParallelTesting::token();
    }
}

这让我能够将整个测试套件的运行时间从 1m 30 缩短到 16s,同时保留了使用上述 if 语句对红绿不并行运行测试的能力。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    • 1970-01-01
    • 2020-06-18
    • 2015-12-30
    • 2011-02-02
    • 1970-01-01
    相关资源
    最近更新 更多