2. Annotations

    Note

    A doc comment in PHP must start with /** and end with */. Annotations in any other style of comment will be ignored.

    This appendix shows all the varieties of annotations supported by PHPUnit.

    The @author annotation is an alias for the @group annotation (see ) and allows to filter tests based on their authors.

    @after

    The @after annotation can be used to specify methods that should be called after each test method in a test case class.

    @afterClass

    The @afterClass annotation can be used to specify static methods that should be called after all test methods in a test class have been run to clean up shared fixtures.

    1. <?php declare(strict_types=1);
    2. use PHPUnit\Framework\TestCase;
    3. final class MyTest extends TestCase
    4. {
    5. /**
    6. * @afterClass
    7. */
    8. public static function tearDownSomeSharedFixtures(): void
    9. {
    10. // ...
    11. }
    12. /**
    13. * @afterClass
    14. */
    15. public static function tearDownSomeOtherSharedFixtures(): void
    16. {
    17. // ...
    18. }
    19. }

    @backupGlobals

    PHPUnit can optionally backup all global and super-global variables before each test and restore this backup after each test.

    The @backupGlobals enabled annotation can be used on the class level to enable this operation for all tests of a test case class:

    1. <?php declare(strict_types=1);
    2. use PHPUnit\Framework\TestCase;
    3. /**
    4. * @backupGlobals enabled
    5. */
    6. final class MyTest extends TestCase
    7. {
    8. // ...
    9. }

    The @backupGlobals annotation can also be used on the test method level. This allows for a fine-grained configuration of the backup and restore operations:

    1. <?php declare(strict_types=1);
    2. use PHPUnit\Framework\TestCase;
    3. /**
    4. * @backupGlobals enabled
    5. */
    6. final class MyTest extends TestCase
    7. {
    8. public function testThatInteractsWithGlobalVariables()
    9. {
    10. // ...
    11. }
    12. /**
    13. * @backupGlobals disabled
    14. */
    15. public function testThatDoesNotInteractWithGlobalVariables(): void
    16. {
    17. // ...
    18. }
    19. }

    @backupStaticAttributes

    PHPUnit can optionally backup all static attributes in all declared classes before each test and restore this backup after each test.

    The @backupStaticAttributes enabled annotation can be used on the class level to enable this operation for all tests of a test case class:

    1. <?php declare(strict_types=1);
    2. use PHPUnit\Framework\TestCase;
    3. /**
    4. * @backupStaticAttributes enabled
    5. */
    6. {
    7. // ...
    8. }

    The @backupStaticAttributes annotation can also be used on the test method level. This allows for a fine-grained configuration of the backup and restore operations:

    1. use PHPUnit\Framework\TestCase;
    2. /**
    3. * @backupStaticAttributes enabled
    4. */
    5. class MyTest extends TestCase
    6. {
    7. public function testThatInteractsWithStaticAttributes(): void
    8. {
    9. // ...
    10. }
    11. /**
    12. * @backupStaticAttributes disabled
    13. */
    14. public function testThatDoesNotInteractWithStaticAttributes(): void
    15. {
    16. // ...
    17. }
    18. }

    Note

    @backupStaticAttributes is limited by PHP internals and may cause unintended static values to persist and leak into subsequent tests in some circumstances.

    See Global State for details.

    @before

    The @before annotation can be used to specify methods that should be called before each test method in a test case class.

    @beforeClass

    The @beforeClass annotation can be used to specify static methods that should be called before any test methods in a test class are run to set up shared fixtures.

    1. <?php declare(strict_types=1);
    2. use PHPUnit\Framework\TestCase;
    3. final class MyTest extends TestCase
    4. {
    5. /**
    6. */
    7. public static function setUpSomeSharedFixtures(): void
    8. {
    9. // ...
    10. }
    11. /**
    12. * @beforeClass
    13. */
    14. public static function setUpSomeOtherSharedFixtures(): void
    15. {
    16. // ...
    17. }
    18. }

    @codeCoverageIgnore*

    The @codeCoverageIgnore, @codeCoverageIgnoreStart and @codeCoverageIgnoreEnd annotations can be used to exclude lines of code from the coverage analysis.

    For usage see Ignoring Code Blocks.

    @covers

    The @covers annotation can be used in the test code to specify which parts of the code it is supposed to test:

    1. /**
    2. * @covers \BankAccount
    3. */
    4. public function testBalanceIsInitiallyZero(): void
    5. {
    6. $this->assertSame(0, $this->ba->getBalance());
    7. }

    If provided, this effectively filters the code coverage report to include executed code from the referenced code parts only. This will make sure that code is only marked as covered if there are dedicated tests for it, but not if it used indirectly by the tests for a different class, thus avoiding false positives for code coverage.

    This annotation can be added to the docblock of the test class or the individual test methods. The recommended way is to add the annotation to the docblock of the test class, not to the docblock of the test methods.

    When the forceCoversAnnotation configuration option in the configuration file is set to true, every test method needs to have an associated @covers annotation (either on the test class or the individual test method).

    shows the syntax of the @covers annotation. The section Specifying Covered Code Parts provides longer examples for using the annotation.

    Please note that this annotation requires a fully-qualified class name (FQCN). To make this more obvious to the reader, it is recommended to use a leading backslash (even if this not required for the annotation to work correctly).

    The @coversDefaultClass annotation can be used to specify a default namespace or class name. That way long names don’t need to be repeated for every @covers annotation. See Example 2.18.

    Please note that this annotation requires a fully-qualified class name (FQCN). To make this more obvious to the reader, it is recommended to use a leading backslash (even if this not required for the annotation to work correctly).

    Example 2.18 Using @coversDefaultClass to shorten annotations

    1. <?php declare(strict_types=1);
    2. use PHPUnit\Framework\TestCase;
    3. /**
    4. * @coversDefaultClass \Foo\CoveredClass
    5. */
    6. final class CoversDefaultClassTest extends TestCase
    7. {
    8. /**
    9. * @covers ::publicMethod
    10. */
    11. public function testSomething(): void
    12. {
    13. $o = new Foo\CoveredClass;
    14. $o->publicMethod();
    15. }
    16. }

    @coversNothing

    The @coversNothing annotation can be used in the test code to specify that no code coverage information will be recorded for the annotated test case.

    This can be used for integration testing. See A test that specifies that no method should be covered for an example.

    The annotation can be used on the class and the method level and will override any @covers tags.

    @dataProvider

    A test method can accept arbitrary arguments. These arguments are to be provided by one or more data provider methods (provider() in Using a data provider that returns an array of arrays). The data provider method to be used is specified using the @dataProvider annotation.

    See for more details.

    @depends

    PHPUnit supports the declaration of explicit dependencies between test methods. Such dependencies do not define the order in which the test methods are to be executed but they allow the returning of an instance of the test fixture by a producer and passing it to the dependent consumers. shows how to use the @depends annotation to express dependencies between test methods.

    See Test Dependencies for more details.

    @doesNotPerformAssertions

    Prevents a test that performs no assertions from being considered risky.

    @group

    A test can be tagged as belonging to one or more groups using the @group annotation like this

    1. <?php declare(strict_types=1);
    2. use PHPUnit\Framework\TestCase;
    3. final class MyTest extends TestCase
    4. {
    5. /**
    6. * @group specification
    7. */
    8. public function testSomething(): void
    9. {
    10. }
    11. /**
    12. * @group regression
    13. * @group bug2204
    14. */
    15. public function testSomethingElse(): void
    16. }
    17. }

    Tests can be selected for execution based on groups using the --group and --exclude-group options of the command-line test runner or using the respective directives of the XML configuration file.

    @large

    The @large annotation is an alias for @group large.

    If the PHP_Invoker package is installed and strict mode is enabled, a large test will fail if it takes longer than 60 seconds to execute. This timeout is configurable via the timeoutForLargeTests attribute in the XML configuration file.

    @medium

    The @medium annotation is an alias for @group medium. A medium test must not depend on a test marked as @large.

    If the PHP_Invoker package is installed and strict mode is enabled, a medium test will fail if it takes longer than 10 seconds to execute. This timeout is configurable via the timeoutForMediumTests attribute in the XML configuration file.

    @preserveGlobalState

    When a test is run in a separate process, PHPUnit will attempt to preserve the global state from the parent process by serializing all globals in the parent process and unserializing them in the child process. This can cause problems if the parent process contains globals that are not serializable. To fix this, you can prevent PHPUnit from preserving global state with the @preserveGlobalState annotation.

    1. <?php declare(strict_types=1);
    2. use PHPUnit\Framework\TestCase;
    3. final class MyTest extends TestCase
    4. {
    5. * @runInSeparateProcess
    6. * @preserveGlobalState disabled
    7. */
    8. public function testInSeparateProcess(): void
    9. {
    10. // ...
    11. }
    12. }

    The @requires annotation can be used to skip tests when common preconditions, like the PHP Version or installed extensions, are not met.

    A complete list of possibilities and examples can be found at

    @runTestsInSeparateProcesses

    Indicates that all tests in a test class should be run in a separate PHP process.

    Note: By default, PHPUnit will attempt to preserve the global state from the parent process by serializing all globals in the parent process and unserializing them in the child process. This can cause problems if the parent process contains globals that are not serializable. See for information on how to fix this.

    @runInSeparateProcess

    Indicates that a test should be run in a separate PHP process.

    1. <?php declare(strict_types=1);
    2. use PHPUnit\Framework\TestCase;
    3. final class MyTest extends TestCase
    4. {
    5. /**
    6. * @runInSeparateProcess
    7. */
    8. public function testInSeparateProcess(): void
    9. {
    10. // ...
    11. }
    12. }

    Note: By default, PHPUnit will attempt to preserve the global state from the parent process by serializing all globals in the parent process and unserializing them in the child process. This can cause problems if the parent process contains globals that are not serializable. See for information on how to fix this.

    @small

    The @small annotation is an alias for @group small. A small test must not depend on a test marked as @medium or @large.

    If the PHP_Invoker package is installed and strict mode is enabled, a small test will fail if it takes longer than 1 second to execute. This timeout is configurable via the timeoutForSmallTests attribute in the XML configuration file.

    Note

    Tests need to be explicitly annotated by either @small, @medium, or @large to enable run time limits.

    @test

    As an alternative to prefixing your test method names with test, you can use the @test annotation in a method’s DocBlock to mark it as a test method.

    1. /**
    2. * @test
    3. */
    4. public function initialBalanceShouldBe0(): void
    5. {
    6. $this->assertSame(0, $this->ba->getBalance());
    7. }

    @testdox

    Specifies an alternative description used when generating the agile documentation sentences.

    The @testdox annotation can be applied to both test classes and test methods.

    1. <?php declare(strict_types=1);
    2. use PHPUnit\Framework\TestCase;
    3. /**
    4. * @testdox A bank account
    5. */
    6. final class BankAccountTest extends TestCase
    7. {
    8. /**
    9. * @testdox has an initial balance of zero
    10. */
    11. public function balanceIsInitiallyZero(): void
    12. {
    13. $this->assertSame(0, $this->ba->getBalance());
    14. }
    15. }

    Note

    Prior to PHPUnit 7.0 (due to a bug in the annotation parsing), using the @testdox annotation also activated the behaviour of the @test annotation.

    When using the @testdox annotation at method level with a @dataProvider you may use the method parameters as placeholders in your alternative description. $_dataName is available in addition to use the actual name of the current data. That would be data set 1 up to 4 in below example.

    1. /**
    2. * @dataProvider additionProvider
    3. * @testdox Adding $a to $b results in $expected
    4. */
    5. public function testAdd($a, $b, $expected)
    6. {
    7. $this->assertSame($expected, $a + $b);
    8. }
    9. public function additionProvider()
    10. {
    11. return [
    12. 'data set 1' => [0, 0, 0],
    13. 'data set 2' => [0, 1, 1],
    14. 'data set 3' => [1, 0, 1],
    15. 'data set 4' => [1, 1, 3]
    16. ];
    17. }

    @testWith

    Instead of implementing a method for use with @dataProvider, you can define a data set using the @testWith annotation.

    A data set consists of one or many elements. To define a data set with multiple elements, define each element in a separate line. Each element of the data set must be an array defined in JSON.

    See Data Providers to learn more about passing a set of data to a test.

    1. /**
    2. * @testWith ["test", 4]
    3. * ["longer-string", 13]
    4. */
    5. public function testStringLength(string $input, int $expectedLength): void
    6. {
    7. $this->assertSame($expectedLength, strlen($input));
    8. }

    An object representation in JSON will be converted into an associative array.

    @ticket

    The @ticket annotation is an alias for the @group annotation (see @group) and allows to filter tests based on their ticket ID.

    @uses

    The @uses annotation specifies code which will be executed by a test, but is not intended to be covered by the test. A good example is a value object which is necessary for testing a unit of code.

    1. /**
    2. * @covers \BankAccount
    3. * @uses \Money
    4. */
    5. public function testMoneyCanBeDepositedInAccount(): void
    6. {
    7. // ...

    Example 9.2 shows another example.

    Please note that this annotation requires a fully-qualified class name (FQCN). To make this more obvious to the reader, it is recommended to use a leading backslash (even if this is not required for the annotation to work correctly).