2. Attributes

Attributes are “a form of structured, syntactic metadata to declarations of classes, properties, functions, methods, parameters and constants. Attributes allow to define configuration directives directly embedded with the declaration of that code.”

The attributes supported by PHPUnit are all declared in the PHPUnit\Framework\Attributes namespace. They are documented in this appendix.

Test

Class Level

Method Level

Repeatable

no

yes

no

As an alternative to prefixing your test method names with test, you can use the Test attribute to mark it as a test method.

Example 2.12 Using the Test attribute
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class ExampleTest extends TestCase
{
    #[Test]
    public function it_does_something(): void
    {
        // ...
    }
}

AllowMockObjectsWithoutExpectations

Class Level

Method Level

Repeatable

yes

no

no

The AllowMockObjectsWithoutExpectations attribute can be used to opt out of the check that emits the notice for mock objects without expectations.

DisableReturnValueGenerationForTestDoubles

Class Level

Method Level

Repeatable

yes

no

no

The DisableReturnValueGenerationForTestDoubles attribute can be used to disable the return value generation for test doubles created using createMock(), createMockForIntersectionOfInterfaces(), createPartialMock(), createStub(), and createStubForIntersectionOfInterfaces() for all tests of a test case class.

DoesNotPerformAssertions

Class Level

Method Level

Repeatable

yes

yes

no

By default, PHPUnit considers a test that does not perform assertions and does not configure expectations on mock objects as risky. The DoesNotPerformAssertions attribute can be used to prevent this.

IgnoreDeprecations

Class Level

Method Level

Repeatable

yes

yes

no

The IgnoreDeprecations attribute can be used to configure PHPUnit’s error handler to not emit events for E_DEPRECATED and E_USER_DEPRECATED errors.

WithoutErrorHandler

Class Level

Method Level

Repeatable

no

yes

no

The WithoutErrorHandler attribute can be used to disable PHPUnit’s error handler for a test method.

Warning

Features of PHPUnit that rely on PHPUnit’s error handler to be active while a test method is executed will not work when PHPUnit’s error handler is disabled. No E_(USER_)* errors triggered by PHP will be processed by PHPUnit when its error handler is disabled.

You should only disable PHPUnit’s error handler when it interferes with the code you are testing, for instance when it uses error_get_last() to react to E_(USER_)* errors triggered by PHP.

IgnorePhpunitWarnings

Class Level

Method Level

Repeatable

no

yes

no

The IgnorePhpunitWarnings(null|string $messagePattern = null) attribute can be used to suppress warnings emitted by PHPUnit for a test method. When a $messagePattern is specified, only warnings whose message matches the given regular expression pattern are suppressed.

Code Coverage

CoversClass

Class Level

Method Level

Repeatable

yes

no

yes

The CoversClass(string $className) attribute can be used to specify that a test intends to cover the given class.

CoversClassesThatImplementInterface

Class Level

Method Level

Repeatable

yes

no

yes

The CoversClassesThatImplementInterface(string $interfaceName) attribute can be used to specify that a test intends to cover implementations of the given interface.

CoversClassesThatExtendClass

Class Level

Method Level

Repeatable

yes

no

yes

The CoversClassesThatExtendClass(string $className) attribute can be used to specify that a test intends to cover child classes of the given parent class.

CoversTrait

Class Level

Method Level

Repeatable

yes

no

yes

The CoversTrait(string $traitName) attribute can be used to specify that a test intends to cover the given trait.

CoversMethod

Class Level

Method Level

Repeatable

yes

no

yes

The CoversMethod(string $className, string $methodName) attribute can be used to specify that a test intends to cover the given method.

CoversFunction

Class Level

Method Level

Repeatable

yes

no

yes

The CoversFunction(string $functionName) attribute can be used to specify that a test intends to cover the given function.

CoversNamespace

Class Level

Method Level

Repeatable

yes

no

yes

The CoversNamespace(string $namespace) attribute can be used to specify that a test intends to cover code in the given namespace.

CoversNothing

Class Level

Method Level

Repeatable

yes

yes

no

The CoversNothing() attribute can be used to specify that a test does not intend to contribute to code coverage.

