让我们从证明开始,证明这是我在这里面临的竞争条件:
失败的测试用例 ❌
phpunit --filter testMethod testlass path/to/testFile.php
PHPUnit 5.7.26 by Sebastian Bergmann and contributors.
F 1 / 1 (100%)
You should really fix these slow tests (>500ms)...
1. 6441ms to run testClass::testMethod
Time: 6.49 seconds, Memory: 22.00MB
There was 1 failure:
1) ≈
Unable to find row in database table [orders] that matched attributes
[{"collect_cash":104,"id":1728,"final_total":100}].
Failed asserting that 0 is greater than 0.
project/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithDatabase.php:24
path/to/testFile.php:78
FAILURES!
Tests: 1, Assertions: 2, Failures: 1.
这里是相同的测试运行并成功,没有任何代码更改:
成功的测试用例✅
$ phpunit --filter method class path/to/testFile.php
PHPUnit 5.7.26 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
You should really fix these slow tests (>500ms)...
1. 1631ms to run testClass::testMethod
Time: 1.68 seconds, Memory: 22.00MB
失败发生的地方🤔
失败发生在检查数据库记录的地方:
$this->shopperPut("/some/api/call")
->seeApiSuccess();
$this->seeInDatabase('orders', [
'collect_cash' => $order->final_total + $chargeFare,
'id' => $order->id,
'final_total' => $order->final_total,
在 /some/api/call
中我们这样做
.. some logic
$order->save();
.. more logic
return response()->success(compact('order'));
我尝试过的
我试过放置 sleep 命令.. 但那很老套,会减慢测试速度,而且最重要的是并不总是有效。
我还能做什么?
注意:这个问题不是关于许多开发人员使用同一个数据库。这完全是在我的本地主机上,事实上我使用的是专门为单元测试制作的 testDatabase。
最佳答案
我有这样的测试,没有竞争条件问题。
$response = $this->get('/some/api/call');
$response->assertSessionHas('order');
$this-assertDatabaseHas('orders', [
'collect_cash' => $order->final_total + $chargeFare,
'id' => $order->id,
'final_total' => $order->final_total,
]);
关于php - 如何通过 PHP 单元测试避免竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48403252/