在集成测试中并行PHPUnit测试

hen*_*rkh 14 php phpunit integration-testing unit-testing parallel-testing

随着运行完成PHPUnit套件所需的时间增加,我们的团队开始怀疑是否有可能并行运行单元测试.最近我读了一篇关于Paraunit的文章,Sebastian Bergman也写道,他将在PHPUnit 3.7中添加并行性.

但是,集成测试仍然存在问题,或者更常见的是与DB交互的测试.为了保持一致性,必须重置testDB并在每次测试后加载夹具.但是在并行测试中,竞争条件存在问题,因为所有进程都使用相同的DB.

因此,为了能够并行运行集成测试,我们必须为每个进程分配自己的数据库.我想问一下,如果有人对如何解决这个问题有一些想法.也许在另一个xUnit实现中已经实现了这个问题的解决方案.

在我的团队中,我们使用的是MongoDB,因此一个解决方案是以编程方式为每个PHPUnit进程创建一个配置文件,并生成数据库名称(对于此过程),在setUp()方法中我们可以将主TestDb克隆到此临时数据库中.但在我们开始实施这种方法之前,我想问一下你对这个主题的看法.

Dar*_*ook 6

这是一个好问题:准备并行单元测试将需要学习一些新的最佳实践,我怀疑其中一些会拖慢我们的测试速度。

在最高级别上,建议是:尽可能避免使用数据库进行测试。抽象与数据库的所有交互,然后模拟该类。但是您已经注意到您的问题是关于集成测试的,不可能做到这一点。

使用PDO时,我通常使用sqlite :: memory:每个测试都有自己的数据库。它是匿名的,并在测试结束时自动清除。(但是当您的实际应用程序不使用sqlite时,我注意到了一些问题:使用内存中的sqlite DB加速单元测试时,避免DB deps的建议

当使用没有内存选择的数据库时,请使用随机名称创建数据库。如果并行化是在PHPUnit进程级别进行的,则相当粗糙,您可以使用进程pid。但这与随机名称相比并没有真正的优势。(我知道PHP是单线程的,但是将来可能会有一个自定义的phpUnit模块,该模块使用线程并行运行测试;我们也可以为此做好准备。)

如果您有《 xUnit测试模式》一书,则第13章是关于测试数据库的(相对简短)。关于瞬态和持久夹具的第8章和第9章也很有用。而且,当然,大多数书都位于抽象层上,以使模拟更容易:-)