UsesClass

Class Level

Method Level

Repeatable

yes

no

yes

The UsesClass(string $className) attribute can be used to specify that a test allows the execution of code in the given class, but does not intend to cover it. This is relevant in the context of preventing unintentionally covered code.

UsesClassesThatImplementInterface

Class Level

Method Level

Repeatable

yes

no

yes

The UsesClassesThatImplementInterface(string $interfaceName) attribute can be used to specify that a test allows the execution of code in classes that implement the given interface, but does not intend to cover it. This is relevant in the context of preventing unintentionally covered code.

UsesClassesThatExtendClass

Class Level

Method Level

Repeatable

yes

no

yes

The UsesClassesThatExtendClass(string $className) attribute can be used to specify that a test allows the execution of code in child classes that extend the given parent class, but does not intend to cover it. This is relevant in the context of preventing unintentionally covered code.

UsesTrait

Class Level

Method Level

Repeatable

yes

no

yes

The UsesTrait(string $traitName) attribute can be used to specify that a test allows the execution of code in the given trait, but does not intend to cover it. This is relevant in the context of preventing unintentionally covered code.

UsesMethod

Class Level

Method Level

Repeatable

yes

no

yes

The UsesMethod(string $className) attribute can be used to specify that a test allows the execution of code in the given method, but does not intend to cover it. This is relevant in the context of preventing unintentionally covered code.

UsesFunction

Class Level

Method Level

Repeatable

yes

no

yes

The UsesFunction(string $functionName) attribute can be used to specify that a test allows the execution of code in the given global function, but does not intend to cover it. This is relevant in the context of preventing unintentionally covered code.

UsesNamespace

Class Level

Method Level

Repeatable

yes

no

yes

The UsesNamespace(string $namespace) attribute can be used to specify that a test allows the execution of code in the given namespace, but does not intend to cover it. This is relevant in the context of preventing unintentionally covered code.

Data Provider

DataProvider

Class Level

Method Level

Repeatable

no

yes

yes

The DataProvider(string $methodName) attribute can be used on a test method to specify a static method that is declared in the same class as the test method as a data provider.

DataProviderExternal

Class Level

Method Level

Repeatable

no

yes

yes

The DataProviderExternal(string $className, string $methodName) attribute can be used on a test method to specify a static method that is declared in another class as a data provider.

TestWith

Class Level

Method Level

Repeatable

no

yes

yes

The TestWith(array $data) attribute can be used to define a data provider for a test method without having to implement a static data provider method.

Example 2.13 Using the TestWith attribute
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;

final class DataTest extends TestCase
{
    #[TestWith([0, 0, 0])]
    #[TestWith([0, 1, 1])]
    #[TestWith([1, 0, 1])]
    #[TestWith([1, 1, 3])]
    public function testAdd(int $a, int $b, int $expected): void
    {
        $this->assertSame($expected, $a + $b);
    }
}

Running the test shown above yields the output shown below:

./tools/phpunit tests/DataTest.php
PHPUnit 12.5.0 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.2

...F                                                                4 / 4 (100%)

Time: 00:00.058, Memory: 8.00 MB

There was 1 failure:

1) DataTest::testAdd with data set #3
Failed asserting that 2 is identical to 3.

/path/to/DataTest.php:10

FAILURES!
Tests: 4, Assertions: 4, Failures: 1.

TestWithJson

Class Level

Method Level

Repeatable

no

yes

yes

The TestWithJson(string $json) attribute can be used to define a data provider for a test method without having to implement a static data provider method.

Example 2.14 Using the TestWithJson attribute
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\TestWithJson;
use PHPUnit\Framework\TestCase;

final class DataTest extends TestCase
{
    #[TestWithJson('[0, 0, 0]')]
    #[TestWithJson('[0, 1, 1]')]
    #[TestWithJson('[1, 0, 1]')]
    #[TestWithJson('[1, 1, 3]')]
    public function testAdd(int $a, int $b, int $expected): void
    {
        $this->assertSame($expected, $a + $b);
    }
}

Running the test shown above yields the output shown below:

./tools/phpunit tests/DataTest.php
PHPUnit 12.5.0 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.2

