mardi 23 janvier 2018

How to avoid race conditions with PHP Unit testing

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.

Aucun commentaire:

Enregistrer un commentaire