Mock type | Tests duration |
---|---|
Native mocks | 160.10 seconds |
Mockery | 177.01 seconds (+10%) |
PHPUnit mocks | 232.29 seconds (+45%) |
Prophecy | 3868.80 seconds (+2416%) |
Benchmarked on the exact same Windows machine, with PHP 7.3.7, PHPUnit 8.2.5, inside a Docker container, testing consisting on executing the same test 400k times.
I did not show native classes here, as we only focus on PHPUnit's system.
$repo = new class() extends SubscriptionRepository {
public $executions = [];
public function __construct()
{
// Don't call parent constructor in case it needs dependencies
}
public function hasSimilarActiveSubscriptions(Subscription $subscription): bool
{
// Only mock methods that have to be used during the test
$this->executions[] = $subscription;
return true;
}
};
// Tests ...
static::assertCount(1, $repo->executions);
static::assertSame($subscription, $repo->executions[0]);
$repo = Mockery::mock(SubscriptionRepository::class);
$repo
->shouldReceive('hasSimilarActiveSubscriptions')
->with($subscription)
->once()
->andReturn(true)
;
// Tests ...
$repo = $this->createMock(SubscriptionRepository::class);
$repo->expects(static::once())
->method('hasSimilarActiveSubscriptions')
->with($subscription)
->willReturn(true)
;
// Tests ...
$repo = $this->prophesize(SubscriptionRepository::class);
$repo
->hasSimilarActiveSubscriptions($subscription)
->shouldBeCalledOnce()
->willReturn(true)
;
// Don't forget that "$repo" must be injected using "$repo->reveal()"
// Tests ...
I think it is worth mentioning that I could only run Prophecy tests with batches of 25k tests instead of 400k. More was leading to segfaults. Therefore, the time is an average (but significantly slower anyway).
Well on some projects I have hundreds of tests, and if they run in 5 minutes, I'd be perfectly okay for them to be run in 3 minutes instead by giving them a perf boost just by changing the mocking system.
I'm going to open a PR on a personal project on which I have ~400 tests, change all
createMock()
calls to native implementations (if possible) and check the performance differences with the PHPUnit's--repeat=...
option, but this will be in the future when all tests will be refactored 😛