...F                                                                4 / 4 (100%)

Time: 00:00.058, Memory: 8.00 MB

There was 1 failure:

1) DataTest::testAdd with data set #3
Failed asserting that 2 is identical to 3.

/path/to/DataTest.php:10

FAILURES!
Tests: 4, Assertions: 4, Failures: 1.

Test Dependencies

Depends

Class Level

Method Level

Repeatable

no

yes

yes

The Depends(string $methodName) attribute can be used to specify that a test depends on another test that is declared in the same test case class.

Any value that is passed from a producer (a depended-upon test) to a consumer (the depending test) is passed without cloning it.

DependsUsingDeepClone

Class Level

Method Level

Repeatable

no

yes

yes

The DependsUsingDeepClone(string $methodName) attribute can be used to specify that a test depends on another test that is declared in the same test case class.

Any value that is passed from a producer (a depended-upon test) to a consumer (the depending test) is passed after deep-cloning it.

DependsUsingShallowClone

Class Level

Method Level

Repeatable

no

yes

yes

The DependsUsingShallowClone(string $methodName) attribute can be used to specify that a test depends on another test that is declared in the same test case class.

Any value that is passed from a producer (a depended-upon test) to a consumer (the depending test) is passed after shallow-cloning it.

DependsExternal

Class Level

Method Level

Repeatable

no

yes

yes

The DependsExternal(string $className, string $methodName) attribute can be used to specify that a test depends on another test that is declared in another test case class.

Any value that is passed from a producer (a depended-upon test) to a consumer (the depending test) is passed without cloning it.

DependsExternalUsingDeepClone

Class Level

Method Level

Repeatable

no

yes

yes

The DependsExternalUsingDeepClone(string $className, string $methodName) attribute can be used to specify that a test depends on another test that is declared in another test case class.

Any value that is passed from a producer (a depended-upon test) to a consumer (the depending test) is passed after deep-cloning it.

DependsExternalUsingShallowClone

Class Level

Method Level

Repeatable

no

yes

yes

The DependsExternalUsingShallowClone(string $className, string $methodName) attribute can be used to specify that a test depends on another test that is declared in another test case class.

Any value that is passed from a producer (a depended-upon test) to a consumer (the depending test) is passed after shallow-cloning it.

DependsOnClass

Class Level

Method Level

Repeatable

no

yes

yes

The DependsOnClass(string $className) attribute can be used to specify that a test depends on all tests of another test case class.

Any value that is passed from a producer (a depended-upon test) to a consumer (the depending test) is passed without cloning it.

DependsOnClassUsingDeepClone

Class Level

Method Level

Repeatable

no

yes

yes

The DependsOnClassUsingDeepClone(string $className) attribute can be used to specify that a test depends on all tests of another test case class.

Any value that is passed from a producer (a depended-upon test) to a consumer (the depending test) is passed after deep-cloning it.

DependsOnClassUsingShallowClone

Class Level

Method Level

Repeatable

no

yes

yes

The DependsOnClassUsingShallowClone(string $className) attribute can be used to specify that a test depends on all tests of another test case class.

Any value that is passed from a producer (a depended-upon test) to a consumer (the depending test) is passed after shallow-cloning it.

TestDox

See TestDox for a detailed discussion of the TestDox functionality.

TestDox

Class Level

Method Level

Repeatable

yes

yes

no

The TestDox(string $text) attribute can be used to customize the text that is printed for a test when TestDox output is enabled.

Example 2.15 Using the TestDox attribute
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;

final class ExampleTest extends TestCase
{
    #[TestDox('It does something')]
    public function testOne(): void
    {
        // ...
    }
}

Running the test shown above with TestDox output enabled yields the output shown below:

$ ./tools/phpunit --no-progress --testdox tests/ExampleTest.php
PHPUnit 12.5.0 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.2

Time: 00:00.057, Memory: 6.00 MB

Example
 ✔ It does something

OK (1 test, 1 assertion)

When you use the TestDox attribute for a test method that uses a data provider then you may use the method parameters as placeholders in your alternative description.

Example 2.16 Using the TestDox attribute together with data providers
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;

