How to avoid race conditions with PHP Unit testing

僤鯓⒐⒋嵵緔 提交于 2019-12-12 15:38:29

问题


Let's start from the proof that it's a race condition I'm facing here:

Failed Test Case ❌

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.

here is the same test running and succeeding, without any code changes:

Successful Test Case ✅

$ 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

Where the failure is happening 🤔

the failure happens where where it's checking for a database record:

    $this->shopperPut("/some/api/call")
        ->seeApiSuccess();

    $this->seeInDatabase('orders', [
        'collect_cash'  => $order->final_total + $chargeFare,
        'id'            => $order->id,
        'final_total'   => $order->final_total,

inside the /some/api/call we do this

    .. some logic

    $order->save();

    .. more logic

    return response()->success(compact('order'));

What I have tried

I have tried putting sleep commands.. but that's hacky, slows down the tests, and most importantly doesn't always work.

What else can I do?

note: this question isn't about many developers using the same database.. This is strictly on my localhost and in fact I'm using a testDatabase that's specifically made for unit tests.


回答1:


I've got tests like that working without race condition issues.

$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,
]);

https://laravel.com/docs/5.5/database-testing#introduction



来源:https://stackoverflow.com/questions/48403252/how-to-avoid-race-conditions-with-php-unit-testing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!