testing php applications
PHPUnit Attributes
PHP attributes provide structured metadata directly on PHP declarations. PHPUnit uses attributes for test discovery, data providers, dependencies, groups, coverage metadata, environment requirements, isolation, and lifecycle hooks.
Prefer Structured Metadata
Attributes are visible to PHP and tooling. Common examples include #[Test], #[DataProvider(...)], #[Group(...)], #[RequiresPhp(...)], and coverage attributes. Use only metadata that clarifies execution or reporting.
Know The Runtime Requirement
PHP attributes were introduced in PHP 8.0. This course targets modern PHP, but legacy projects may still contain older docblock metadata while migrating.
<?php
declare(strict_types=1);
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RequiresPhp;
use PHPUnit\Framework\TestCase;
final class CheckoutTest extends TestCase
{
public static function validOrders(): array
{
return ['free delivery threshold' => [5_000]];
}
#[Group('integration')]
#[RequiresPhp('>= 8.3')]
#[DataProvider('validOrders')]
public function testCheckoutAcceptsValidOrder(int $basketTotalPence): void
{
$this->assertGreaterThan(0, $basketTotalPence);
}
}
Common Mistakes
- Adding metadata that nobody uses.
- Copying obsolete docblock syntax into a modern suite without checking the PHPUnit version.
- Using a bare PHP version in
RequiresPhpwhen a comparison or constraint is intended. - Hiding complicated setup behind attributes without documentation.
What To Practise
- Recognise common PHPUnit attributes.
- Use attributes as structured metadata.
- Check current PHPUnit attribute documentation during migration.
Practice
Practice: Choose Useful PHPUnit Attributes
Select attributes for a test that needs PHP 8.3 or newer, belongs to the integration group, and uses a data provider.
Requirements
- Name each attribute and its purpose.
- Use a version constraint rather than a bare version.
- Keep business assertions inside the test method.
- Check the current PHPUnit manual.
Show solution
The outline separates execution metadata from behaviour.
#[RequiresPhp('>= 8.3')]
#[Group('integration')]
#[DataProvider('validOrders')]
The test method still performs the assertions.
The provider method supplies named order examples.
Import attributes from PHPUnit\Framework\Attributes in a real PHPUnit test.