final class ExampleTest extends TestCase
{
    #[DataProvider('additionProvider')]
    #[TestDox('Adding $a to $b results in $expected')]
    public function testAdd(int $expected, int $a, int $b)
    {
        $this->assertSame($expected, $a + $b);
    }

    public static function additionProvider()
    {
        return [
            'data set 1' => [0, 0, 0],
            'data set 2' => [1, 0, 1],
            'data set 3' => [1, 1, 0],
            'data set 4' => [3, 1, 1]
        ];
    }
}

Running the test shown above with TestDox output enabled yields the output shown below:

$ ./tools/phpunit --no-progress --testdox tests/ExampleTest.php
PHPUnit 12.5.0 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.2

Time: 00:00.116, Memory: 8.00 MB

Example
 ✔ Adding 0 to 0 results in 0
 ✔ Adding 1 to 0 results in 1
 ✔ Adding 0 to 1 results in 1
 ✘ Adding 1 to 1 results in 3
   │
   │ Failed asserting that 2 is identical to 3.
   │
   │ /path/to/ExampleTest.php:12
   │

FAILURES!
Tests: 4, Assertions: 4, Failures: 1.

Additionally, $_dataName is available and holds the name of the current data. That would be data set 1 through data set 4 in the example shown above.

TestDoxFormatter

Class Level

Method Level

Repeatable

no

yes

no

The TestDoxFormatter(string $methodName) attribute can be used on a test method to specify a static method that is declared in the same class as the test method as a TestDox formatter.

Example 2.17 Using the TestDoxFormatter attribute
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\TestDoxFormatter;
use PHPUnit\Framework\TestCase;

final class ExampleTest extends TestCase
{
    public static function provider(): array
    {
        return [
            [
                new DateTimeImmutable('2025-08-01'),
                new DateTimeImmutable('2025-08-01'),
            ]
        ];
    }

    public static function formatter(DateTimeImmutable $expected, DateTimeImmutable $actual): string
    {
        return sprintf(
            '%s is expected to be %s',
            $actual->format('Y-m-d'),
            $expected->format('Y-m-d'),
        );
    }

    #[DataProvider('provider')]
    #[TestDoxFormatter('formatter')]
    public function testOne(DateTimeImmutable $expected, DateTimeImmutable $actual): void
    {
        $this->assertEquals($expected, $actual);
    }
}

Running the test shown above with TestDox output enabled yields the output shown below:

$ ./tools/phpunit --no-progress --testdox tests/ExampleTest.php
PHPUnit 12.5.0 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.4.10

Time: 00:00.224, Memory: 25.77 MB

Example
 ✔ 2025-08-01 is expected to be 2025-08-01

OK (1 test, 1 assertion)

TestDoxFormatterExternal

Class Level

Method Level

Repeatable

no

yes

no

The TestDoxFormatterExternal(string $className, string $methodName) attribute can be used on a test method to specify a static method that is declared in another class as a TestDox formatter.

Test Groups

Group

Class Level

Method Level

Repeatable

yes

yes

yes

The Group(string $name) attribute can be used to assign tests to test groups.

Groups can be used, for instance, to select which tests should be run.

The strings small, medium, and large may not be used as group names.

Small

Class Level

Method Level

Repeatable

yes

no

no

The Small attribute marks the tests of a test case class as small. These tests are added to a special test group named small that has special semantics.

The size of a test is relevant in the context of test execution timeouts, for instance.

Tests that are marked as small cause the lines of code that they cover to be highlighted by a darker shade of green in the HTML code coverage report compared to tests that are marked medium or large.

Medium

Class Level

Method Level

Repeatable

yes

no

no

The Medium attribute marks the tests of a test case class as medium. These tests are added to a special test group named medium that has special semantics.

The size of a test is relevant in the context of test execution timeouts, for instance.

Tests that are marked as medium cause the lines of code that they cover to be highlighted by a darker shade of green in the HTML code coverage report compared to tests that are marked large and by a lighter shade of green compared to test that are marked small small.

Large

Class Level

Method Level

Repeatable

yes

no

no

The Large attribute marks the tests of a test case class as large. These tests are added to a special test group named large that has special semantics.

