Testing in PHP: Frameworks and Tools
Quality testing is the foundation of a reliable web application. The PHP ecosystem has developed a powerful set of tools covering all levels: from unit tests to acceptance tests. In this article, we'll break down the main frameworks and libraries that will help you write clean, testable code.
1. PHPUnit — The De Facto Standard
PHPUnit remains the most popular framework for unit testing in PHP. It is included in Symfony, Laravel, and many other projects. Key features:
- Support for assertions — from simple
assertEqualsto complexassertJsonStructure. - Fixtures for preparing and cleaning up data (
setUp(),tearDown()). - Report generation in HTML, XML, Clover formats.
- Integration with CI/CD (GitHub Actions, GitLab CI, Jenkins).
<?phpuse PHPUnit\\Framework\\TestCase;
class CalculatorTest extends TestCase{ public function testAddition() { $calc = new Calculator(); $this->assertEquals(4, $calc->add(2, 2)); }
public function testDivisionByZero() { $this->expectException(\\DivisionByZeroError::class); $calc = new Calculator(); $calc->divide(10, 0); }}2. Mockery — Flexible Stub Creation
Mockery extends PHPUnit's capabilities for creating mock objects. It is convenient when you need to replace a complex service or database.
- Support for partial mocks.
- Verification of method call order (
shouldReceive). - Working with magic methods (
__call,__get).
<?phpuse Mockery as m;
class OrderProcessorTest extends TestCase{ public function testProcess() { $gateway = m::mock(PaymentGateway::class); $gateway->shouldReceive('charge') ->once() ->with(100.0) ->andReturn(true);
$processor = new OrderProcessor($gateway); $this->assertTrue($processor->process(100.0)); }
protected function tearDown(): void { m::close(); }}3. Codeception — All-in-One
Codeception combines unit, functional, and acceptance tests in a single syntax. It is especially popular in web projects where you need to test forms, AJAX requests, and databases.
- Modules for working with PHPBrowser, Selenium, Laravel, Symfony.
- Test generation via CLI:
codecept generate:test. - Support for BDD (Behavior-Driven Development) via Gherkin.
<?php// acceptance.suite.ymlactor: AcceptanceTestermodules: enabled: - WebDriver: url: 'http://localhost' browser: chrome - Laravel5: environment_file: .env.testing
// tests/acceptance/LoginCept.php$I = new AcceptanceTester($scenario);$I->wantTo('see that login form works');$I->amOnPage('/login');$I->fillField('email', 'user@example.com');$I->fillField('password', 'secret');$I->click('Login');$I->see('Dashboard');4. Pest — Minimalist Syntax
Pest is a modern alternative to PHPUnit with a concise syntax, inspired by the JavaScript library Jest. It is ideal for those who value test readability.
- Automatic dependency resolution.
- Assertion chains:
expect($result)->toBeTrue(). - Built-in support for parallel execution.
<?phpuse function Pest\\Faker\\faker;
test('it creates a user', function () { $user = User::factory()->create([ 'name' => faker()->name, 'email' => faker()->email, ]);
expect($u