我正在越来越深入地进行单元测试。
我遇到的一个问题,这就是我想要反馈的地方,就是当一个人运行多个测试套件时,可能只是我,但我需要使用参数--process-isolation让我的测试通过。我可以单独运行我的任何套件而没有任何问题,但是如果我在没有--process-isolation的情况下运行,那么运行我迄今为止在其中传播的180个断言的6-7套件会失败。问题是使用此参数使测试运行持续35分钟,而通常的2.5分钟。那是一个漫长的等待。
问题与使用模拟DI容器进行特定测试有关,并且当测试套件运行链接时,容器未正确重新初始化。在DI-Container上设置的静态属性用于测试预期的故障,使得以下套件中的测试失败。容器有一个参数,可以将包含的对象保存在静态var中,以便在每次调用时返回相同的实例。伪装的单身人士。这在应用程序级别上运行良好,这对测试来说只是一个麻烦。
我可以避免使用容器参数并将应用程序编码为不使用静态属性,但是为了方法而避免使用有用的语言构造似乎有些过分。
也许我做错了什么(我当然希望如此!)但是如果有人想要在每个测试中以干净状态运行SUT测试,我就会有这样的印象,没有使用--process-isolation。这使得测试非常耗时并且可以稍微消除它的乐趣。我在编码时单独运行套件和测试,并在主要提交之前在后台运行套件,从而绕过了这个问题。
我遇到的是正常情况,有没有办法解决这个问题?你如何测试那里确保测试时间合理?如何处理静力学以免影响测试?
任何见解赞赏/评论赞赏。
答案 0 :(得分:33)
你有几个问题。
首先是流程隔离。通常情况下,它不应该是必要的,您只想使用它来找出哪个特定的测试是致命的测试。正如你自己所说,它非常慢,这是你无法解决的问题。 您可能希望禁用备份全局变量,这会为每次测试节省几毫秒。
导致第一个问题的第二个问题是你的代码不可测试,因为在测试期间保留了静态变量 - 这是我最讨厌的单例问题。
您可以通过在依赖项容器中提供“清理”或“重置”方法来解决该问题。这些将从主测试用例类中的setUp()
方法调用,并将所有内容重置为干净状态。
关于测试的运行时间 - 我最近写了一篇关于找出哪些测试太慢的blog entry。通常,如果在保存文件或在您自己的盒子上进行每次提交后无法运行测试,则测试速度太慢。 10秒对我来说几乎无法接受。你拥有的测试越多,运行它们的速度就越慢。
如果你真的有35分钟,那么将你的测试分成合理的组,这样你就可以在你自己的机器上运行必要的 - 只测试你改变的代码。 Pyrus,下一代PEAR安装程序,具有automatically detect and run the tests that need to be run的漂亮功能,具体取决于您更改的文件。
PHPUnit没有,但您可以手动模拟phpunit --group ..
:)
始终注意模拟Web服务和数据库,或者至少运行数据库,每个测试只包含必要的数据。在验证是否可以将用户保存到数据库的测试中等待3秒的Web服务响应是您不想要的。
答案 1 :(得分:4)
当我使用MySQL而不是SQLite :memory:
进行测试时,我通常会做的一件事是我在Hash::setRounds(5);
内添加tests/CreatesApplication.php
这样的特征。我经历过这将使MySQL的测试速度更快:
public function createApplication()
{
$app = require __DIR__ . '/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
// TODO: DON'T FORGET TO IMPORT HASH OBJECT ON TOP
Hash::setRounds(5);
return $app;
}
答案 2 :(得分:2)
一些技巧;
过滤您的测试用例l例如,如果您想测试onw文件,只需要
phpunit --filter'Default_My_Test'
删除phpunit.xml文件中的代码覆盖率。如果您想获得代码覆盖,请执行以下操作:
phpunit --coverage-html ./report reportTest