The size of a test is relevant in the context of test execution timeouts, for instance.

Tests that are marked as large cause the lines of code that they cover to be highlighted by a lighter shade of green in the HTML code coverage report compared to tests that are marked medium or small.

Ticket

Class Level

Method Level

Repeatable

yes

yes

yes

The Ticket(string $text) attribute is an alias for Group(string $text).

Template Methods

BeforeClass

Class Level

Method Level

Repeatable

no

yes

no

The BeforeClass(int $priority = 0) attribute can be used to specify that a public static method should be invoked before the first test method of a test case class is run. This is the same phase where a method named setUpBeforeClass() would be invoked. We refer to such methods as “before test class” methods.

When a test case class has more than one methods with the BeforeClass attribute then, by default, the test runner assumes that the order in which these methods are invoked does not matter. If this assumption is wrong and the order in which these methods are invoked does matter then the attribute’s optional $priority argument (non-negative integer) can be used to define the desired invocation order: a method with a higher $priority value is invoked before a method with a lower $priority value.

Before

Class Level

Method Level

Repeatable

no

yes

no

The Before(int $priority = 0) attribute can be used to specify that a protected non-static method should be invoked before each test method of a test case class is run. This is the same phase where a method named setUp() would be invoked. We refer to such methods as “before test” methods.

When a test case class has more than one methods with the Before attribute then, by default, the test runner assumes that the order in which these methods are invoked does not matter. If this assumption is wrong and the order in which these methods are invoked does matter then the attribute’s optional $priority argument (non-negative integer) can be used to define the desired invocation order: a method with a higher $priority value is invoked before a method with a lower $priority value.

PreCondition

Class Level

Method Level

Repeatable

no

yes

no

The PreCondition(int $priority = 0) attribute can be used to specify that a protected non-static method should be invoked before each test method (but after any “before test” methods) of a test case class is run. This is the same phase where a method named assertPreConditions() would be invoked. We refer to such methods as “pre-condition” methods.

When a test case class has more than one methods with the PreCondition attribute then, by default, the test runner assumes that the order in which these methods are invoked does not matter. If this assumption is wrong and the order in which these methods are invoked does matter then the attribute’s optional $priority argument (non-negative integer) can be used to define the desired invocation order: a method with a higher $priority value is invoked before a method with a lower $priority value.

PostCondition

Class Level

Method Level

Repeatable

no

yes

no

The PostCondition(int $priority = 0) attribute can be used to specify that a protected non-static method should be invoked after each test method (but before any “after test” methods) of a test case class is run. This is the same phase where a method named assertPostConditions() would be invoked. We refer to such methods as “post-condition” methods.

When a test case class has more than one methods with the PostCondition attribute then, by default, the test runner assumes that the order in which these methods are invoked does not matter. If this assumption is wrong and the order in which these methods are invoked does matter then the attribute’s optional $priority argument (non-negative integer) can be used to define the desired invocation order: a method with a higher $priority value is invoked before a method with a lower $priority value.

After

Class Level

Method Level

Repeatable

no

yes

no

The After(int $priority = 0) attribute can be used to specify that a protected non-static method should be invoked after each test method of a test case class is run. This is the same phase where a method named tearDown() would be invoked. We refer to such methods as “after test” methods.

When a test case class has more than one methods with the After attribute then, by default, the test runner assumes that the order in which these methods are invoked does not matter. If this assumption is wrong and the order in which these methods are invoked does matter then the attribute’s optional $priority argument (non-negative integer) can be used to define the desired invocation order: a method with a higher $priority value is invoked before a method with a lower $priority value.

AfterClass

Class Level

Method Level

Repeatable

no

yes

no

The AfterClass(int $priority = 0) attribute can be used to specify that a public static method should be invoked after the last test method of a test case class is run. This is the same phase where a method named tearDownAfterClass() would be invoked. We refer to such methods as “after test class” methods.

When a test case class has more than one methods with the AfterClass attribute then, by default, the test runner assumes that the order in which these methods are invoked does not matter. If this assumption is wrong and the order in which these methods are invoked does matter then the attribute’s optional $priority argument (non-negative integer) can be used to define the desired invocation order: a method with a higher $priority value is invoked before a method with a lower $priority value.

