velo9
velo9

Reputation: 2335

How do you repeat a test in PHPUnit?

I know about the "--repeat" option, but I'd rather define the repeating within the test and per test. In my unit tests there are tests I don't want to repeat, and there are tests I want to repeat more than others.

I was thinking:

protected function tearDown() {
  if (test has not been ran 3 times) {
      $this->runTest(); // Re-run the test
  }
}

This doesn't seem to work, nor does $this->run(). I've looked at the PHPUnit source code but I'm not sure. I'm guessing it's checking the test status and if it's been ran it denies running it again.

Upvotes: 8

Views: 10886

Answers (7)

Ronald Araújo
Ronald Araújo

Reputation: 1479

If you use terminal fish, you can run

for i in seq(seq 10)                                                                                                                                          
    sail artisan test --filter MyControllerTest
end

Upvotes: 1

Clément Baconnier
Clément Baconnier

Reputation: 6108

As @reusen mentioned, we had the command

phpunit --repeat 3 myTest.php

But this feature has been removed and not planned to be re-implemented. At least, not at the moment.

Currently there's this workaround

while php vendor/bin/phpunit tests/ExampleTest.php --stop-on-failure; do echo; done

Upvotes: 3

reusen
reusen

Reputation: 511

PHPUnit has a repeat option within the command line runner. This works as follows for a test that repeats 3 times:

phpunit --repeat 3 myTest.php

Upvotes: 18

Loupax
Loupax

Reputation: 4934

This is a bit of a roundabout way of doing this but it's the cleanest I could come up with:

/**
 * @dataProvider numberOfTests
 */
public function test()
{
    // Do your test
}

public function numberOfTests() 
{
    for ($i = 0; $i < 100; $i++) {
       yield [];
    }
}

The benefit of this is setUp and tearDown methods will be run for each invocation of the loop.

Upvotes: 6

David Harkness
David Harkness

Reputation: 36562

There's far more to running a test than setUp, run, and tearDown. For one thing, each test method is run against a new instance of the test case. Don't forget about @dataProvider and the other annotations, code coverage, etc. You really don't want to do this.

For the few cases you absolutely need it, code the loop in the test method itself.

Upvotes: 2

Alan
Alan

Reputation: 93

I think you need to take a step back and create a test that runs your tests!

You need a loop that goes something along the lines of:

$myTest = \my\test\class();
foreach($iterations){
    $myTest->setup();
    $myTest->doTestyStuff();
    $myTest->tearDown();
}

the code you posted won't work because each test needs the setup and teardown to be run each time the test runs.

Upvotes: 0

ncremins
ncremins

Reputation: 9200

Can this not be achieved with a do-while loop?

protected function tearDown() {
    $i = 0;
    do {
        $this->runTest(); // Re-run the test
        $i++;
    } while($i < 3);
}

Upvotes: -1

Related Questions