Test Isolation

BackupGlobals

Class Level

Method Level

Repeatable

yes

yes

no

The BackupGlobals attribute can be used to specify that global and super-global variables should be backed up before a test and then restored after the test has been run.

ExcludeGlobalVariableFromBackup

Class Level

Method Level

Repeatable

yes

yes

yes

The ExcludeGlobalVariableFromBackup($globalVariableName) attribute can be used to exclude the specified global variable from the backup and restore operations for global and super-global variables.

BackupStaticProperties

Class Level

Method Level

Repeatable

yes

yes

no

The BackupStaticProperties attribute can be used to specify that static properties of classes should be backed up before a test and then restored after the test has been run.

ExcludeStaticPropertyFromBackup

Class Level

Method Level

Repeatable

yes

yes

yes

The ExcludeStaticPropertyFromBackup(string $className, string $propertyName) attribute can be used to exclude the specified static property from the backup and restore operations for static properties of classes.

RunInSeparateProcess

Class Level

Method Level

Repeatable

no

yes

no

The RunInSeparateProcess attribute can be used to specify that a test should be run in a separate process.

RunTestsInSeparateProcesses

Class Level

Method Level

Repeatable

yes

no

no

The RunTestsInSeparateProcesses attribute can be used to specify that all tests of a test case class should be run in separate processes (one separate process per test).

RunClassInSeparateProcess

Class Level

Method Level

Repeatable

yes

no

no

The RunClassInSeparateProcess attribute can be used to specify that all tests of a test case class should be run in a (single) separate process.

PreserveGlobalState

Class Level

Method Level

Repeatable

yes

yes

no

The PreserveGlobalState(bool $enabled) attribute can be used to specify whether the global state of the main PHPUnit test runner process should be made available in the child process when a test is run in a separate process.

WithEnvironmentVariable

Class Level

Method Level

Repeatable

yes

yes

yes

The WithEnvironmentVariable(string $environmentVariableName, ?string $value = null) attribute can be used to set an environment variable for the duration of a test. The environment variable is set before before-test methods such as `setUp() are called and restored to its original value after after-test methods such as tearDown() have been called.

When used on a class, the environment variable is set for all tests in that class. When used on a method, it applies only to that test method. A method-level attribute overrides a class-level attribute for the same environment variable.

Example 2.18 Using the WithEnvironmentVariable attribute
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\WithEnvironmentVariable;
use PHPUnit\Framework\TestCase;

#[WithEnvironmentVariable('APP_ENV', 'testing')]
final class EnvironmentTest extends TestCase
{
    public function testAppEnvIsSetFromClassAttribute(): void
    {
        $this->assertSame('testing', $_ENV['APP_ENV']);
        $this->assertSame('testing', getenv('APP_ENV'));
    }

    #[WithEnvironmentVariable('APP_ENV', 'production')]
    public function testAppEnvIsOverriddenByMethodAttribute(): void
    {
        $this->assertSame('production', $_ENV['APP_ENV']);
        $this->assertSame('production', getenv('APP_ENV'));
    }

    #[WithEnvironmentVariable('APP_DEBUG', 'true')]
    public function testAdditionalVariableFromMethodAttribute(): void
    {
        $this->assertSame('testing', $_ENV['APP_ENV']);
        $this->assertSame('true', $_ENV['APP_DEBUG']);
    }
}

When $value is null (or omitted), the environment variable is removed for the duration of the test:

Example 2.19 Removing an environment variable for a test
#[WithEnvironmentVariable('APP_ENV')]
public function testAppEnvIsNotSet(): void
{
    $this->assertFalse(isset($_ENV['APP_ENV']));
    $this->assertFalse(getenv('APP_ENV'));
}

The environment variable is set in both $_ENV and via putenv(), so it is accessible through both $_ENV and getenv(). After the test, the original state is restored.

When multiple WithEnvironmentVariable attributes are specified for the same variable name, the last one wins.

Skipping Tests

The Requires* attributes documented in this section are convenience functionality for replacing custom skip logic in before-class or before-test methods for common cases. For skip logic that goes beyond what these attributes support, use markTestSkipped() in a setUp() or setUpBeforeClass() method (or in a method configured with the #[Before] or #[BeforeClass] attribute).

RequiresPhp

Class Level

Method Level

Repeatable

yes

yes

no

The RequiresPhp(string $versionRequirement) attribute can be used to skip the execution of a test when the PHP version used to run PHPUnit does not match the specified version requirement.

$versionRequirement must be one of the following:

  • A version number string preceded by a comparison operator supported by PHP’s version_compare() function: >=, >, <=, <, ==, or !=

  • A version constraint in the syntax supported by Composer (e.g. ^8.3, ~8.3.0, >=8.3 <8.5)

Here are some examples:

  • #[RequiresPhp('>= 8.3')] — PHP 8.3.0 or newer

  • #[RequiresPhp('^8.3')] — PHP 8.3.0 or newer, but below 9.0.0 (Composer syntax)

  • #[RequiresPhp('~8.3.0')] — PHP 8.3.0 or newer, but below 8.4.0 (Composer syntax)

Always use an operator or Composer constraint syntax

A bare version number without an operator (e.g. '8.3.0') does not mean “8.3.0 or newer”. It is interpreted as an exact version match. This is almost never what you want.

Use of a version requirement without an operator is hard-deprecated and will trigger a deprecation warning. Support for this will be removed in PHPUnit 13.

RequiresPhpExtension

Class Level

Method Level

Repeatable

yes

yes

yes

The RequiresPhpExtension(string $extension[, string $versionRequirement]) attribute can be used to skip the execution of a test when the specified PHP extension is not available. The optional $versionRequirement argument can be used to specify a version requirement for this PHP extension and follows the same format that is described here.

Here are some examples:

  • #[RequiresPhpExtension('mysqli')]

  • #[RequiresPhpExtension('mysqli', '>= 8.3.0')]

  • #[RequiresPhpExtension('mysqli', '^8.3')]

RequiresSetting

Class Level

Method Level

Repeatable

yes

yes

yes

The RequiresSetting(string $setting, string $value) attribute can be used to skip the execution of a test when the specified PHP configuration setting is not set to the expected value.

RequiresPhpunit

Class Level

Method Level

Repeatable

yes

yes

no

The RequiresPhpunit(string $versionRequirement) attribute can be used to skip the execution of a test when the PHPUnit version does not match the specified version requirement.

$versionRequirement follows the same format that is described here.

Here are some examples:

  • #[RequiresPhpunit('>= 10.1.0')]

  • #[RequiresPhpunit('^10.1')]

RequiresPhpunitExtension

Class Level

Method Level

Repeatable

yes

yes

yes

The RequiresPhpunitExtension(string $extensionClass) attribute can be used to skip the execution of a test when the PHPUnit extension identified by its bootstrap class is not available.

RequiresFunction

Class Level

Method Level

Repeatable

yes

yes

yes

The RequiresFunction(string $functionName) attribute can be used to skip the execution of a test when the specified global function is not declared.

RequiresMethod

Class Level

Method Level

Repeatable

yes

yes

yes

The RequiresMethod(string $className, string $methodName) attribute can be used to skip the execution of a test when the specified method is not declared.

RequiresOperatingSystem

Class Level

Method Level

Repeatable

yes

yes

no

The RequiresOperatingSystem(string $regularExpression) attribute can be used to skip the execution of a test when the specified regular expression does not match the value of the PHP_OS constant provided by PHP.

RequiresOperatingSystemFamily

Class Level

Method Level

Repeatable

yes

yes

no

The RequiresOperatingSystemFamily(string $operatingSystemFamily) attribute can be used to skip the execution of a test when the specified string is not identical to the value of the PHP_OS_FAMILY constant provided by PHP.

RequiresEnvironmentVariable

Class Level

Method Level

Repeatable

yes

yes

yes

The RequiresEnvironmentVariable(string $environmentVariableName[, string $value]) attribute can be used to skip the execution of a test when the specified environment variable is not set. Optionally, using the the $value argument, a required value can be specified for the environment variable.