# Table of Contents - [PHPUnit Manual — PHPUnit 12.4 Manual](#phpunit-manual-phpunit-12-4-manual) - [1. Installation — PHPUnit 12.4 Manual](#1-installation-phpunit-12-4-manual) - [3. The Command-Line Test Runner — PHPUnit 12.4 Manual](#3-the-command-line-test-runner-phpunit-12-4-manual) - [4. Organizing Tests — PHPUnit 12.4 Manual](#4-organizing-tests-phpunit-12-4-manual) - [2. Writing Tests for PHPUnit — PHPUnit 12.4 Manual](#2-writing-tests-for-phpunit-phpunit-12-4-manual) - [5. Fixtures — PHPUnit 12.4 Manual](#5-fixtures-phpunit-12-4-manual) - [6. Test Doubles — PHPUnit 12.4 Manual](#6-test-doubles-phpunit-12-4-manual) - [7. Code Coverage — PHPUnit 12.4 Manual](#7-code-coverage-phpunit-12-4-manual) - [8. Risky Tests — PHPUnit 12.4 Manual](#8-risky-tests-phpunit-12-4-manual) - [10. Extending PHPUnit — PHPUnit 12.4 Manual](#10-extending-phpunit-phpunit-12-4-manual) - [9. Error Handling — PHPUnit 12.4 Manual](#9-error-handling-phpunit-12-4-manual) - [3. Events — PHPUnit 12.4 Manual](#3-events-phpunit-12-4-manual) - [2. Attributes — PHPUnit 12.4 Manual](#2-attributes-phpunit-12-4-manual) - [5. Copyright — PHPUnit 12.4 Manual](#5-copyright-phpunit-12-4-manual) - [4. The XML Configuration File — PHPUnit 12.4 Manual](#4-the-xml-configuration-file-phpunit-12-4-manual) - [1. Assertions — PHPUnit 12.4 Manual](#1-assertions-phpunit-12-4-manual) --- # PHPUnit Manual — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/#) * PHPUnit Manual * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/index.rst) * * * PHPUnit Manual[](https://docs.phpunit.de/en/12.4/#phpunit-manual "Permalink to this heading") =============================================================================================== Edition for PHPUnit 12.4. Updated on Oct 20, 2025. Sebastian Bergmann This work is licensed under the Creative Commons Attribution 3.0 Unported License. Contents: * [1\. Installation](https://docs.phpunit.de/en/12.4/installation.html) * [PHP on the Command-Line](https://docs.phpunit.de/en/12.4/installation.html#php-on-the-command-line) * [Installing the PHP Command-Line Interpreter](https://docs.phpunit.de/en/12.4/installation.html#installing-the-php-command-line-interpreter) * [Using the PHP Command-Line Interpreter](https://docs.phpunit.de/en/12.4/installation.html#using-the-php-command-line-interpreter) * [Configuring PHP for Development](https://docs.phpunit.de/en/12.4/installation.html#configuring-php-for-development) * [Installing PHPUnit](https://docs.phpunit.de/en/12.4/installation.html#installing-phpunit) * [PHP Archive (PHAR)](https://docs.phpunit.de/en/12.4/installation.html#php-archive-phar) * [Composer](https://docs.phpunit.de/en/12.4/installation.html#composer) * [PHAR or Composer?](https://docs.phpunit.de/en/12.4/installation.html#phar-or-composer) * [Global Installation](https://docs.phpunit.de/en/12.4/installation.html#global-installation) * [Web Server](https://docs.phpunit.de/en/12.4/installation.html#web-server) * [2\. Writing Tests for PHPUnit](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html) * [Asserting Return Values](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#asserting-return-values) * [Expecting Exceptions](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#expecting-exceptions) * [Data Providers](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#data-providers) * [Testing Output](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#testing-output) * [Incomplete Tests](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#incomplete-tests) * [Skipping Tests](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#skipping-tests) * [Skipping Tests using Attributes](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#skipping-tests-using-attributes) * [Test Dependencies](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#test-dependencies) * [Failure Output](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#failure-output) * [Edge Cases](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#edge-cases) * [3\. The Command-Line Test Runner](https://docs.phpunit.de/en/12.4/textui.html) * [Outcome and Issues](https://docs.phpunit.de/en/12.4/textui.html#outcome-and-issues) * [Output](https://docs.phpunit.de/en/12.4/textui.html#output) * [Versions and Configuration](https://docs.phpunit.de/en/12.4/textui.html#versions-and-configuration) * [Progress](https://docs.phpunit.de/en/12.4/textui.html#progress) * [Test Results](https://docs.phpunit.de/en/12.4/textui.html#test-results) * [Summary](https://docs.phpunit.de/en/12.4/textui.html#summary) * [Command-Line Options](https://docs.phpunit.de/en/12.4/textui.html#command-line-options) * [Configuration](https://docs.phpunit.de/en/12.4/textui.html#configuration) * [Selection](https://docs.phpunit.de/en/12.4/textui.html#selection) * [Execution](https://docs.phpunit.de/en/12.4/textui.html#execution) * [Reporting](https://docs.phpunit.de/en/12.4/textui.html#reporting) * [Logging](https://docs.phpunit.de/en/12.4/textui.html#logging) * [4\. Organizing Tests](https://docs.phpunit.de/en/12.4/organizing-tests.html) * [Composing a Test Suite Using the Filesystem](https://docs.phpunit.de/en/12.4/organizing-tests.html#composing-a-test-suite-using-the-filesystem) * [Composing a Test Suite Using XML Configuration](https://docs.phpunit.de/en/12.4/organizing-tests.html#composing-a-test-suite-using-xml-configuration) * [5\. Fixtures](https://docs.phpunit.de/en/12.4/fixtures.html) * [More setUp() than tearDown()](https://docs.phpunit.de/en/12.4/fixtures.html#more-setup-than-teardown) * [Sharing Fixture](https://docs.phpunit.de/en/12.4/fixtures.html#sharing-fixture) * [Global State](https://docs.phpunit.de/en/12.4/fixtures.html#global-state) * [6\. Test Doubles](https://docs.phpunit.de/en/12.4/test-doubles.html) * [Test Stubs](https://docs.phpunit.de/en/12.4/test-doubles.html#test-stubs) * [Creating Test Stubs](https://docs.phpunit.de/en/12.4/test-doubles.html#creating-test-stubs) * [Configuring Test Stubs](https://docs.phpunit.de/en/12.4/test-doubles.html#configuring-test-stubs) * [Mock Objects](https://docs.phpunit.de/en/12.4/test-doubles.html#mock-objects) * [Creating Mock Objects](https://docs.phpunit.de/en/12.4/test-doubles.html#creating-mock-objects) * [Configuring Mock Objects](https://docs.phpunit.de/en/12.4/test-doubles.html#configuring-mock-objects) * [MockBuilder API](https://docs.phpunit.de/en/12.4/test-doubles.html#mockbuilder-api) * [`setConstructorArgs()`](https://docs.phpunit.de/en/12.4/test-doubles.html#setconstructorargs) * [`disableOriginalConstructor()`](https://docs.phpunit.de/en/12.4/test-doubles.html#disableoriginalconstructor) * [`disableOriginalClone()`](https://docs.phpunit.de/en/12.4/test-doubles.html#disableoriginalclone) * [`disableAutoReturnValueGeneration()`](https://docs.phpunit.de/en/12.4/test-doubles.html#disableautoreturnvaluegeneration) * [`onlyMethods()`](https://docs.phpunit.de/en/12.4/test-doubles.html#onlymethods) * [`getMock()`](https://docs.phpunit.de/en/12.4/test-doubles.html#getmock) * [Set-Hooked Properties](https://docs.phpunit.de/en/12.4/test-doubles.html#set-hooked-properties) * [7\. Code Coverage](https://docs.phpunit.de/en/12.4/code-coverage.html) * [Software Metrics for Code Coverage](https://docs.phpunit.de/en/12.4/code-coverage.html#software-metrics-for-code-coverage) * [Including Files](https://docs.phpunit.de/en/12.4/code-coverage.html#including-files) * [Targeting Units of Code](https://docs.phpunit.de/en/12.4/code-coverage.html#targeting-units-of-code) * [Ignoring Code Blocks](https://docs.phpunit.de/en/12.4/code-coverage.html#ignoring-code-blocks) * [8\. Risky Tests](https://docs.phpunit.de/en/12.4/risky-tests.html) * [Useless Tests](https://docs.phpunit.de/en/12.4/risky-tests.html#useless-tests) * [Unintentionally Covered Code](https://docs.phpunit.de/en/12.4/risky-tests.html#unintentionally-covered-code) * [Output During Test Execution](https://docs.phpunit.de/en/12.4/risky-tests.html#output-during-test-execution) * [Test Execution Timeout](https://docs.phpunit.de/en/12.4/risky-tests.html#test-execution-timeout) * [Global State Manipulation](https://docs.phpunit.de/en/12.4/risky-tests.html#global-state-manipulation) * [9\. Error Handling](https://docs.phpunit.de/en/12.4/error-handling.html) * [Limiting issues to “your code”](https://docs.phpunit.de/en/12.4/error-handling.html#limiting-issues-to-your-code) * [Ignoring issue suppression](https://docs.phpunit.de/en/12.4/error-handling.html#ignoring-issue-suppression) * [Ignoring previously reported issues](https://docs.phpunit.de/en/12.4/error-handling.html#ignoring-previously-reported-issues) * [Expecting Deprecations (`E_USER_DEPRECATED`)](https://docs.phpunit.de/en/12.4/error-handling.html#expecting-deprecations-e-user-deprecated) * [Disabling PHPUnit’s error handler](https://docs.phpunit.de/en/12.4/error-handling.html#disabling-phpunit-s-error-handler) * [10\. Extending PHPUnit](https://docs.phpunit.de/en/12.4/extending-phpunit.html) * [Enhancing concrete test cases](https://docs.phpunit.de/en/12.4/extending-phpunit.html#enhancing-concrete-test-cases) * [Extracting abstract test cases](https://docs.phpunit.de/en/12.4/extending-phpunit.html#extracting-abstract-test-cases) * [Extracting traits](https://docs.phpunit.de/en/12.4/extending-phpunit.html#extracting-traits) * [Extending the Test Runner](https://docs.phpunit.de/en/12.4/extending-phpunit.html#extending-the-test-runner) * [Implementing an extension](https://docs.phpunit.de/en/12.4/extending-phpunit.html#implementing-an-extension) * [Sharing an extension](https://docs.phpunit.de/en/12.4/extending-phpunit.html#sharing-an-extension) * [Registering an extension](https://docs.phpunit.de/en/12.4/extending-phpunit.html#registering-an-extension) * [Debugging PHPUnit](https://docs.phpunit.de/en/12.4/extending-phpunit.html#debugging-phpunit) * [Wrapping the Test Runner](https://docs.phpunit.de/en/12.4/extending-phpunit.html#wrapping-the-test-runner) Appendix * [1\. Assertions](https://docs.phpunit.de/en/12.4/assertions.html) * [Static vs. Non-Static Usage of Assertion Methods](https://docs.phpunit.de/en/12.4/assertions.html#static-vs-non-static-usage-of-assertion-methods) * [Boolean](https://docs.phpunit.de/en/12.4/assertions.html#boolean) * [`assertTrue()`](https://docs.phpunit.de/en/12.4/assertions.html#asserttrue) * [`assertFalse()`](https://docs.phpunit.de/en/12.4/assertions.html#assertfalse) * [Identity](https://docs.phpunit.de/en/12.4/assertions.html#appendixes-assertions-identity) * [`assertSame()`](https://docs.phpunit.de/en/12.4/assertions.html#assertsame) * [`assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys()`](https://docs.phpunit.de/en/12.4/assertions.html#assertarrayisidenticaltoarrayonlyconsideringlistofkeys) * [`assertArrayIsIdenticalToArrayIgnoringListOfKeys()`](https://docs.phpunit.de/en/12.4/assertions.html#assertarrayisidenticaltoarrayignoringlistofkeys) * [Equality](https://docs.phpunit.de/en/12.4/assertions.html#equality) * [`assertEquals()`](https://docs.phpunit.de/en/12.4/assertions.html#assertequals) * [`assertEqualsCanonicalizing()`](https://docs.phpunit.de/en/12.4/assertions.html#assertequalscanonicalizing) * [`assertEqualsIgnoringCase()`](https://docs.phpunit.de/en/12.4/assertions.html#assertequalsignoringcase) * [`assertEqualsWithDelta()`](https://docs.phpunit.de/en/12.4/assertions.html#assertequalswithdelta) * [`assertObjectEquals()`](https://docs.phpunit.de/en/12.4/assertions.html#assertobjectequals) * [`assertFileEquals()`](https://docs.phpunit.de/en/12.4/assertions.html#assertfileequals) * [`assertArrayIsEqualToArrayOnlyConsideringListOfKeys()`](https://docs.phpunit.de/en/12.4/assertions.html#assertarrayisequaltoarrayonlyconsideringlistofkeys) * [`assertArrayIsEqualToArrayIgnoringListOfKeys()`](https://docs.phpunit.de/en/12.4/assertions.html#assertarrayisequaltoarrayignoringlistofkeys) * [Iterable](https://docs.phpunit.de/en/12.4/assertions.html#iterable) * [`assertArrayHasKey()`](https://docs.phpunit.de/en/12.4/assertions.html#assertarrayhaskey) * [`assertContains()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontains) * [`assertContainsOnly()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonly) * [`assertContainsOnlyArray()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyarray) * [`assertContainsOnlyBool()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlybool) * [`assertContainsOnlyCallable()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlycallable) * [`assertContainsOnlyFloat()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyfloat) * [`assertContainsOnlyInt()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyint) * [`assertContainsOnlyIterable()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyiterable) * [`assertContainsOnlyNull()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlynull) * [`assertContainsOnlyNumeric()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlynumeric) * [`assertContainsOnlyObject()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyobject) * [`assertContainsOnlyResource()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyresource) * [`assertContainsOnlyClosedResource()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyclosedresource) * [`assertContainsOnlyScalar()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyscalar) * [`assertContainsOnlyString()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlystring) * [`assertContainsOnlyInstancesOf()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyinstancesof) * [Objects](https://docs.phpunit.de/en/12.4/assertions.html#objects) * [`assertObjectHasProperty()`](https://docs.phpunit.de/en/12.4/assertions.html#assertobjecthasproperty) * [Cardinality](https://docs.phpunit.de/en/12.4/assertions.html#cardinality) * [`assertCount()`](https://docs.phpunit.de/en/12.4/assertions.html#assertcount) * [`assertSameSize()`](https://docs.phpunit.de/en/12.4/assertions.html#assertsamesize) * [`assertEmpty()`](https://docs.phpunit.de/en/12.4/assertions.html#assertempty) * [`assertGreaterThan()`](https://docs.phpunit.de/en/12.4/assertions.html#assertgreaterthan) * [`assertGreaterThanOrEqual()`](https://docs.phpunit.de/en/12.4/assertions.html#assertgreaterthanorequal) * [`assertLessThan()`](https://docs.phpunit.de/en/12.4/assertions.html#assertlessthan) * [`assertLessThanOrEqual()`](https://docs.phpunit.de/en/12.4/assertions.html#assertlessthanorequal) * [Types](https://docs.phpunit.de/en/12.4/assertions.html#types) * [`assertInstanceOf()`](https://docs.phpunit.de/en/12.4/assertions.html#assertinstanceof) * [`assertIsArray()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisarray) * [`assertIsList()`](https://docs.phpunit.de/en/12.4/assertions.html#assertislist) * [`assertIsBool()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisbool) * [`assertIsCallable()`](https://docs.phpunit.de/en/12.4/assertions.html#assertiscallable) * [`assertIsFloat()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisfloat) * [`assertIsInt()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisint) * [`assertIsIterable()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisiterable) * [`assertIsNumeric()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisnumeric) * [`assertIsObject()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisobject) * [`assertIsResource()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisresource) * [`assertIsScalar()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisscalar) * [`assertIsString()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisstring) * [`assertNull()`](https://docs.phpunit.de/en/12.4/assertions.html#assertnull) * [Strings](https://docs.phpunit.de/en/12.4/assertions.html#strings) * [`assertStringStartsWith()`](https://docs.phpunit.de/en/12.4/assertions.html#assertstringstartswith) * [`assertStringEndsWith()`](https://docs.phpunit.de/en/12.4/assertions.html#assertstringendswith) * [`assertStringContainsString()`](https://docs.phpunit.de/en/12.4/assertions.html#assertstringcontainsstring) * [`assertStringContainsStringIgnoringCase()`](https://docs.phpunit.de/en/12.4/assertions.html#assertstringcontainsstringignoringcase) * [`assertStringEqualsStringIgnoringLineEndings()`](https://docs.phpunit.de/en/12.4/assertions.html#assertstringequalsstringignoringlineendings) * [`assertMatchesRegularExpression()`](https://docs.phpunit.de/en/12.4/assertions.html#assertmatchesregularexpression) * [`assertStringMatchesFormat()`](https://docs.phpunit.de/en/12.4/assertions.html#assertstringmatchesformat) * [`assertStringMatchesFormatFile()`](https://docs.phpunit.de/en/12.4/assertions.html#assertstringmatchesformatfile) * [`assertFileMatchesFormat()`](https://docs.phpunit.de/en/12.4/assertions.html#assertfilematchesformat) * [`assertFileMatchesFormatFile()`](https://docs.phpunit.de/en/12.4/assertions.html#assertfilematchesformatfile) * [`assertStringEqualsFile()`](https://docs.phpunit.de/en/12.4/assertions.html#assertstringequalsfile) * [JSON](https://docs.phpunit.de/en/12.4/assertions.html#json) * [`assertJson()`](https://docs.phpunit.de/en/12.4/assertions.html#assertjson) * [`assertJsonFileEqualsJsonFile()`](https://docs.phpunit.de/en/12.4/assertions.html#assertjsonfileequalsjsonfile) * [`assertJsonStringEqualsJsonFile()`](https://docs.phpunit.de/en/12.4/assertions.html#assertjsonstringequalsjsonfile) * [`assertJsonStringEqualsJsonString()`](https://docs.phpunit.de/en/12.4/assertions.html#assertjsonstringequalsjsonstring) * [XML](https://docs.phpunit.de/en/12.4/assertions.html#xml) * [`assertXmlFileEqualsXmlFile()`](https://docs.phpunit.de/en/12.4/assertions.html#assertxmlfileequalsxmlfile) * [`assertXmlStringEqualsXmlFile()`](https://docs.phpunit.de/en/12.4/assertions.html#assertxmlstringequalsxmlfile) * [`assertXmlStringEqualsXmlString()`](https://docs.phpunit.de/en/12.4/assertions.html#assertxmlstringequalsxmlstring) * [Filesystem](https://docs.phpunit.de/en/12.4/assertions.html#filesystem) * [`assertDirectoryExists()`](https://docs.phpunit.de/en/12.4/assertions.html#assertdirectoryexists) * [`assertDirectoryIsReadable()`](https://docs.phpunit.de/en/12.4/assertions.html#assertdirectoryisreadable) * [`assertDirectoryIsWritable()`](https://docs.phpunit.de/en/12.4/assertions.html#assertdirectoryiswritable) * [`assertFileExists()`](https://docs.phpunit.de/en/12.4/assertions.html#assertfileexists) * [`assertFileIsReadable()`](https://docs.phpunit.de/en/12.4/assertions.html#assertfileisreadable) * [`assertFileIsWritable()`](https://docs.phpunit.de/en/12.4/assertions.html#assertfileiswritable) * [`assertIsReadable()`](https://docs.phpunit.de/en/12.4/assertions.html#assertisreadable) * [`assertIsWritable()`](https://docs.phpunit.de/en/12.4/assertions.html#assertiswritable) * [Math](https://docs.phpunit.de/en/12.4/assertions.html#math) * [`assertInfinite()`](https://docs.phpunit.de/en/12.4/assertions.html#assertinfinite) * [`assertNan()`](https://docs.phpunit.de/en/12.4/assertions.html#assertnan) * [Constraints](https://docs.phpunit.de/en/12.4/assertions.html#constraints) * [`assertThat()`](https://docs.phpunit.de/en/12.4/assertions.html#assertthat) * [2\. Attributes](https://docs.phpunit.de/en/12.4/attributes.html) * [`Test`](https://docs.phpunit.de/en/12.4/attributes.html#test) * [`DisableReturnValueGenerationForTestDoubles`](https://docs.phpunit.de/en/12.4/attributes.html#disablereturnvaluegenerationfortestdoubles) * [`DoesNotPerformAssertions`](https://docs.phpunit.de/en/12.4/attributes.html#doesnotperformassertions) * [`IgnoreDeprecations`](https://docs.phpunit.de/en/12.4/attributes.html#ignoredeprecations) * [`WithoutErrorHandler`](https://docs.phpunit.de/en/12.4/attributes.html#withouterrorhandler) * [Code Coverage](https://docs.phpunit.de/en/12.4/attributes.html#code-coverage) * [`CoversClass`](https://docs.phpunit.de/en/12.4/attributes.html#coversclass) * [`CoversClassesThatImplementInterface`](https://docs.phpunit.de/en/12.4/attributes.html#coversclassesthatimplementinterface) * [`CoversClassesThatExtendClass`](https://docs.phpunit.de/en/12.4/attributes.html#coversclassesthatextendclass) * [`CoversTrait`](https://docs.phpunit.de/en/12.4/attributes.html#coverstrait) * [`CoversMethod`](https://docs.phpunit.de/en/12.4/attributes.html#coversmethod) * [`CoversFunction`](https://docs.phpunit.de/en/12.4/attributes.html#coversfunction) * [`CoversNothing`](https://docs.phpunit.de/en/12.4/attributes.html#coversnothing) * [`UsesClass`](https://docs.phpunit.de/en/12.4/attributes.html#usesclass) * [`UsesClassesThatImplementInterface`](https://docs.phpunit.de/en/12.4/attributes.html#usesclassesthatimplementinterface) * [`UsesClassesThatExtendClass`](https://docs.phpunit.de/en/12.4/attributes.html#usesclassesthatextendclass) * [`UsesTrait`](https://docs.phpunit.de/en/12.4/attributes.html#usestrait) * [`UsesMethod`](https://docs.phpunit.de/en/12.4/attributes.html#usesmethod) * [`UsesFunction`](https://docs.phpunit.de/en/12.4/attributes.html#usesfunction) * [Data Provider](https://docs.phpunit.de/en/12.4/attributes.html#data-provider) * [`DataProvider`](https://docs.phpunit.de/en/12.4/attributes.html#dataprovider) * [`DataProviderExternal`](https://docs.phpunit.de/en/12.4/attributes.html#dataproviderexternal) * [`TestWith`](https://docs.phpunit.de/en/12.4/attributes.html#testwith) * [`TestWithJson`](https://docs.phpunit.de/en/12.4/attributes.html#testwithjson) * [Test Dependencies](https://docs.phpunit.de/en/12.4/attributes.html#test-dependencies) * [`Depends`](https://docs.phpunit.de/en/12.4/attributes.html#depends) * [`DependsUsingDeepClone`](https://docs.phpunit.de/en/12.4/attributes.html#dependsusingdeepclone) * [`DependsUsingShallowClone`](https://docs.phpunit.de/en/12.4/attributes.html#dependsusingshallowclone) * [`DependsExternal`](https://docs.phpunit.de/en/12.4/attributes.html#dependsexternal) * [`DependsExternalUsingDeepClone`](https://docs.phpunit.de/en/12.4/attributes.html#dependsexternalusingdeepclone) * [`DependsExternalUsingShallowClone`](https://docs.phpunit.de/en/12.4/attributes.html#dependsexternalusingshallowclone) * [`DependsOnClass`](https://docs.phpunit.de/en/12.4/attributes.html#dependsonclass) * [`DependsOnClassUsingDeepClone`](https://docs.phpunit.de/en/12.4/attributes.html#dependsonclassusingdeepclone) * [`DependsOnClassUsingShallowClone`](https://docs.phpunit.de/en/12.4/attributes.html#dependsonclassusingshallowclone) * [TestDox](https://docs.phpunit.de/en/12.4/attributes.html#testdox) * [`TestDox`](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-testdox) * [`TestDoxFormatter`](https://docs.phpunit.de/en/12.4/attributes.html#testdoxformatter) * [`TestDoxFormatterExternal`](https://docs.phpunit.de/en/12.4/attributes.html#testdoxformatterexternal) * [Test Groups](https://docs.phpunit.de/en/12.4/attributes.html#test-groups) * [`Group`](https://docs.phpunit.de/en/12.4/attributes.html#group) * [`Small`](https://docs.phpunit.de/en/12.4/attributes.html#small) * [`Medium`](https://docs.phpunit.de/en/12.4/attributes.html#medium) * [`Large`](https://docs.phpunit.de/en/12.4/attributes.html#large) * [`Ticket`](https://docs.phpunit.de/en/12.4/attributes.html#ticket) * [Template Methods](https://docs.phpunit.de/en/12.4/attributes.html#template-methods) * [`BeforeClass`](https://docs.phpunit.de/en/12.4/attributes.html#beforeclass) * [`Before`](https://docs.phpunit.de/en/12.4/attributes.html#before) * [`PreCondition`](https://docs.phpunit.de/en/12.4/attributes.html#precondition) * [`PostCondition`](https://docs.phpunit.de/en/12.4/attributes.html#postcondition) * [`After`](https://docs.phpunit.de/en/12.4/attributes.html#after) * [`AfterClass`](https://docs.phpunit.de/en/12.4/attributes.html#afterclass) * [Test Isolation](https://docs.phpunit.de/en/12.4/attributes.html#test-isolation) * [`BackupGlobals`](https://docs.phpunit.de/en/12.4/attributes.html#backupglobals) * [`ExcludeGlobalVariableFromBackup`](https://docs.phpunit.de/en/12.4/attributes.html#excludeglobalvariablefrombackup) * [`BackupStaticProperties`](https://docs.phpunit.de/en/12.4/attributes.html#backupstaticproperties) * [`ExcludeStaticPropertyFromBackup`](https://docs.phpunit.de/en/12.4/attributes.html#excludestaticpropertyfrombackup) * [`RunInSeparateProcess`](https://docs.phpunit.de/en/12.4/attributes.html#runinseparateprocess) * [`RunTestsInSeparateProcesses`](https://docs.phpunit.de/en/12.4/attributes.html#runtestsinseparateprocesses) * [`RunClassInSeparateProcess`](https://docs.phpunit.de/en/12.4/attributes.html#runclassinseparateprocess) * [`PreserveGlobalState`](https://docs.phpunit.de/en/12.4/attributes.html#preserveglobalstate) * [Skipping Tests](https://docs.phpunit.de/en/12.4/attributes.html#skipping-tests) * [`RequiresPhp`](https://docs.phpunit.de/en/12.4/attributes.html#requiresphp) * [`RequiresPhpExtension`](https://docs.phpunit.de/en/12.4/attributes.html#requiresphpextension) * [`RequiresSetting`](https://docs.phpunit.de/en/12.4/attributes.html#requiressetting) * [`RequiresPhpunit`](https://docs.phpunit.de/en/12.4/attributes.html#requiresphpunit) * [`RequiresPhpunitExtension`](https://docs.phpunit.de/en/12.4/attributes.html#requiresphpunitextension) * [`RequiresFunction`](https://docs.phpunit.de/en/12.4/attributes.html#requiresfunction) * [`RequiresMethod`](https://docs.phpunit.de/en/12.4/attributes.html#requiresmethod) * [`RequiresOperatingSystem`](https://docs.phpunit.de/en/12.4/attributes.html#requiresoperatingsystem) * [`RequiresOperatingSystemFamily`](https://docs.phpunit.de/en/12.4/attributes.html#requiresoperatingsystemfamily) * [`RequiresEnvironmentVariable`](https://docs.phpunit.de/en/12.4/attributes.html#requiresenvironmentvariable) * [3\. Events](https://docs.phpunit.de/en/12.4/events.html) * [Application](https://docs.phpunit.de/en/12.4/events.html#application) * [TestRunner](https://docs.phpunit.de/en/12.4/events.html#testrunner) * [TestSuite](https://docs.phpunit.de/en/12.4/events.html#testsuite) * [Test](https://docs.phpunit.de/en/12.4/events.html#test) * [4\. The XML Configuration File](https://docs.phpunit.de/en/12.4/configuration.html) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-phpunit-element) * [The `backupGlobals` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-backupglobals-attribute) * [The `backupStaticProperties` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-backupstaticproperties-attribute) * [The `bootstrap` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-bootstrap-attribute) * [The `cacheDirectory` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-cachedirectory-attribute) * [The `cacheResult` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-cacheresult-attribute) * [The `colors` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-colors-attribute) * [The `columns` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-columns-attribute) * [The `controlGarbageCollector` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-controlgarbagecollector-attribute) * [The `numberOfTestsBeforeGarbageCollection` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-numberoftestsbeforegarbagecollection-attribute) * [The `requireCoverageMetadata` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-requirecoveragemetadata-attribute) * [The `processIsolation` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-processisolation-attribute) * [The `stopOnDefect` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-stopondefect-attribute) * [The `stopOnError` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponerror-attribute) * [The `stopOnFailure` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponfailure-attribute) * [The `stopOnWarning` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponwarning-attribute) * [The `stopOnRisky` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponrisky-attribute) * [The `stopOnDeprecation` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-stopondeprecation-attribute) * [The `stopOnNotice` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponnotice-attribute) * [The `stopOnSkipped` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponskipped-attribute) * [The `stopOnIncomplete` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponincomplete-attribute) * [The `failOnAllIssues` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-failonallissues-attribute) * [The `failOnEmptyTestSuite` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-failonemptytestsuite-attribute) * [The `failOnWarning` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-failonwarning-attribute) * [The `failOnRisky` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-failonrisky-attribute) * [The `failOnDeprecation` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-failondeprecation-attribute) * [The `failOnPhpunitDeprecation` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-failonphpunitdeprecation-attribute) * [The `failOnNotice` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-failonnotice-attribute) * [The `failOnSkipped` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-failonskipped-attribute) * [The `failOnIncomplete` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-failonincomplete-attribute) * [The `beStrictAboutChangesToGlobalState` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-bestrictaboutchangestoglobalstate-attribute) * [The `beStrictAboutOutputDuringTests` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-bestrictaboutoutputduringtests-attribute) * [The `beStrictAboutTestsThatDoNotTestAnything` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-bestrictaboutteststhatdonottestanything-attribute) * [The `beStrictAboutCoverageMetadata` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-bestrictaboutcoveragemetadata-attribute) * [The `enforceTimeLimit` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-enforcetimelimit-attribute) * [The `defaultTimeLimit` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-defaulttimelimit-attribute) * [The `timeoutForSmallTests` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-timeoutforsmalltests-attribute) * [The `timeoutForMediumTests` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-timeoutformediumtests-attribute) * [The `timeoutForLargeTests` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-timeoutforlargetests-attribute) * [The `defaultTestSuite` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-defaulttestsuite-attribute) * [The `stderr` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-stderr-attribute) * [The `reverseDefectList` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-reversedefectlist-attribute) * [The `registerMockObjectsFromTestArgumentsRecursively` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-registermockobjectsfromtestargumentsrecursively-attribute) * [The `extensionsDirectory` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-extensionsdirectory-attribute) * [The `executionOrder` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-executionorder-attribute) * [The `resolveDependencies` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-resolvedependencies-attribute) * [The `testdox` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-testdox-attribute) * [The `testdoxSummary` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-testdoxsummary-attribute) * [The `displayDetailsOnAllIssues` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonallissues-attribute) * [The `displayDetailsOnIncompleteTests` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonincompletetests-attribute) * [The `displayDetailsOnSkippedTests` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonskippedtests-attribute) * [The `displayDetailsOnTestsThatTriggerDeprecations` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonteststhattriggerdeprecations-attribute) * [The `displayDetailsOnPhpunitDeprecations` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonphpunitdeprecations-attribute) * [The `displayDetailsOnTestsThatTriggerErrors` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonteststhattriggererrors-attribute) * [The `displayDetailsOnTestsThatTriggerNotices` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonteststhattriggernotices-attribute) * [The `displayDetailsOnTestsThatTriggerWarnings` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonteststhattriggerwarnings-attribute) * [The `shortenArraysForExportThreshold` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-shortenarraysforexportthreshold-attribute) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-testsuites-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-testsuite-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-source-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-include-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-exclude-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-directory-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-file-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-deprecationtrigger-element) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoreselfdeprecations-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoredirectdeprecations-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoreindirectdeprecations-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-restrictnotices-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-restrictwarnings-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-baseline-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofdeprecations-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofphpdeprecations-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionoferrors-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofnotices-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofphpnotices-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofwarnings-attribute) * [The `` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofphpwarnings-attribute) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-coverage-element) * [The `includeUncoveredFiles` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-includeuncoveredfiles-attribute) * [The `ignoreDeprecatedCodeUnits` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoredeprecatedcodeunits-attribute) * [The `pathCoverage` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-pathcoverage-attribute) * [The `disableCodeCoverageIgnore` Attribute](https://docs.phpunit.de/en/12.4/configuration.html#the-disablecodecoverageignore-attribute) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-report-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-logging-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-junit-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-teamcity-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-testdoxhtml-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-testdoxtext-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-groups-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-extensions-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-bootstrap-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-php) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-includepath-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-ini-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-const-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-var-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-env-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-get-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-post-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-cookie-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-server-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-files-element) * [The `` Element](https://docs.phpunit.de/en/12.4/configuration.html#the-request-element) * [5\. Copyright](https://docs.phpunit.de/en/12.4/copyright.html) --- # 1. Installation — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 1\. Installation * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/installation.rst) * * * 1\. Installation[](https://docs.phpunit.de/en/12.4/installation.html#installation "Permalink to this heading") ================================================================================================================ PHP is a general-purpose programming language. While it originally only supported the paradigm of procedural programming, most PHP code that is written today leverages the language’s capabilities for object-oriented programming. As it is especially suited for web development, you probably made your first contact with PHP in an environment where PHP code is executed on a web server. PHPUnit provides a framework for writing tests as well as a command-line tool for running these tests. Before we discuss obtaining and using PHPUnit, let us have a look at installing and configuring the PHP command-line interpreter. PHPUnit 12 requires PHP 8.3; using the latest version of PHP is highly recommended. PHP on the Command-Line[](https://docs.phpunit.de/en/12.4/installation.html#php-on-the-command-line "Permalink to this heading") ---------------------------------------------------------------------------------------------------------------------------------- We start by installing PHP’s command-line interpreter as well as the PHP extensions required to use PHPUnit. ### Installing the PHP Command-Line Interpreter[](https://docs.phpunit.de/en/12.4/installation.html#installing-the-php-command-line-interpreter "Permalink to this heading") #### Fedora[](https://docs.phpunit.de/en/12.4/installation.html#fedora "Permalink to this heading") At the time of writing, Fedora 43 is the current version of this Linux distribution. It ships with PHP 8.4 by default. Here is how you install PHP’s command-line interpreter together with the extensions required for PHPUnit: sudo dnf install php-cli \\ php-json \\ php-mbstring \\ php-process \\ php-xml \\ php-pecl-pcov \\ php-pecl-xdebug If you use an older version of Fedora then you should have a look at the [package repository maintained by Remi Collet](https://rpms.remirepo.net/) . #### Debian[](https://docs.phpunit.de/en/12.4/installation.html#debian "Permalink to this heading") At the time of writing, Debian 13 is the current version of this Linux distribution. It ships with PHP 8.4 by default. Here is how you install PHP’s command-line interpreter together with the extensions required for PHPUnit: sudo apt install php-cli \\ php-json \\ php-mbstring \\ php-xml \\ php-pcov \\ php-xdebug If you use an older version of Debian then you should have a look at the [package repository](https://deb.sury.org/) maintained by Ondřej Surý. #### Ubuntu[](https://docs.phpunit.de/en/12.4/installation.html#ubuntu "Permalink to this heading") At the time of writing, Ubuntu 25.10 is the current version of this Linux distribution. It ships with PHP 8.4 by default. Here is how you install PHP’s command-line interpreter together with the extensions required for PHPUnit: sudo apt install php-cli \\ php-json \\ php-mbstring \\ php-xml \\ php-pcov \\ php-xdebug If you use an older version of Ubuntu then you should have a look at the [package repository](https://deb.sury.org/) maintained by Ondřej Surý. #### macOS[](https://docs.phpunit.de/en/12.4/installation.html#macos "Permalink to this heading") The most common way to install PHP on macOS is using [Homebrew](https://brew.sh/) . The instructions given below assume that you have Homebrew already set up. We will use the [homebrew-php formulae maintained by Shivam Mathur](https://github.com/shivammathur/homebrew-php) . The following command will fetch these formulae: brew tap shivammathur/php brew tap shivammathur/extensions The following command will install PHP 8.2: brew install shivammathur/php/php@8.2 The following extensions required by PHPUnit are already installed and enabled by default: * `dom` * `json` * `libxml` * `mbstring` * `xml` * `xmlwriter` If you want to collect code coverage information, you need to additionally install and enable one of the following extensions: * `pcov` * `xdebug` The following command will install and enable the `pcov` extension: brew install pcov@8.2 The following command will install and enable the `xdebug` extension: brew install xdebug@8.2 #### Windows[](https://docs.phpunit.de/en/12.4/installation.html#windows "Permalink to this heading") ##### Native Binaries[](https://docs.phpunit.de/en/12.4/installation.html#native-binaries "Permalink to this heading") The PHP Project provides native binaries for Windows at [windows.php.net](https://windows.php.net/) . Choose the appropriate binary package for your architecture (32-bit or 64-bit) and version of Windows and follow the installation instructions given on this website. Enable the `mbstring` extension by adding `extension=mbstring` to the `php.ini` configuration file used by the PHP command-line interpreter. ##### Windows Subsystem for Linux[](https://docs.phpunit.de/en/12.4/installation.html#windows-subsystem-for-linux "Permalink to this heading") The Windows Subsystem for Linux allows Linux binary executables (in ELF format) to be run on Windows 10 (or later). Update to the latest version of Windows, install the latest version of Windows Subsystem for Linux, and install the Linux distribution of your choice from the Microsoft Store. Then follow the installation instructions in this chapter for the Linux distribution you chose. ### Using the PHP Command-Line Interpreter[](https://docs.phpunit.de/en/12.4/installation.html#using-the-php-command-line-interpreter "Permalink to this heading") Now we have the PHP command-line interpreter set up, and it is time to learn how to use it. With `php --version` we can verify that the PHP command-line interpreter, `php`, is on the path, works, and check which version it is. ### Configuring PHP for Development[](https://docs.phpunit.de/en/12.4/installation.html#configuring-php-for-development "Permalink to this heading") In this section we ensure that the PHP command-line interpreter is configured in such a way that we can properly use PHPUnit. The configuration directives shown below should be added to your PHP configuration file. Using `php --ini` we can ask the PHP command-line interpreter for the configuration file, or files, that is (are) being used. We want to see all PHP errors, warnings, notices, etc. when we run our tests. display\_errors=On display\_startup\_errors=On error\_reporting=-1 The value used with `error_reporting` is a bitmask that can be used to toggle the reporting of the various types of errors supported by PHP. Setting this to `-1` ensures that we always see all errors. When Xdebug is loaded, we do not want it to print its exception traces while our tests are being executed: xdebug.show\_exception\_trace=0 This is how you enable Xdebug’s code coverage functionality: xdebug.mode=coverage Please note that the `xdebug.mode` configuration directive takes a comma-separated list of modes. `coverage` must be one of these modes for code coverage to work. When the code we test contains `assert()` statements then we want them to be evaluated and to raise exceptions: zend.assertions=1 assert.exception=1 The collection of code coverage data and the generation of a code coverage report sometimes requires more memory than PHP is allowed to use by default: memory\_limit=-1 It is recommended to only load Xdebug when it is needed, for instance when you want to use it for debugging or to collect code coverage data. When it comes to collecting code coverage data and when you are interested only in line coverage, the [PCOV](https://github.com/krakjoe/pcov) extension is recommended over Xdebug for performance reasons. Do not worry if terms such as “code coverage” or “line coverage” do not mean anything to you just yet. We will cover them in great detail later. Installing PHPUnit[](https://docs.phpunit.de/en/12.4/installation.html#installing-phpunit "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------ ### PHP Archive (PHAR)[](https://docs.phpunit.de/en/12.4/installation.html#php-archive-phar "Permalink to this heading") The recommended way to install and use PHPUnit is to download a distribution that is packaged as a PHP Archive (PHAR). Releases of PHPUnit packaged as PHP archives are available on `https://phar.phpunit.de/`. At `https://phar.phpunit.de/phpunit-10.phar`, for instance, you will always find the latest version of PHPUnit 10. At `https://phar.phpunit.de/phpunit-10.0.0.phar`, for instance, you will always find that specific version of PHPUnit. At `https://phar.phpunit.de/phpunit-snapshot.phar` you will always find the latest development snapshot of PHPUnit. Such a PHP archive has all required (as well as some optional) dependencies of PHPUnit bundled in a single file. The PHAR (`ext/phar`) extension is required if you want to use PHPUnit from a PHP archive. #### Manual Download of PHAR[](https://docs.phpunit.de/en/12.4/installation.html#manual-download-of-phar "Permalink to this heading") You can simply download a release of PHPUnit packaged as a PHP archive and immediately use it: wget -O phpunit.phar https://phar.phpunit.de/phpunit-10.phar php phpunit.phar --version PHPUnit 10.0.0 by Sebastian Bergmann and contributors. It is a common practice to make the PHAR executable: chmod +x phpunit.phar Now you can directly run the PHAR: ./phpunit.phar --version PHPUnit 10.0.0 by Sebastian Bergmann and contributors. All official releases distributed by the PHPUnit Project are signed by the release manager for the release. PGP signatures and SHA256 hashes are available for verification on `https://phar.phpunit.de/`. Here is an example of how you can manually verify a PHP archive of a PHPUnit release using its PGP signature: wget -O phpunit.phar https://phar.phpunit.de/phpunit-10.phar wget -O phpunit.phar.asc https://phar.phpunit.de/phpunit-10.phar.asc gpg --keyserver pgp.uni-mainz.de --recv-keys 0x4AA394086372C20A gpg phpunit.phar.asc It is a common practice to use different versions of PHPUnit on a per-project basis. This is achieved by putting a PHP archive of PHPUnit into your project directory. A typical directory structure for a PHP project looks like this: ├── public ├── src ├── tests └── tools The `public` directory contains the application’s static assets (CSS, JavaScript, images, …); it is the webserver’s document root. The `src` directory contains the application’s PHP source code. The `tests` directory contains the application’s test suite. The `tools` directory contains tools such as PHPUnit packaged as PHP archives. You can download PHPUnit’s PHP archive to that `tools` directory manually, of course: wget -O phpunit.phar https://phar.phpunit.de/phpunit-10.phar chmod +x phpunit.phar mv phpunit.phar tools #### Installing PHPUnit with Phive[](https://docs.phpunit.de/en/12.4/installation.html#installing-phpunit-with-phive "Permalink to this heading") You can use [Phive](https://phar.io/) , the _PHAR Installation and Verification Environment_, to manage the PHAR-based tools of your PHP project. This is how you install Phive: wget https://phar.io/releases/phive.phar wget https://phar.io/releases/phive.phar.asc gpg --keyserver hkps.pool.sks-keyservers.net --recv-keys 0x9B2D5D79 gpg --verify phive.phar.asc phive.phar chmod +x phive.phar mv phive.phar /usr/local/bin/phive Once Phive is installed, PHPUnit can be installed like so: phive install phpunit After executing the command shown above the project’s directory will look like this: ├── .phive | └── phars.xml ├── public ├── src ├── tests └── tools └── phpunit -> ~/.phive/phars/phpunit-10.0.0.phar Phive has downloaded the PHP archive for PHPUnit 10.0.0, placed it in a cache located in your home directory, and created a symbolic link from there to `tools/phpunit`. You can now invoke the project-local installation of PHPUnit by running `./tools/phpunit`: ./tools/phpunit --version PHPUnit 10.0.0 by Sebastian Bergmann and contributors. The `.phive/phars.xml` file that was generated in your project’s root directory contains metadata about your project’s tool dependencies: `.phive/phars.xml` should be put under version control. The `^10.0` is a semantic version constraint: Phive will always install the latest version of PHPUnit that is compatible with PHPUnit 10.0. Phive does not only provide a convenient way for installing, managing, and updating tools that are distributed as a PHP archive. Phive also keeps you safe by automatically verifying the PGP signatures while downloading the PHAR files. If you want to keep PHPUnit’s PHP archive under version control, then you should use Phive’s `--copy` option to copy the PHP archive from its cache located in your home directory into your project’s tools directory: phive install --copy phpunit After executing the command shown above the project’s directory will look like this: ├── .phive | └── phars.xml ├── public ├── src ├── tests └── tools └── phpunit Note Unfortunately, PhpStorm only recognizes a file as a PHP archive when it has the `.phar` suffix. This is remedied by creating a symbolic link: `ln -s phpunit tools/phpunit.phar`. #### Updating PHPUnit with Phive[](https://docs.phpunit.de/en/12.4/installation.html#updating-phpunit-with-phive "Permalink to this heading") `phive install phpunit` adds a dependency on PHPUnit with a version constraint that uses the caret operator (`^`) for semantic versioning: `version="^10.0"`. With this configuration, Phive will always install the latest version of PHPUnit that is compatible with PHPUnit 10.0. This ensures you “stay fresh” as long as PHPUnit 10 is the current stable version of PHPUnit and includes new minor versions such as PHPUnit 10.1. And when the time comes and PHPUnit 11 is released then Phive will not automatically and unexpectedly install it. ##### Updating to a new minor or patch version[](https://docs.phpunit.de/en/12.4/installation.html#updating-to-a-new-minor-or-patch-version "Permalink to this heading") Consider the following situation: you use the semantic version constraint `^9.6` for PHPUnit in your `.phive/phars.xml` file and have PHPUnit 9.6.0 installed. Here is what your `.phive/phars.xml` file currently looks like: Since you used `phive update` last, PHPUnit 9.6.3 became available. You can use the `phive outdated` command to check whether an update is available for any of your project’s PHP archives that are managed by Phive: phive outdated Phive 0.15.2 - Copyright (C) 2015-2023 by Arne Blankerts, Sebastian Heuer and Contributors Found 1 outdated PHARs in phive.xml: Name Version Constraint Installed Available phpunit ^9.6 9.6.0 9.6.3 Because PHPUnit 9.6.3 is a new patch version (and not a new major version), `phive update` will update from PHPUnit 9.6.0 to PHPUnit 9.6.3. ##### Updating to a new major version[](https://docs.phpunit.de/en/12.4/installation.html#updating-to-a-new-major-version "Permalink to this heading") Consider the following situation: Now PHPUnit 10, a new major version, became available. However, running `phive outdated` does not offer us the update to PHPUnit 10: phive outdated Phive 0.15.2 - Copyright (C) 2015-2023 by Arne Blankerts, Sebastian Heuer and Contributors Congrats, no outdated phars found Note Unfortunately, the output of `phive outdated` is confusing when no new minor or patch versions are available, but a new major version is available. This is because PHPUnit 10 is a new major version and updates to a new major version should be an explicit operation following a conscious decision. If you use semantic version constraints in your `.phive/phars.xml` file ([and you should!](https://thephp.cc/articles/the-death-star-version-constraint?ref=phpunit) ) then you have to use the `install` command and explicitly request the new major version to be installed: phive install phpunit@^10.0 Phive 0.15.2 - Copyright (C) 2015-2024 by Arne Blankerts, Sebastian Heuer and Contributors Linking /home/sb/.phive/phars/phpunit-10.5.15.phar to /path/to/tools/phpunit #### What is inside the PHAR?[](https://docs.phpunit.de/en/12.4/installation.html#what-is-inside-the-phar "Permalink to this heading") To avoid [problems](https://github.com/sebastianbergmann/phpunit/issues/2014) that occur when the code under test shares dependencies with PHPUnit but requires different versions than the ones bundled in the PHAR, a couple of measures have been implemented. Most units of code bundled in PHPUnit’s PHAR distribution, including all dependencies such as vendor directories, are moved to a new and distinct namespace, for instance. Classes that are part of PHPUnit’s public API, for example `PHPUnit\Framework\TestCase`, are exempt from this. PHPUnit’s PHAR does not use dynamic autoloading to load the bundled units of code. Instead, all units of code bundled in the PHAR are loaded on startup. Here is an [article](https://thephp.cc/articles/ready-or-not-here-it-comes?ref=phpunit) that explains these measures in more detail. Sometimes you need to know exactly which versions of PHPUnit’s dependencies are bundled in PHPUnit’s PHAR distribution, for example in the context of [software supply chain security](https://thephp.cc/presentations/the-php-stacks-supply-chain?ref=phpunit) . For this purpose, PHPUnit’s PHAR distribution offers additional CLI options that the Composer-installed test runner does not have. When PHPUnit’s PHAR is invoked with the `--manifest` CLI option then it will print a plain-text manifest with information about the versions of PHPUnit’s dependencies that are bundled in the PHAR: php phpunit-10.5.1.phar --manifest phpunit/phpunit: 10.5.1 myclabs/deep-copy: 1.11.1 nikic/php-parser: v4.17.1 phar-io/manifest: 2.0.3 phar-io/version: 3.2.1 phpunit/php-code-coverage: 10.1.9 phpunit/php-file-iterator: 4.1.0 phpunit/php-invoker: 4.0.0 phpunit/php-text-template: 3.0.1 phpunit/php-timer: 6.0.0 sebastian/cli-parser: 2.0.0 sebastian/code-unit: 2.0.0 sebastian/code-unit-reverse-lookup: 3.0.0 sebastian/comparator: 5.0.1 sebastian/complexity: 3.1.0 sebastian/diff: 5.0.3 sebastian/environment: 6.0.1 sebastian/exporter: 5.1.1 sebastian/global-state: 6.0.1 sebastian/lines-of-code: 2.0.1 sebastian/object-enumerator: 5.0.0 sebastian/object-reflector: 3.0.0 sebastian/recursion-context: 5.0.0 sebastian/type: 4.0.0 sebastian/version: 4.0.1 theseer/tokenizer: 1.2.2 When PHPUnit’s PHAR is invoked with the `--sbom` CLI option then it will print a Software Bill of Materials (SBOM) in XML format with information about the versions of PHPUnit’s dependencies that are bundled in the PHAR: php phpunit-10.5.1.phar --sbom phpunit phpunit 10.5.1 The PHP Unit Testing framework. BSD-3-Clause pkg:composer/phpunit/phpunit@10.5.1 . . . When PHPUnit’s PHAR is invoked with the `--composer-lock` CLI option then it will print the `composer.lock` file that was used to install PHPUnit’s dependencies during the build of the PHAR: php phpunit-10.5.1.phar --composer-lock { "\_readme": \[\ "This file locks the dependencies of your project to a known state",\ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",\ "This file is @generated automatically"\ \], "content-hash": "e06728e5442edec84af96f94a889b4a7", . . . ### Composer[](https://docs.phpunit.de/en/12.4/installation.html#composer "Permalink to this heading") Using a PHP Archive (PHAR) is the recommended way of installing PHPUnit, but it is not the only way. You can add PHPUnit as a development-time dependency to your project using [Composer](https://getcomposer.org/) . #### Installing PHPUnit with Composer[](https://docs.phpunit.de/en/12.4/installation.html#installing-phpunit-with-composer "Permalink to this heading") The command shown below assumes that you have previously installed Composer and that its `composer` executable is on your `$PATH`. The installation of Composer is explained on the tool’s website. composer require --dev phpunit/phpunit After executing the command shown above the project’s directory will look like this: ├── composer.json ├── composer.lock ├── public ├── src ├── tests └── vendor The `composer.json` file contains metadata about the dependencies of your project, for instance. This file must be put under version control. The `composer.lock` file contains the list of the exact versions of the dependencies which were installed by Composer. While technically not required, it is considered a best practice to put this file under version control. The project-local installation of PHPUnit can be invoked like this: ./vendor/bin/phpunit --version PHPUnit 10.0.0 by Sebastian Bergmann and contributors. #### Updating PHPUnit with Composer[](https://docs.phpunit.de/en/12.4/installation.html#updating-phpunit-with-composer "Permalink to this heading") `composer require --dev phpunit/phpunit` adds a development-time dependency on PHPUnit with a version constraint that uses the caret operator (`^`) for semantic versioning: `"phpunit/phpunit": "^10.0"`. With this configuration, Composer will always install the latest version of PHPUnit that is compatible with PHPUnit 10.0. This ensures you “stay fresh” as long as PHPUnit 10 is the current stable version of PHPUnit and includes new minor versions such as PHPUnit 10.1. And when the time comes and PHPUnit 11 is released then Composer will not automatically and unexpectedly install it. ##### Updating to a new minor or patch version[](https://docs.phpunit.de/en/12.4/installation.html#id4 "Permalink to this heading") Consider the following situation: { "require-dev": { "phpunit/phpunit": "^9.6" } } Using the `composer outdated` command we can see that we have PHPUnit 9.6.0 in our project and that a new patch version is available: composer outdated --minor-only Legend: ! patch or minor release available - update recommended ~ major release available - update possible Direct dependencies required in composer.json: phpunit/phpunit 9.6.0 ! 9.6.3 The PHP Unit Testing framework. Because PHPUnit 9.6.3 is a new patch version, `composer update` will update from PHPUnit 9.6.0 to PHPUnit 9.6.3. ##### Updating to a new major version[](https://docs.phpunit.de/en/12.4/installation.html#id5 "Permalink to this heading") Consider the following situation: { "require-dev": { "phpunit/phpunit": "^9.6" } } Using the `composer outdated` command we can see that we have PHPUnit 9.6.3 in our project and that a new major version is available: composer outdated Legend: ! patch or minor release available - update recommended ~ major release available - update possible Direct dependencies required in composer.json: phpunit/phpunit 9.6.3 ~ 10.0.7 The PHP Unit Testing framework. Because PHPUnit 10 is a new major version, `composer update` will not update from PHPUnit 9.6.3 to PHPUnit 10.0.7. Updates to a new major version should be an explicit operation following a conscious decision. If you use semantic version constraints in your `composer.json` file ([and you should!](https://thephp.cc/articles/the-death-star-version-constraint?ref=phpunit) ) then you will have to manually update PHPUnit’s version constraint when you want to update to a new major version. Here is what you should do: edit your project’s `composer.json` file and change `^9.6` to `^10.0`: { "require-dev": { "phpunit/phpunit": "^10.0" } } Now we can run `composer update` and the new major version will be installed. ### PHAR or Composer?[](https://docs.phpunit.de/en/12.4/installation.html#phar-or-composer "Permalink to this heading") According to its own documentation, Composer “\[e\]nables you to declare the libraries you depend on” and “\[f\]inds out which versions of which packages can and need to be installed, and installs them (meaning it downloads them into your project)”. This is exactly what you need – and want – for dealing with your project’s dependencies that are required at runtime. It is, however, not what you want for your project’s development-time dependencies, for instance tools for static analysis. While Composer allows for the separate declaration of dependencies that are only required during development and dependencies that are actually required to run the software, the implementation of this separation is merely cosmetic: the entirety of both development-time dependencies and runtime dependencies is resolved to one installable set. This set of dependencies is then installed into the same `vendor` directory. What happens, for instance, when a tool that you install using Composer requires a version of a library that is not compatible with the version of that library that is required by another tool – or even by your own software? Such a conflict cannot be resolved and Composer will abort the installation process. The really frustrating thing about this situation is the fact that such a conflict is, in most cases, unwarranted. A static analysis tool, for instance, never loads or executes the code of your software (it only looks at it in order to reason about it). Therefore, the conflicting versions of the library – one depended upon by your software, the other depended upon by the tool – are never (tried to be) loaded in the same PHP process. Hence: no problem. This is the primary reason why I do not use Composer to install a tool but instead use a PHP Archive (PHAR). The self-contained PHAR of a tool ensures that its dependencies cannot conflict with the actual software’s dependencies. ### Global Installation[](https://docs.phpunit.de/en/12.4/installation.html#global-installation "Permalink to this heading") So far we have discussed how to install PHPUnit on a per-project basis using a PHP Archive (PHAR) – manually as well as using Phive – and Composer. For the sake of completeness, we shall also discuss the possibility of installing PHPUnit globally. What we mean by that is having one global installation of PHPUnit where the command-line tool, `phpunit`, is on your `$PATH` to make it globally available in all your projects. A common approach for installing PHPUnit globally is to download a release of PHPUnit packaged as a PHP archive, make it executable, and put it into your `$PATH`: wget -O phpunit.phar https://phar.phpunit.de/phpunit-10.phar chmod +x phpunit.phar sudo mv phpunit.phar /usr/local/bin/phpunit phpunit --version PHPUnit 10.0.0 by Sebastian Bergmann and contributors. Both Composer and Phive can be used to perform a global installation of PHPUnit. Using such a global installation of PHPUnit is almost always a bad idea as the different projects you work on may require different versions of PHPUnit, for instance. It is therefore best to use a project-local installation of the version of PHPUnit that should be used for the project at hand. Consequently, the package manager of your operating system should not be used to install PHPUnit as this would result in a global installation of PHPUnit. ### Web Server[](https://docs.phpunit.de/en/12.4/installation.html#web-server "Permalink to this heading") PHPUnit is a framework for writing as well as a command-line tool for running tests. Writing and running tests is a development-time activity. There is no reason why PHPUnit should be installed on a web server. If you put PHPUnit on a web server then your deployment process is broken. On a more general note, if your `vendor` directory is publicly accessible on your web server then your deployment process is also broken. [Please note that if you put PHPUnit on a web server “bad things” may happen. You have been warned.](https://thephp.cc/articles/phpunit-a-security-risk?ref=phpunit) Make sure your deployment process does not make PHPUnit, or any other development tool, publicly accessible on a web server. --- # 3. The Command-Line Test Runner — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 3\. The Command-Line Test Runner * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/textui.rst) * * * 3\. The Command-Line Test Runner[](https://docs.phpunit.de/en/12.4/textui.html#the-command-line-test-runner "Permalink to this heading") ========================================================================================================================================== The PHPUnit command-line test runner can be invoked through the `phpunit` command. The following code shows how to run tests with the PHPUnit command-line test runner: ./tools/phpunit tests/ArrayTest.php PHPUnit 12.4.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.2 .. 2 / 2 (100%) Time: 00:00.077, Memory: 10.00 MB OK (2 tests, 2 assertions) When invoked as shown above, the PHPUnit command-line test runner will look for a `ArrayTest.php` source code file in the current working directory, load it, and expect to find an `ArrayTest` test case class. It will then run the tests found in that class. Outcome and Issues[](https://docs.phpunit.de/en/12.4/textui.html#outcome-and-issues "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------ PHPUnit separates the _outcome_ (errored, failed, incomplete, skipped, or passed) of a test from the _issues_ (considered risky, triggered a warning, …) of a test. With regard to outcome, PHPUnit distinguishes between _failures_ and _errors_. A test fails when an assertion failed. This is different from an unexpected exception or a PHP error that occur while a test is running. When this happens, the test errors. Errors tend to be easier to fix than failures. If you have a big list of problems, it is best to tackle the errors first and see if you have any failures left when they are all fixed. Output[](https://docs.phpunit.de/en/12.4/textui.html#output "Permalink to this heading") ------------------------------------------------------------------------------------------ The default output of PHPUnit’s test runner consists of up to four sections. ### Versions and Configuration[](https://docs.phpunit.de/en/12.4/textui.html#versions-and-configuration "Permalink to this heading") This section contains information about the PHPUnit version, PHP version, and PHPUnit’s XML configuration file. This section can be disabled using the `--no-output` CLI option. ### Progress[](https://docs.phpunit.de/en/12.4/textui.html#progress "Permalink to this heading") This section is printed to indicate progress while the tests are being run: For each test run, the PHPUnit command-line tool prints one character to indicate progress: `.` > Printed when a successful test has no issues `F` > Printed when an assertion fails while running the test method `E` > Printed when an error occurs while running the test method `W` > Printed when the test triggered a warning `R` > Printed when the test has been considered risky (see [Risky Tests](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests) > ) `D` > Printed when the test triggered a deprecation `N` > Printed when the test triggered a notice `I` > Printed when the test is marked as incomplete (see [Incomplete Tests](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-incomplete-tests) > ) `S` > Printed when the test was skipped (see [Skipping Tests](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests) > ) This section can be disabled using the `--no-progress` and `--no-output` CLI options. ### Test Results[](https://docs.phpunit.de/en/12.4/textui.html#test-results "Permalink to this heading") This section contains information about errors, failures, skipped tests, incomplete tests, and issues. By default, only information about errors and failures is printed. This section is only printed when there are errors, failures, or issues to report. It can be disabled using the `--no-results` and `--no-output` CLI options. ### Summary[](https://docs.phpunit.de/en/12.4/textui.html#summary "Permalink to this heading") This section contains a summary of the test suite execution. * When no test errored or failed then the summary will be `OK` * When a test errored then the summary will be `ERRORED!` * When a test failed and no test errored then the summary will be `FAILED!` * When there were no errors, failures, or issues, but a test was skipped, then the summary will be `OK, but some tests were skipped!` * When there were no errors, failures, skipped tests, or issues then the summary will be `OK, but there were issues!` `--fail-on-*` Please note that if you use CLI options such as `--fail-on-deprecation`, for example, or their XML configuration counterparts, then this only affects the test runner’s shell exit code. It does not have an effect on whether or not `OK` will be printed in the output’s summary section. This section can be disabled using the `--no-output` CLI option. Command-Line Options[](https://docs.phpunit.de/en/12.4/textui.html#command-line-options "Permalink to this heading") ---------------------------------------------------------------------------------------------------------------------- ### Configuration[](https://docs.phpunit.de/en/12.4/textui.html#configuration "Permalink to this heading") `--bootstrap ` > Configures a PHP script that is included before the tests run. For common use cases, this script should not do more than register an autoloader so that PHP can find the tested units of code. `-c|--configuration ` > Configure PHPUnit’s test runner using an XML configuration file. This is not required when the configuration file that is to be used is located in the current working directory and is named `phpunit.xml`, `phpunit.dist.xml`, or `phpunit.xml.dist`. `--no-configuration` > Do not use an XML configuration named `phpunit.xml`, `phpunit.dist.xml`, or `phpunit.xml.dist` that is located in the current working directory. `--no-extensions` > Do not load PHPUnit test runner extensions from PHP archives (PHARs) from a directory that is configured in the XML configuration file. Do not bootstrap PHPUnit test runner extensions that are configured in the XML configuration file. `--include-path ` > Prepend PHP’s `include_path` with given path(s). `-d ` > Set a PHP configuration setting (php.ini). `--cache-directory ` > Configure a directory where the PHPUnit test runner can cache data such as test results (required for reordering tests based on previous failures, for instance) or information about tested code as well as test code generated using static analysis (significantly improves performance of code coverage analysis, for instance). `--generate-configuration` > Generate an XML configuration file with best practice defaults. `--migrate-configuration` > Migrate an XML configuration file from a previous version’s format to the current format. ### Selection[](https://docs.phpunit.de/en/12.4/textui.html#selection "Permalink to this heading") `--list-suites` > List available test suites as defined in the XML configuration file. See [Composing a Test Suite Using XML Configuration](https://docs.phpunit.de/en/12.4/organizing-tests.html#organizing-tests-xml-configuration) > for an example. `--testsuite ` > Only run tests from the specified list of comma-separated test suites that are defined in the XML configuration file. See [Composing a Test Suite Using XML Configuration](https://docs.phpunit.de/en/12.4/organizing-tests.html#organizing-tests-xml-configuration) > for an example. `--exclude-testsuite ` > Run all tests except for those from the specified list of comma-separated test suites that are defined in the XML configuration file. `--list-groups` > List available test groups. Tests can be put into multiple test groups using the attributes `PHPUnit\Framework\Attributes\Group`, `PHPUnit\Framework\Attributes\Small`, `PHPUnit\Framework\Attributes\Medium`, `PHPUnit\Framework\Attributes\Large`, and `PHPUnit\Framework\Attributes\Ticket`. `--group ` > Only run tests from the specified list of comma-separated test groups. `--exclude-group ` > Run all tests except for those from the specified list of comma-separated test groups. `--covers ` > Only run tests that intend to cover `` and use code coverage metadata such as `PHPUnit\Framework\Attributes\CoversClass` to document this. `--uses ` > Only run tests that intend to use `` and use code coverage metadata such as `PHPUnit\Framework\Attributes\UsesClass` to document this. `--requires-php-extension ` > Only run tests that require PHP extension ``. `--list-tests` > Print a list of tests. `--list-tests-xml ` > Write a list of tests in XML format to a file. `--filter ` > Filter which tests to run using pattern matching on the test name. `--filter ` may be used multiple times and then combines the individual filters into a single filter using a _logical and_. `--test-suffix ` > Only search for tests in files with specified suffix(es). Default: `Test.php`, `.phpt`. ### Execution[](https://docs.phpunit.de/en/12.4/textui.html#execution "Permalink to this heading") #### Isolation[](https://docs.phpunit.de/en/12.4/textui.html#isolation "Permalink to this heading") `--process-isolation` > Run each test in a separate PHP process. `--globals-backup` > Backup global and super-global variables before each test, restore them after each test. `--static-backup` > Backup static properties of classes before each test, restore them after each test. #### Risky Tests[](https://docs.phpunit.de/en/12.4/textui.html#risky-tests "Permalink to this heading") `--strict-coverage` > Be strict about code coverage metadata. See [Unintentionally Covered Code](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-unintentionally-covered-code) > for more details. `--strict-global-state` > Be strict about changes to global state. See [Global State Manipulation](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-global-state-manipulation) > for more details. `--disallow-test-output` > Be strict about output during tests. See [Output During Test Execution](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-output-during-test-execution) > for more details. `--enforce-time-limit` > Enforce time limit based on test size. See [Test Execution Timeout](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-test-execution-timeout) > for more details. `--default-time-limit ` > Timeout in seconds for tests that have no declared size. See [Test Execution Timeout](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-test-execution-timeout) > for more details. `--dont-report-useless-tests` > Do not report tests that do not test anything. See [Useless Tests](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-useless-tests) > for more details on the default behaviour. #### Automatically stop when …[](https://docs.phpunit.de/en/12.4/textui.html#automatically-stop-when "Permalink to this heading") `--stop-on-defect` > Stop execution upon first that errored, failed, that triggered a warning, or that was considered risky. `--stop-on-error` > Stop execution upon first that errored. `--stop-on-failure` > Stop execution upon first that failed. `--stop-on-warning` > Stop execution upon first that triggered a warning. `--stop-on-risky` > Stop execution upon first that was considered risky. `--stop-on-deprecation` > Stop execution upon first that triggered a deprecation (`E_DEPRECATED`, `E_USER_DEPRECATED`, or PHPUnit deprecation). `--stop-on-notice` > Stop execution upon first that triggered a notice (`E_STRICT`, `E_NOTICE`, or `E_USER_NOTICE`). `--stop-on-skipped` > Stop execution upon first that was skipped. `--stop-on-incomplete` > Stop execution upon first that was marked as incomplete. #### Exit with error code when …[](https://docs.phpunit.de/en/12.4/textui.html#exit-with-error-code-when "Permalink to this heading") `--fail-on-warning` > Exit with a shell exit code that signals failure even when all tests passed but at least one test triggered a warning. `--fail-on-risky` > Exit with a shell exit code that signals failure even when all tests passed but at least one test was considered risky. `--fail-on-deprecation` > Exit with a shell exit code that signals failure even when all tests passed but at least one test triggered a deprecation (`E_DEPRECATED` or `E_USER_DEPRECATED`). `--fail-on-phpunit-deprecation` > Exit with a shell exit code that signals failure even when all tests passed but at least one PHPUnit deprecation was triggered. `--fail-on-notice` > Exit with a shell exit code that signals failure even when all tests passed but at least one test triggered a notice (`E_STRICT`, `E_NOTICE`, or `E_USER_NOTICE`). `--fail-on-incomplete` > Exit with a shell exit code that signals failure even when all tests passed but at least one test was marked as incomplete. `--fail-on-skipped` > Exit with a shell exit code that signals failure even when all tests passed but at least one test was skipped. #### Test Result Cache[](https://docs.phpunit.de/en/12.4/textui.html#test-result-cache "Permalink to this heading") `--cache-result` > Write test results to cache file. This is required for reordering tests based on previous failures, for instance. `--do-not-cache-result` > Do not write test results to cache file. #### Test Order[](https://docs.phpunit.de/en/12.4/textui.html#test-order "Permalink to this heading") `--order-by ` > Reorder tests using `` strategy before running them. `` can be a comma-separated list of `default`, `defects`, `depends`, `duration`, `no-depends`, `random`, `reverse`, and `size`. `--random-order-seed ` > Use the specified random seed when running tests in random order. ### Reporting[](https://docs.phpunit.de/en/12.4/textui.html#reporting "Permalink to this heading") #### Console[](https://docs.phpunit.de/en/12.4/textui.html#console "Permalink to this heading") `--colors ` > Use colors in output (`never`, `auto`, or `always`) `--columns ` > Number of columns to use for progress output. `--columns max` > Use maximum number of columns for progress output. `--stderr` > Write to php://stderr instead of php://stdout. #### Progress and Result Printing[](https://docs.phpunit.de/en/12.4/textui.html#progress-and-result-printing "Permalink to this heading") `--no-progress` > Disable output of test execution progress. `--no-results` > Disable output of test results. `--no-output` > Disable all output. #### Details about Issues[](https://docs.phpunit.de/en/12.4/textui.html#details-about-issues "Permalink to this heading") `--display-incomplete` > Display details for incomplete tests. `--display-skipped` > Display details for skipped tests. `--display-deprecations` > Display details for deprecations triggered by tests. `--display-phpunit-deprecations` > Display details for PHPUnit deprecations. `--display-errors` > Display details for errors triggered by tests. `--display-notices` > Display details for notices triggered by tests. `--display-warnings` > Display details for warnings triggered by tests. `--display-all-issues` > Display details for all issues. Backward Compatibility Please note that if you use `--display-all-issues` then you opt in to printing additional issues in later versions of PHPUnit that will be put under the control of this CLI option. This is not considered to be a break of backward compatibility and rather the expected behaviour of this CLI option. `--reverse-list` > Print defects in reverse order. #### Alternative Output[](https://docs.phpunit.de/en/12.4/textui.html#alternative-output "Permalink to this heading") `--teamcity` > Replace default progress and result output with TeamCity format. `--testdox` > Replace default result output with TestDox format. `--testdox-summary` > Repeat TestDox output for non-successful tests after the regular TestDox output. This only has an effect when the `--testdox` option (see above) is also used. ### Logging[](https://docs.phpunit.de/en/12.4/textui.html#logging "Permalink to this heading") `--log-junit ` > Write test results in JUnit XML format to file. `--log-teamcity ` > Write test results in TeamCity format to file. `--testdox-html ` > Write test results in TestDox format (HTML) to file. `--testdox-text ` > Write test results in TestDox format (plain text) to file. `--log-events-text ` > Stream events as plain text to file. `--log-events-verbose-text ` > Stream events as plain text (with telemetry information) to file. `--no-logging` > Ignore logging configured in the XML configuration file. #### Code Coverage[](https://docs.phpunit.de/en/12.4/textui.html#code-coverage "Permalink to this heading") `--coverage-clover ` > Write code coverage report in Clover XML format to file. `--coverage-cobertura ` > Write code coverage report in Cobertura XML format to file. `--coverage-crap4j ` > Write code coverage report in Crap4J XML format to file. `--coverage-html ` > Write code coverage report in HTML format to directory. `--coverage-php ` > Write serialized code coverage data to file. `--coverage-text=` > Write code coverage report in text format to file (default: `php://stdout`). `--coverage-xml ` > Write code coverage report in XML format to directory. `--warm-coverage-cache` > Warm cache for static analysis that is needed for code coverage reporting. `--coverage-filter ` > Include `` in code coverage reporting. `--path-coverage` > Report path coverage in addition to line coverage. `--disable-coverage-ignore` > Disable metadata for ignoring code coverage. `--no-coverage` > Ignore code coverage reporting configured in the XML configuration file. #### Miscellaneous[](https://docs.phpunit.de/en/12.4/textui.html#miscellaneous "Permalink to this heading") `-h|--help` > Prints usage information. `--version` > Prints the version and exits. `--atleast-version ` > Checks that version is greater than `` and exits. `--check-version` > Check whether PHPUnit is the latest version and exits. --- # 4. Organizing Tests — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 4\. Organizing Tests * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/organizing-tests.rst) * * * 4\. Organizing Tests[](https://docs.phpunit.de/en/12.4/organizing-tests.html#organizing-tests "Permalink to this heading") ============================================================================================================================ One of the goals of PHPUnit is that tests should be composable: we want to be able to run any number or combination of tests together, for instance all tests for the whole project, or the tests for all classes of a component that is part of the project, or just the tests for a single class. PHPUnit supports different ways of organizing tests and composing them into a test suite. This chapter shows the most commonly used approaches. Composing a Test Suite Using the Filesystem[](https://docs.phpunit.de/en/12.4/organizing-tests.html#composing-a-test-suite-using-the-filesystem "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Probably the easiest way to compose a test suite is to keep all test case source files in a test directory. PHPUnit can automatically discover and run the tests by recursively traversing the test directory. Lets take a look at the test suite of the [sebastianbergmann/raytracer](https://github.com/sebastianbergmann/raytracer) project. Looking at this project’s directory structure, we see that the test case classes in the `tests/unit` directory mirror the package and class structure of the System Under Test (SUT) in the `src` directory: src tests/unit ├── autoload.php ├── CameraTest.php ├── Camera.php ├── canvas ├── canvas │   ├── AnsiMapperTest.php │   ├── AnsiMapper.php │   ├── CanvasTest.php │   ├── CanvasIterator.php │   └── PortablePixmapMapperTest.php │   ├── Canvas.php ├── ColorTest.php │   ├── PortablePixmapMapper.php ├── intersection │   └── WebpMapper.php │   ├── IntersectionCollectionTest.php ├── Color.php │   └── IntersectionTest.php ├── exceptions ├── material │   ├── Exception.php │   ├── CheckersPatternTest.php │   ├── IntersectionHasNoHitException.php │   ├── GradientPatternTest.php │   ├── InvalidArgumentException.php │   ├── MaterialTest.php │   ├── OutOfBoundsException.php │   ├── PatternTest.php │   ├── RuntimeException.php │   ├── RingPatternTest.php │   └── WorldHasNoLightException.php │   └── StripePatternTest.php ├── intersection ├── math │   ├── IntersectionCollectionIterator.php │   ├── MatrixTest.php │   ├── IntersectionCollection.php │   ├── RayTest.php │   ├── Intersection.php │   ├── TransformationsTest.php │   └── PreparedComputation.php │   └── TupleTest.php ├── material ├── PointLightTest.php │   ├── CheckersPattern.php ├── shapes │   ├── GradientPattern.php │   ├── PlaneTest.php │   ├── Material.php │   ├── ShapeCollectionTest.php │   ├── Pattern.php │   ├── ShapeTest.php │   ├── RingPattern.php │   └── SphereTest.php │   └── StripePattern.php └── WorldTest.php ├── math │   ├── Matrix.php tests/integration │   ├── Ray.php └── PuttingItTogetherTest.php │   ├── Transformations.php │   └── Tuple.php ├── PointLight.php ├── shapes │   ├── Plane.php │   ├── ShapeCollectionIterator.php │   ├── ShapeCollection.php │   ├── Shape.php │   └── Sphere.php └── World.php The `tests/integration` directory contains integration test cases that are kept separate from the `tests/unit` directory’s unit tests. To run all tests for this project we need to point the PHPUnit command-line test runner to the test directory: $ ./tools/phpunit --bootstrap tests/bootstrap.php tests PHPUnit 12.4.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.2 ............................................................... 63 / 177 ( 35%) ............................................................... 126 / 177 ( 71%) ................................................... 177 / 177 (100%) Time: 00:17.100, Memory: 28.27 MB OK (177 tests, 657 assertions) Note If you point the PHPUnit command-line test runner to a directory it will look for `*Test.php` files. To run only the tests that are declared in the `WorldTest` test case class in `tests/unit/WorldTest.php` we can use the following command: $ ./tools/phpunit --bootstrap src/autoload.php tests/unit/WorldTest.php PHPUnit 12.4.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.2 ............. 13 / 13 (100%) Time: 00:00.095, Memory: 8.00 MB OK (13 tests, 30 assertions) For more fine-grained control of which tests to run we can use the `--filter` option: $ ./tools/phpunit --bootstrap src/autoload.php tests/unit --filter test\_creating\_a\_world PHPUnit 12.4.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.2 . 1 / 1 (100%) Time: 00:00.077, Memory: 10.00 MB OK (1 test, 2 assertions) Composing a Test Suite Using XML Configuration[](https://docs.phpunit.de/en/12.4/organizing-tests.html#composing-a-test-suite-using-xml-configuration "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ PHPUnit’s XML configuration file ([The XML Configuration File](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration) ) can also be used to compose a test suite. [Example 4.1](https://docs.phpunit.de/en/12.4/organizing-tests.html#organizing-tests-xml-configuration-examples-phpunit-xml) shows a minimal `phpunit.xml` file that will add all `*Test` classes that are found in `*Test.php` files when the `tests` directory is recursively traversed. Example 4.1 Composing a Test Suite Using XML Configuration[](https://docs.phpunit.de/en/12.4/organizing-tests.html#organizing-tests-xml-configuration-examples-phpunit-xml "Permalink to this code") tests/unit tests/integration Note You should reference the schema definition that is appropriate for the PHPUnit version you are using in your XML configuration file. The schema definition for PHPUnit 12.4 can always be found at [https://schema.phpunit.de/](https://schema.phpunit.de/) 12.4/phpunit.xsd, for instance. Now that we have an XML configuration file, we can invoke the PHPUnit test runner without arguments (`tests`, for instance) or options (`--bootstrap`, for instance) to run our tests: $ ./tools/phpunit PHPUnit 12.4.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.2 Configuration: /path/to/raytracer/phpunit.xml ............................................................... 63 / 177 ( 35%) ............................................................... 126 / 177 ( 71%) ................................................... 177 / 177 (100%) Time: 00:17.100, Memory: 28.27 MB OK (177 tests, 657 assertions) The PHPUnit test runner’s `--list-suites` option can be used to print a list of all test suites defined in PHPUnit’s XML configuration file: $ ./tools/phpunit --list-suites PHPUnit 12.4.0 by Sebastian Bergmann and contributors. Available test suite(s): - unit - integration We can use the PHPUnit test runner’s `--testsuite` option to limit the tests that are run to the tests of a specific test suite that is declared in the XML configuration file: $ ./tools/phpunit --testsuite unit PHPUnit 12.4.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.2 Configuration: /path/to/raytracer/phpunit.xml ............................................................... 63 / 172 ( 36%) ............................................................... 126 / 172 ( 73%) .............................................. 172 / 172 (100%) Time: 00:00.213, Memory: 24.27 MB OK (172 tests, 637 assertions) --- # 2. Writing Tests for PHPUnit — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 2\. Writing Tests for PHPUnit * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/writing-tests-for-phpunit.rst) * * * 2\. Writing Tests for PHPUnit[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit "Permalink to this heading") ======================================================================================================================================================= Asserting Return Values[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#asserting-return-values "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------------------------- This first example introduces the basic conventions and steps for writing tests with PHPUnit: 1. The tests for a class `Greeter` go into a class `GreeterTest`. 2. `GreeterTest` inherits from `PHPUnit\Framework\TestCase`. 3. The tests are public methods that are named `test*`. Alternatively, you can use the `PHPUnit\Framework\Attributes\Test` attribute on a method to mark it as a test method. See the section on the [Test](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-test) attribute for details. 4. Inside the test methods, assertion methods such as `assertSame()` (see [Assertions](https://docs.phpunit.de/en/12.4/assertions.html#appendixes-assertions) ) are used to assert that an actual value matches an expected value, for instance. Example 2.1 A class named `Greeter` (declared in `src/Greeter.php`)[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-examples-greeter-php "Permalink to this code") greet('Alice'); $this\->assertSame('Hello, Alice!', $greeting); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/GreeterTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 . 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB OK (1 test, 1 assertion) Martin Fowler once said: > Whenever you are tempted to type something into a `print` statement or a debugger expression, write it as a test instead. Expecting Exceptions[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#expecting-exceptions "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------------------- [Example 2.3](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-exceptions-examples-exceptiontest-php) shows how to use the `expectException()` method to test whether an exception is thrown by the code under test. Example 2.3 Using the expectException() method[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-exceptions-examples-exceptiontest-php "Permalink to this code") expectException(InvalidArgumentException::class); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ExceptionTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ExceptionTest::testException Failed asserting that exception of type "InvalidArgumentException" is thrown. FAILURES! Tests: 1, Assertions: 1, Failures: 1. The `expectException()` method has to be used **before** the exception you expect to be thrown is thrown. Ideally, `expectException()` is called immediately before the code is called that is expected to throw the exception. In addition to the `expectException()` method the `expectExceptionCode()`, `expectExceptionMessage()`, and `expectExceptionMessageMatches()` methods exist to set up expectations for exceptions raised by the code under test. Note Note that `expectExceptionMessage()` asserts that the `$actual` message contains the `$expected` message and does not perform an exact string comparison. Asserting return values and expecting exceptions are two of the three most commonly performed operations in a test method. The third is verifying side effects. The verification of side effects in object collaboration is discussed in the chapter on [Test Doubles](https://docs.phpunit.de/en/12.4/test-doubles.html#test-doubles) . Data Providers[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#data-providers "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------- A test method can accept arbitrary arguments. These arguments are to be provided by one or more data provider methods (`additionProvider()` in the example shown below). The data provider method to be used is specified using the `PHPUnit\Framework\Attributes\DataProvider` or the `PHPUnit\Framework\Attributes\DataProviderExternal` attribute. A data provider method must be `public` and `static` and its name must not start with `test`. It must return a value that is [iterable](https://www.php.net/manual/en/language.types.iterable.php) , either an array or an object that implements the `Traversable` interface. In each iteration step, it must yield an array. For each of these arrays, the test method will be called with the contents of the array as its arguments. Example 2.4 Using a data provider that returns an array of arrays[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-data-providers-examples-numericdatasetstest-php "Permalink to this code") assertSame($expected, $a + $b); } } Example 2.5 Using an external data provider that returns an array of arrays[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-data-providers-examples-numericdatasetstestusingexternaldataprovider-php "Permalink to this code") assertSame($expected, $a + $b); } } final class ExternalDataProvider { public static function additionProvider(): array { return \[\ \[0, 0, 0\],\ \[0, 1, 1\],\ \[1, 0, 1\],\ \[1, 1, 3\],\ \]; } } Running the test shown above yields the output shown below: ./tools/phpunit tests/NumericDataSetsTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 ...F 4 / 4 (100%) Time: 00:00.001, Memory: 15.81 MB There was 1 failure: 1) NumericDataSetsTest::testAdd#3 with data (1, 1, 3) Failed asserting that 2 is identical to 3. /path/to/tests/NumericDataSetsTest.php:20 FAILURES! Tests: 4, Assertions: 4, Failures: 1. It is useful to name each one with a string key. Output will be more verbose as it will contain that name of a dataset that breaks a test. Example 2.6 Using a data provider with named data sets[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-data-providers-examples-nameddatasetstest-php "Permalink to this code") \[0, 0, 0\],\ 'zero plus one' \=> \[0, 1, 1\],\ 'one plus zero' \=> \[1, 0, 1\],\ 'one plus one' \=> \[1, 1, 3\],\ \]; } #\[DataProvider('additionProvider')\] 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/NamedDataSetsTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 ...F 4 / 4 (100%) Time: 00:00.001, Memory: 15.81 MB There was 1 failure: 1) NamedDataSetsTest::testAdd@one plus one with data (1, 1, 3) Failed asserting that 2 is identical to 3. /path/to/tests/NamedDataSetsTest.php:20 FAILURES! Tests: 4, Assertions: 4, Failures: 1. Note You can make the test output more verbose by defining a sentence and using the test’s parameter names as placeholders (`$a`, `$b` and `$expected` in the example above) with the [TestDox](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-testdox) attribute. You can also refer to the name of a named data set with `$_dataName`. When a test receives input from both a data provider method and from one or more tests it depends on, the arguments from the data provider will come before the ones from depended-upon tests. The arguments from depended-upon tests will be the same for each data set. When a test depends on a test that uses data providers, the depending test will be executed when the test it depends upon is successful for at least one data set. The result of a test that uses data providers cannot be injected into a depending test. Note All data providers, including those for test methods that will not be run due to `--filter` or `--exclude-group`, for example, are executed before both the call to the `setUpBeforeClass()` static method and the first call to the `setUp()` method. You cannot access any properties of the actual test case object in methods such as `setUpBeforeClass()` or `setUp()` within a data provider. Note No code coverage data is collected while data provider methods are executed. Note The data sets provided by a data provider method should only contain (arrays of) scalar values, immutable value objects, or Test Stubs. Services or large objects graphs should not be created in a data provider method. Mock Objects cannot be created in a data provider method. Testing Output[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#testing-output "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------- Sometimes you want to assert that the execution of a method, for instance, generates an expected output (via `echo` or `print`, for example). The `PHPUnit\Framework\TestCase` class uses PHP’s [Output Buffering](http://www.php.net/manual/en/ref.outcontrol.php) feature to provide the functionality that is necessary for this. [Example 2.7](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-output-examples-outputtest-php) shows how to use the `expectOutputString()` method to set the expected output. If this expected output is not generated, the test will be counted as a failure. Example 2.7 Testing the output of a function or method[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-output-examples-outputtest-php "Permalink to this code") expectOutputString('foo'); print 'foo'; } public function testExpectBarActualBaz(): void { $this\->expectOutputString('bar'); print 'baz'; } } Running the test shown above yields the output shown below: ./tools/phpunit tests/OutputTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 .F 2 / 2 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) OutputTest::testExpectBarActualBaz Failed asserting that two strings are identical. --- Expected +++ Actual @@ @@ -'bar' +'baz' FAILURES! Tests: 2, Assertions: 2, Failures: 1. [Table 2.1](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-output-tables-api) shows the methods provided for testing output | | | | --- | --- |Table 2.1 Methods for testing output[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-output-tables-api "Permalink to this table") | Method | Meaning | | --- | --- | | `void expectOutputRegex(string $regularExpression)` | Set up the expectation that the output matches a `$regularExpression`. | | `void expectOutputString(string $expectedString)` | Set up the expectation that the output is equal to an `$expectedString`. | Incomplete Tests[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#incomplete-tests "Permalink to this heading") --------------------------------------------------------------------------------------------------------------------------------- When you are working on a new test case class, you might want to begin by writing empty test methods such as: public function testSomething(): void { } to keep track of the tests that you have to write. Note Do yourself a favour and never use pointless names such as `testSomething` for your test methods. The problem with empty test methods is that they cannot fail and may be misinterpreted as a success. This misinterpretation leads to the test reports being useless – you cannot see whether a test is actually successful or just not implemented yet. Calling `$this->assertTrue(false)`, for instance, in the unfinished test method does not help either, since then the test will be interpreted as a failure. This would be just as wrong as interpreting an unimplemented test as a success. If we think of a successful test as a green light and a test failure as a red light, then we need an additional yellow light to mark a test as being incomplete or not yet implemented. By calling the method `markTestIncomplete()` in a test method, we can mark the test as incomplete: Example 2.8 Marking a test as incomplete[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-incomplete-tests-examples-workinprogresstest-php "Permalink to this code") assertTrue(true, 'This should already work.'); // Stop here and mark this test as incomplete. $this\->markTestIncomplete( 'This test has not been implemented yet.', ); } } An incomplete test is denoted by an `I` in the output of the PHPUnit command-line test runner, as shown in the following example: ./tools/phpunit --display-incomplete tests/WorkInProgressTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 I 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 incomplete test: 1) WorkInProgressTest::testSomething This test has not been implemented yet. /path/to/tests/WorkInProgressTest.php:12 OK, but there were issues! Tests: 1, Assertions: 1, Incomplete: 1. Skipping Tests[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#skipping-tests "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------- Not all tests can be run in every environment. Consider, for instance, a database abstraction layer that has several drivers for the different database systems it supports. The tests for the MySQL driver can only be run if a MySQL server is available. [Example 2.9](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-examples-databasetest-php) shows a test case class, `DatabaseTest`, that contains one test method, `testConnection()`. In the test case class’ `setUp()` template method we check whether the MySQLi extension is available and use the `markTestSkipped()` method to skip the test if it is not. Example 2.9 Skipping a test[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-examples-databasetest-php "Permalink to this code") markTestSkipped( 'The PostgreSQL extension is not available', ); } } public function testConnection(): void { // ... } } A test that has been skipped is denoted by an `S` in the output of the PHPUnit command-line test runner, as shown in the following example: ./tools/phpunit --display-skipped tests/DatabaseTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 S 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 skipped test: 1) DatabaseTest::testConnection The PostgreSQL extension is not available OK, but some tests were skipped! Tests: 1, Assertions: 0, Skipped: 1. ### Skipping Tests using Attributes[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#skipping-tests-using-attributes "Permalink to this heading") In addition to the above methods it is also possible to use attributes to express common preconditions for a test case: * `RequiresFunction(string $functionName)` skips the test when no function with the specified name is declared * `RequiresMethod(string $className, string $functionName)` skips the test when no method with the specified name is declared * `RequiresOperatingSystem(string $regularExpression)` skips the test when the operating system’s name does not match the specified regular expression * `RequiresOperatingSystemFamily(string $operatingSystemFamily)` skips the test when the operating system’s family is not the specified one * `RequiresPhp(string $versionRequirement)` skips the test when the PHP version does not match the specified one * `RequiresPhpExtension(string $extension, ?string $versionRequirement)` skips the test when the specified PHP extension is not available * `RequiresPhpunit(string $versionRequirement)` skips the test when the PHPUnit version does not match the specified one * `RequiresSetting(string $setting, string $value)` skips the test when the specified PHP configuration setting is not set to the specified value All attributes listed above are declared in the `PHPUnit\Framework\Attributes` namespace. Example 2.10 Skipping a test using attributes[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-examples-databasetest-php-attributes "Permalink to this code") Unit Tests are primarily written as a good practice to help developers identify and fix bugs, to refactor code and to serve as documentation for a unit of software under test. To achieve these benefits, unit tests ideally should cover all the possible paths in a program. One unit test usually covers one specific path in one function or method. However a test method is not necessarily an encapsulated, independent entity. Often there are implicit dependencies between test methods, hidden in the implementation scenario of a test. 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. * A producer is a test method that yields its unit under test as return value. * A consumer is a test method that depends on one or more producers and their return values. This example shows how to use the `PHPUnit\Framework\Attributes\Depends` attribute to express dependencies between test methods: Example 2.11 Using the `Depends` attribute to express dependencies[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-examples-stacktest-php "Permalink to this code") assertEmpty($stack); return $stack; } #\[Depends('testEmpty')\] public function testPush(array $stack): array { $stack\[\] \= 'foo'; $this\->assertSame('foo', $stack\[count($stack) \- 1\]); $this\->assertNotEmpty($stack); return $stack; } #\[Depends('testPush')\] public function testPop(array $stack): void { $this\->assertSame('foo', array\_pop($stack)); $this\->assertEmpty($stack); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/StackTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 ... 3 / 3 (100%) Time: 00:00.001, Memory: 15.81 MB OK (3 tests, 5 assertions) In the example above, the first test, `testEmpty()`, creates a new array and asserts that it is empty. The test then returns the fixture as its result. The second test, `testPush()`, depends on `testEmpty()` and is passed the result of that depended-upon test as its argument. Finally, `testPop()` depends upon `testPush()`. Note The return value yielded by a producer is passed “as-is” to its consumers by default. This means that when a producer returns an object, a reference to that object is passed to the consumers. Instead of a reference either (a) a (deep) copy via `DependsUsingDeepClone`, or (b) a (normal shallow) clone (based on PHP keyword `clone`) via `DependsUsingShallowClone` are possible, too. To localize defects, we want our attention to be focussed on relevant failing tests. This is why PHPUnit skips the execution of a test when a depended-upon test has failed. This improves defect localization by exploiting the dependencies between tests as shown in [Example 2.12](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-examples-dependencyfailuretest-php) . Example 2.12 Leveraging the dependencies between tests[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-examples-dependencyfailuretest-php "Permalink to this code") assertTrue(false); } #\[Depends('testOne')\] public function testTwo(): void { } } Running the test shown above yields the output shown below: ./tools/phpunit --display-skipped tests/DependencyFailureTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 FS 2 / 2 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) DependencyFailureTest::testOne Failed asserting that false is true. /path/to/tests/DependencyFailureTest.php:9 -- There was 1 skipped test: 1) DependencyFailureTest::testTwo This test depends on "DependencyFailureTest::testOne" to pass FAILURES! Tests: 2, Assertions: 1, Failures: 1, Skipped: 1. A test may have more than one test dependency attribute. By default, PHPUnit does not change the order in which tests are executed, so you have to ensure that the dependencies of a test can actually be met before the test is run. A test that has more than one test dependency attribute will get a fixture from the first producer as the first argument, a fixture from the second producer as the second argument, and so on. Failure Output[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#failure-output "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------- Whenever a test fails, PHPUnit tries its best to provide you with as much context as possible that can help to identify the problem. Example 2.13 Output generated when an array comparison fails[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-failure-output-examples-arraydifftest-php "Permalink to this code") assertSame( \[1, 2, 3, 4, 5, 6\], \[1, 2, 33, 4, 5, 6\], ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ArrayDiffTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ArrayDiffTest::testEquality Failed asserting that two arrays are identical. --- Expected +++ Actual @@ @@ Array &0 \[\ 0 => 1,\ 1 => 2,\ - 2 => 3,\ + 2 => 33,\ 3 => 4,\ 4 => 5,\ 5 => 6,\ \] /path/to/tests/ArrayDiffTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. In this example only one of the array values differs and the other values are shown to provide context on where the error occurred. When the generated output would be long to read PHPUnit will split it up and provide a few lines of context around every difference. Example 2.14 Output when an array comparison of a long array fails[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-failure-output-examples-longarraydifftest-php "Permalink to this code") assertSame( \[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6\], \[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 33, 4, 5, 6\], ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/LongArrayDiffTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) LongArrayDiffTest::testEquality Failed asserting that two arrays are identical. --- Expected +++ Actual @@ @@ 11 => 0, 12 => 1, 13 => 2, - 14 => 3, + 14 => 33, 15 => 4, 16 => 5, 17 => 6, \] /path/to/tests/LongArrayDiffTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### Edge Cases[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#edge-cases "Permalink to this heading") When a comparison fails PHPUnit creates textual representations of the input values and compares those. Due to that implementation a diff might show more problems than actually exist. This only happens when using `assertEquals()` or other “weak” comparison functions on arrays or objects. Example 2.15 Edge case in the diff generation when using weak comparison[](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-failure-output-edge-cases-examples-arrayweakcomparisontest-php "Permalink to this code") assertEquals( \[1, 2, 3, 4, 5, 6\], \['1', 2, 33, 4, 5, 6\], ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ArrayWeakComparisonTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ArrayWeakComparisonTest::testEquality Failed asserting that two arrays are equal. --- Expected +++ Actual @@ @@ Array ( - 0 => 1 + 0 => '1' 1 => 2 - 2 => 3 + 2 => 33 3 => 4 4 => 5 5 => 6 ) /path/to/tests/ArrayWeakComparisonTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. In this example the difference in the first index between `1` and `'1'` is reported even though `assertEquals()` considers the values as a match. --- # 5. Fixtures — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 5\. Fixtures * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/fixtures.rst) * * * 5\. Fixtures[](https://docs.phpunit.de/en/12.4/fixtures.html#fixtures "Permalink to this heading") ==================================================================================================== A test usually follows the “Arrange, Act, Assert” structure: **arranging** all necessary preconditions and inputs (the so-called _test fixture_), **acting** on the object under test, and **asserting** that the expected results have occurred. Arrange, Expect, Act When you expect an action to raise an exception or when you verify the communication between collaborating objects using mock objects then the test usually follows the “Arrange, Expect, Act” structure. Sometimes the _test fixture_ is made up of a single object, sometimes it is a more complex object graph, for instance. The amount of code needed to set it up will grow accordingly. The actual content of the test gets lost in the noise of setting up the test fixture. This problem gets even worse when you write several tests with similar test fixtures. PHPUnit supports the reuse of setup code between tests. Before a test method is run, a template method named `setUp()` is invoked: this is where you can create your test fixture. Once the test method has finished running, whether it succeeded or failed, another template method named `tearDown()` is invoked: this is where you can clean up the objects against which you tested. Example 5.1 Example of a test class that uses setUp() and tearDown()[](https://docs.phpunit.de/en/12.4/fixtures.html#fixtures-examples-exampletest-php "Permalink to this code") assertSame( 'the-result', $this\->example\->doSomething() ); } protected function setUp(): void { $this\->example \= new Example( $this\->createStub(Collaborator::class) ); } protected function tearDown(): void { $this\->example \= null; } } The `setUp()` and `tearDown()` template methods are run once for each test method (and on fresh instances) of the test case class. One problem with the `setUp()` and `tearDown()` template methods is that they are called even for tests that do not use the test fixture managed by these methods, in the example shown above the `$this->example` property. Another problem can occur when inheritance comes into play: Example 5.2 Example of an abstract test case class with a setUp() method[](https://docs.phpunit.de/en/12.4/fixtures.html#fixtures-examples-mytestcase-php "Permalink to this code") Sometimes it is just plain hard to test the system under test (SUT) because it depends on other components that cannot be used in the test environment. This could be because they aren’t available, they will not return the results needed for the test or because executing them would have undesirable side effects. In other cases, our test strategy requires us to have more control or visibility of the internal behavior of the SUT. > > When we are writing a test in which we cannot (or chose not to) use a real depended-on component (DOC), we can replace it with a Test Double. The Test Double doesn’t have to behave exactly like the real DOC; it merely has to provide the same API as the real one so that the SUT thinks it is the real one! The `createStub(string $type)` and `createMock(string $type)` methods can be used in a test to automatically generate an object that can act as a test double for the specified original type (interface or extendable class). This test double object can be used in every context where an object of the original type is expected or required. Limitation: final, private, and static methods Please note that `final`, `private`, and `static` methods cannot be doubled. They are ignored by PHPUnit’s test double functionality and retain their original behavior except for `static` methods which will be replaced by a method throwing an exception. Limitation: Enumerations Enumerations (`enum`) are `final` classes and therefore cannot be doubled. Favour doubling interfaces over doubling classes Not only because of the limitations mentioned above, but also to improve your software design, favour the doubling of interfaces over the doubling of classes. Test Stubs[](https://docs.phpunit.de/en/12.4/test-doubles.html#test-stubs "Permalink to this heading") -------------------------------------------------------------------------------------------------------- The practice of replacing an object with a test double that (optionally) returns configured return values is referred to as _stubbing_. You can use a _test stub_ to “replace a real component on which the SUT depends so that the test has a control point for the indirect inputs of the SUT. This allows the test to force the SUT down paths it might not otherwise execute” (Gerard Meszaros). ### Creating Test Stubs[](https://docs.phpunit.de/en/12.4/test-doubles.html#creating-test-stubs "Permalink to this heading") #### `createStub()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#createstub "Permalink to this heading") The `createStub(string $type)` method returns a test stub for the specified interface or extendable class. All methods of the original type are replaced with an implementation that returns an automatically generated value that satisfies the method’s return type declaration without calling the original method. These methods are referred to as “doubled methods”. The behaviour of doubled methods can be configured using methods such as `willReturn()` or `willThrowException()`. These methods are explained later. #### `createStubForIntersectionOfInterfaces()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#createstubforintersectionofinterfaces "Permalink to this heading") The `createStubForIntersectionOfInterfaces(array $interfaces)` method can be used to create a test stub for an intersection of interfaces based on a list of interface names. Consider you have the following interfaces `X` and `Y`: Example 6.1 An interface named X[](https://docs.phpunit.de/en/12.4/test-doubles.html#id4 "Permalink to this code") createStubForIntersectionOfInterfaces(\[X::class, Y::class\]); // $o is of type X ... $this\->assertInstanceOf(X::class, $o); // ... and $o is of type Y $this\->assertInstanceOf(Y::class, $o); } } #### `createConfiguredStub()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#createconfiguredstub "Permalink to this heading") The `createConfiguredStub()` method is a convenience wrapper around `createStub()` that allows configuring return values using an associative array (`['methodName' => ]`): Example 6.5 Using createConfiguredStub() to create a test stub and configure return values[](https://docs.phpunit.de/en/12.4/test-doubles.html#id8 "Permalink to this code") createConfiguredStub( SomeInterface::class, \[\ 'doSomething' \=> 'foo',\ 'doSomethingElse' \=> 'bar',\ \], ); // $o->doSomething() now returns 'foo' $this\->assertSame('foo', $o\->doSomething()); // $o->doSomethingElse() now returns 'bar' $this\->assertSame('bar', $o\->doSomethingElse()); } } ### Configuring Test Stubs[](https://docs.phpunit.de/en/12.4/test-doubles.html#configuring-test-stubs "Permalink to this heading") #### `willReturn()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#willreturn "Permalink to this heading") Using the `willReturn()` method, for instance, you can configure a doubled method to return a specified value when it is called. This configured value must be compatible with the method’s return type declaration. Consider that we have a class that we want to test, `SomeClass`, which depends on `Dependency`: Example 6.6 The class we want to test[](https://docs.phpunit.de/en/12.4/test-doubles.html#id9 "Permalink to this code") doSomething(); } } Example 6.7 The dependency we want to stub[](https://docs.phpunit.de/en/12.4/test-doubles.html#id10 "Permalink to this code") createStub(Dependency::class); // Configure the test stub $dependency\->method('doSomething') \->willReturn('foo'); $result \= $sut\->doSomething($dependency); $this\->assertStringEndsWith('foo', $result); } } Limitation: Methods named “method” The example shown above only works when the original interface or class does not declare a method named “method”. If the original interface or class does declare a method named “method” then `$stub->expects($this->any())->method('doSomething')->willReturn('foo');` has to be used. In the example shown above, we first use the `createStub()` method to create a test stub, an object that looks like an instance of `Dependency`. We then use the [Fluent Interface](http://martinfowler.com/bliki/FluentInterface.html) that PHPUnit provides to specify the behavior for the test stub. “Behind the scenes”, PHPUnit automatically generates a new PHP class that implements the desired behavior when the `createStub()` method is used. Please note that `createStub()` will automatically and recursively stub return values based on a method’s return type. Consider the example shown below: Example 6.9 A method with a return type declaration[](https://docs.phpunit.de/en/12.4/test-doubles.html#id11 "Permalink to this code") createStub(SomeClass::class); // Configure the stub. $stub\->method('doSomething') \->willReturn(1, 2, 3); // $stub->doSomething() returns a different value each time $this\->assertSame(1, $stub\->doSomething()); $this\->assertSame(2, $stub\->doSomething()); $this\->assertSame(3, $stub\->doSomething()); } } #### `willThrowException()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#willthrowexception "Permalink to this heading") Instead of returning a value, a stubbed method can also raise an exception. Here is an example that shows how to use `willThrowException()` to do this: Example 6.11 Using willThrowException() to stub a method call to throw an exception[](https://docs.phpunit.de/en/12.4/test-doubles.html#id13 "Permalink to this code") createStub(SomeClass::class); // Configure the stub. $stub\->method('doSomething') \->willThrowException(new Exception); // $stub->doSomething() throws Exception $stub\->doSomething(); } } #### `willReturnArgument()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#willreturnargument "Permalink to this heading") Sometimes you want to return one of the arguments of a method call (unchanged) as the result of a stubbed method call. Here is an example that shows how you can achieve this using `willReturnArgument()`: Example 6.12 Using willReturnArgument() to stub a method call to return one of the arguments[](https://docs.phpunit.de/en/12.4/test-doubles.html#id14 "Permalink to this code") createStub(SomeClass::class); // Configure the stub. $stub\->method('doSomething') \->willReturnArgument(0); // $stub->doSomething('foo') returns 'foo' $this\->assertSame('foo', $stub\->doSomething('foo')); // $stub->doSomething('bar') returns 'bar' $this\->assertSame('bar', $stub\->doSomething('bar')); } } #### `willReturnCallback()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#willreturncallback "Permalink to this heading") When the stubbed method call should return a calculated value instead of a fixed one (see `willReturn()`) or an (unchanged) argument (see `willReturnArgument()`), you can use `willReturnCallback()` to have the stubbed method return the result of a callback function or method. Here is an example: Example 6.13 Using willReturnCallback() to stub a method call to return a value from a callback[](https://docs.phpunit.de/en/12.4/test-doubles.html#id15 "Permalink to this code") createStub(SomeClass::class); // Configure the stub. $stub\->method('doSomething') \->willReturnCallback('str\_rot13'); // $stub->doSomething($argument) returns str\_rot13($argument) $this\->assertSame('fbzrguvat', $stub\->doSomething('something')); } } #### `willReturnSelf()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#willreturnself "Permalink to this heading") When testing a fluent interface, it is sometimes useful to have a stubbed method return a reference to the stubbed object. Here is an example that shows how you can use `willReturnSelf()` to achieve this: Example 6.14 Using willReturnSelf() to stub a method call to return a reference to the stub object[](https://docs.phpunit.de/en/12.4/test-doubles.html#id16 "Permalink to this code") createStub(SomeClass::class); // Configure the stub. $stub\->method('doSomething') \->willReturnSelf(); // $stub->doSomething() returns $stub $this\->assertSame($stub, $stub\->doSomething()); } } #### `willReturnMap()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#willreturnmap "Permalink to this heading") Sometimes a stubbed method should return different values depending on a predefined list of arguments. Here is an example that shows how to use `willReturnMap()` to create a map that associates arguments with corresponding return values: Example 6.15 Using willReturnMap() to stub a method call to return the value from a map[](https://docs.phpunit.de/en/12.4/test-doubles.html#id17 "Permalink to this code") createStub(SomeClass::class); // Create a map of arguments to return values. $map \= \[\ \['a', 'b', 'c', 'd'\],\ \['e', 'f', 'g', 'h'\],\ \]; // Configure the stub. $stub\->method('doSomething') \->willReturnMap($map); // $stub->doSomething() returns different values depending on // the provided arguments. $this\->assertSame('d', $stub\->doSomething('a', 'b', 'c')); $this\->assertSame('h', $stub\->doSomething('e', 'f', 'g')); } } #### Get-Hooked Properties[](https://docs.phpunit.de/en/12.4/test-doubles.html#get-hooked-properties "Permalink to this heading") PHP 8.4 introduced the language feature of [get-hooked properties](https://www.php.net/releases/8.4/en.php#property_hooks) . The example below shows an interface that declares a get-hooked property: Example 6.16 Interface that declares a get-hooked property[](https://docs.phpunit.de/en/12.4/test-doubles.html#id18 "Permalink to this code") createStub( InterfaceWithHookedProperty::class, ); $stub \->method(PropertyHook::get('property')) \->willReturn('value'); $this\->assertSame('value', $stub\->property); } } In the example shown above, `PropertyHook::get('property')` to specify that we want to configure the behaviour of the method that is called when the property named `property` is accessed for reading. Mock Objects[](https://docs.phpunit.de/en/12.4/test-doubles.html#mock-objects "Permalink to this heading") ------------------------------------------------------------------------------------------------------------ The practice of replacing an object with a test double that verifies expectations, for instance asserting that a method has been called, is referred to as _mocking_. You can use a _mock object_ “as an observation point that is used to verify the indirect outputs of the SUT as it is exercised. Typically, the mock object also includes the functionality of a test stub in that it must return values to the SUT if it hasn’t already failed the tests but the emphasis is on the verification of the indirect outputs. Therefore, a mock object is a lot more than just a test stub plus assertions; it is used in a fundamentally different way” (Gerard Meszaros). ### Creating Mock Objects[](https://docs.phpunit.de/en/12.4/test-doubles.html#creating-mock-objects "Permalink to this heading") Note Mock Objects cannot be created in a data provider method. #### `createMock()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#createmock "Permalink to this heading") The `createMock(string $type)` method returns a mock object for the specified interface or extendable class. All methods of the original type are replaced with an implementation that returns an automatically generated value that satisfies the method’s return type declaration without calling the original method. These methods are referred to as “doubled methods”. The behaviour of doubled methods can be configured using methods such as `willReturn()` or `willThrowException()`. These methods are explained in the section on Test Stubs above. Expectations for invocations of doubled methods (“method must be called with specified arguments”, “method must not be called”, etc.) can be configured using the mock object’s `expects()` method. #### `createMockForIntersectionOfInterfaces()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#createmockforintersectionofinterfaces "Permalink to this heading") The `createMockForIntersectionOfInterfaces(array $interfaces)` method can be used to create a mock object for an intersection of interfaces based on a list of interface names. Consider you have the following interfaces `X` and `Y`: Example 6.18 An interface named X[](https://docs.phpunit.de/en/12.4/test-doubles.html#id20 "Permalink to this code") createMockForIntersectionOfInterfaces(\[X::class, Y::class\]); // $o is of type X ... $this\->assertInstanceOf(X::class, $o); // ... and $o is of type Y $this\->assertInstanceOf(Y::class, $o); } } #### `createConfiguredMock()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#createconfiguredmock "Permalink to this heading") The `createConfiguredMock()` method is a convenience wrapper around `createMock()` that allows configuring return values using an associative array (`['methodName' => ]`): Example 6.22 Using createConfiguredMock() to create a mock object and configure return values[](https://docs.phpunit.de/en/12.4/test-doubles.html#id24 "Permalink to this code") createConfiguredMock( SomeInterface::class, \[\ 'doSomething' \=> 'foo',\ 'doSomethingElse' \=> 'bar',\ \], ); // $o->doSomething() now returns 'foo' $this\->assertSame('foo', $o\->doSomething()); // $o->doSomethingElse() now returns 'bar' $this\->assertSame('bar', $o\->doSomethingElse()); } } ### Configuring Mock Objects[](https://docs.phpunit.de/en/12.4/test-doubles.html#configuring-mock-objects "Permalink to this heading") Here is an example: suppose we want to test that the correct method, `update()` in our example, is called on an object that observes another object. Here is the code for the `Subject` class and the `Observer` interface that are part of the System under Test (SUT): Example 6.23 Subject class that is part of the System under Test (SUT)[](https://docs.phpunit.de/en/12.4/test-doubles.html#id25 "Permalink to this code") observers\[\] \= $observer; } public function doSomething(): void { // ... $this\->notify('something'); } private function notify(string $argument): void { foreach ($this\->observers as $observer) { $observer\->update($argument); } } // ... } Example 6.24 Observer interface that is part of the System under Test (SUT)[](https://docs.phpunit.de/en/12.4/test-doubles.html#id26 "Permalink to this code") createMock(Observer::class); $observer\->expects($this\->once()) \->method('update') \->with($this\->identicalTo('something')); $subject \= new Subject; $subject\->attach($observer); $subject\->doSomething(); } } We first use the `createMock()` method to create a mock object for the `Observer`. Because we are interested in verifying the communication between two objects (that a method is called and which arguments it is called with), we use the `expects()` and `with()` methods to specify what this communication should look like. The `with()` method can take any number of arguments, corresponding to the number of arguments to the method being mocked. You can specify more advanced constraints on the method’s arguments than a simple match. [Constraints](https://docs.phpunit.de/en/12.4/assertions.html#appendixes-assertions-assertthat-tables-constraints) shows the constraints that can be applied to method arguments and here is a list of the matchers that are available to specify the number of invocations: * `any()` returns a matcher that matches when the method it is evaluated for is executed zero or more times * `never()` returns a matcher that matches when the method it is evaluated for is never executed * `atLeastOnce()` returns a matcher that matches when the method it is evaluated for is executed at least once * `once()` returns a matcher that matches when the method it is evaluated for is executed exactly once * `atMost(int $count)` returns a matcher that matches when the method it is evaluated for is executed at most `$count` times * `exactly(int $count)` returns a matcher that matches when the method it is evaluated for is executed exactly `$count` times MockBuilder API[](https://docs.phpunit.de/en/12.4/test-doubles.html#mockbuilder-api "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------ As mentioned before, when the defaults used by the `createStub()` and `createMock()` methods to generate the test double do not match your needs then you can use the `getMockBuilder($type)` method to customize the test double generation using a fluent interface. The methods provided by the Mock Builder are documented below. ### `setConstructorArgs()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#setconstructorargs "Permalink to this heading") `setConstructorArgs(array $args)` can be called to provide a parameter array that is passed to the original class’ constructor (which is not replaced with a dummy implementation by default). ### `disableOriginalConstructor()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#disableoriginalconstructor "Permalink to this heading") `disableOriginalConstructor()` can be used to disable the call to the constructor of the original class. `enableOriginalConstructor()` can be used to make it explicit that the constructor of the original class should be called (which is the default behaviour). ### `disableOriginalClone()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#disableoriginalclone "Permalink to this heading") `disableOriginalClone()` can be used to disable the call to the clone constructor of the original class. `enableOriginalClone()` can be used to make it explicit that the clone constructor of the original class should be called (which is the default behaviour). ### `disableAutoReturnValueGeneration()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#disableautoreturnvaluegeneration "Permalink to this heading") `disableAutoReturnValueGeneration()` can be used to disable the automatic generation of return values when no return value is configured. `enableAutoReturnValueGeneration()` can be used to make it explicit that automatic generation of return values when no return value is configured is enabled (which is the default). ### `onlyMethods()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#onlymethods "Permalink to this heading") `onlyMethods(array $methods)` can be called on the Mock Builder object to specify the methods that are to be replaced with a configurable test double. The behavior of the other methods is not changed. The specified methods must exist in the class that is mocked. ### `getMock()`[](https://docs.phpunit.de/en/12.4/test-doubles.html#getmock "Permalink to this heading") `getMock()` generates and returns a mock object based on the configuration made using previous methods calls. The call to `getMock()` must be the last in the method chain. Here is an example that shows how to use the Mock Builder’s fluent interface to configure the creation of a test stub. The configuration of this test double uses the same best practice defaults used by `createStub()` and `createMock()`: Example 6.26 Using the Mock Builder API to configure how the test double class is generated[](https://docs.phpunit.de/en/12.4/test-doubles.html#id28 "Permalink to this code") getMockBuilder(SomeClass::class) \->disableOriginalConstructor() \->disableOriginalClone() \->getMock(); // Configure the stub. $stub\->method('doSomething') \->willReturn('foo'); // Calling $stub->doSomething() will now return // 'foo'. $this\->assertSame('foo', $stub\->doSomething()); } } ### Set-Hooked Properties[](https://docs.phpunit.de/en/12.4/test-doubles.html#set-hooked-properties "Permalink to this heading") PHP 8.4 introduced the language feature of [set-hooked properties](https://www.php.net/releases/8.4/en.php#property_hooks) . The example below shows an interface that declares a set-hooked property: Example 6.27 Interface that declares a set-hooked property[](https://docs.phpunit.de/en/12.4/test-doubles.html#id29 "Permalink to this code") createMock( InterfaceWithSetHookedProperty::class, ); $mock \->expects($this\->once()) \->method(PropertyHook::set('property')) \->with('value'); $mock\->property \= 'value'; } } In the example shown above, `PropertyHook::set('property')` to specify that we want to configure an expectation for the method that is called when the property named `property` is accessed for writing. --- # 7. Code Coverage — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 7\. Code Coverage * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/code-coverage.rst) * * * 7\. Code Coverage[](https://docs.phpunit.de/en/12.4/code-coverage.html#code-coverage "Permalink to this heading") =================================================================================================================== > _Wikipedia_: > > In computer science, code coverage is a measure used to describe the degree to which the source code of a program is tested by a particular test suite. A program with high code coverage has been more thoroughly tested and has a lower chance of containing software bugs than a program with low code coverage. In this chapter you will learn all about PHPUnit’s code coverage functionality that provides an insight into what parts of the production code are executed when the tests are run. It makes use of the [php-code-coverage](https://github.com/sebastianbergmann/php-code-coverage) library, which in turn leverages the code coverage functionality provided by the [PCOV](https://github.com/krakjoe/pcov) or [Xdebug](https://xdebug.org/) extensions for PHP. Note If you see a warning while running tests that no code coverage driver is available, it means that you are using the PHP CLI binary (`php`) and do not have PCOV or Xdebug loaded. Note When you want to use Xdebug for the collection of code coverage data then you have to activate Xdebug’s [coverage](https://xdebug.org/docs/code_coverage#mode) mode. PHPUnit can generate a code coverage report in HTML format as well as XML-based logfiles with code coverage information in various formats (Clover, Cobertura, Crap4J, PHPUnit). Code coverage information can also be reported as text (and printed to STDOUT) and exported as PHP code for further processing. Please refer to [The Command-Line Test Runner](https://docs.phpunit.de/en/12.4/textui.html#textui) for a list of command-line options that control code coverage functionality as well as [The Element](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source) and [The Element](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-coverage) for the relevant configuration settings for reporting code coverage. Software Metrics for Code Coverage[](https://docs.phpunit.de/en/12.4/code-coverage.html#software-metrics-for-code-coverage "Permalink to this heading") --------------------------------------------------------------------------------------------------------------------------------------------------------- Various software metrics exist to measure code coverage: _Line Coverage_ > The _Line Coverage_ software metric measures whether each executable line was executed. _Branch Coverage_ > The _Branch Coverage_ software metric measures whether the boolean expression of each control structure evaluated to both `true` and `false` while running the test suite. _Path Coverage_ > The _Path Coverage_ software metric measures whether each of the possible execution paths in a function or method has been followed while running the test suite. An execution path is a unique sequence of branches from the entry of the function or method to its exit. _Function and Method Coverage_ > The _Function and Method Coverage_ software metric measures whether each function or method has been invoked. php-code-coverage only considers a function or method as covered when all of its executable lines are covered. _Class and Trait Coverage_ > The _Class and Trait Coverage_ software metric measures whether each method of a class or trait is covered. php-code-coverage only considers a class or trait as covered when all of its methods are covered. _Change Risk Anti-Patterns (CRAP) Index_ > The _Change Risk Anti-Patterns (CRAP) Index_ is calculated based on the cyclomatic complexity and code coverage of a unit of code. Code that is not too complex and has an adequate test coverage will have a low CRAP index. The CRAP index can be lowered by writing tests and by refactoring the code to lower its complexity. The library used by PHPUnit supports all code coverage software metrics listed above. To report branch coverage and path coverage, code coverage data has to be collected using Xdebug as PCOV only supports line coverage. Including Files[](https://docs.phpunit.de/en/12.4/code-coverage.html#including-files "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------- It is mandatory to configure which source code files you consider your own and therefore want to be included in the code coverage report. As other features of PHPUnit also need to know which source code files you consider your own, it is best practice to configure this in the XML configuration file (see [The Element](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-include) ). Alternatively, you may use the `--coverage-filter` [command-line](https://docs.phpunit.de/en/12.4/textui.html#textui-command-line-options) option. The `includeUncoveredFiles` configuration setting is available to configure how the filter is used: * `includeUncoveredFiles="true"` (default) means that all files are included in the code coverage report even if not a single line of code of such a file is executed * `includeUncoveredFiles="false"` means that only files that have at least one line of executed code are included in the code coverage report In order to get a complete and honest code coverage report, it is highly recommended to use the default setting. Targeting Units of Code[](https://docs.phpunit.de/en/12.4/code-coverage.html#targeting-units-of-code "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------------- The `PHPUnit\Framework\Attributes\CoversClass`, `PHPUnit\Framework\Attributes\CoversMethod`, and `PHPUnit\Framework\Attributes\CoversFunction` attributes can be used in the test code to specify which units of code a test class intends to cover. When these attributes are used on a test case class, code coverage information is only collected for the listed units of code when the test methods of this test case class are executed. [Example 7.1](https://docs.phpunit.de/en/12.4/code-coverage.html#code-coverage-targeting-units-of-code-examples-invoicetest-php) shows an example. Example 7.1 Test class that specifies which class it wants to cover[](https://docs.phpunit.de/en/12.4/code-coverage.html#code-coverage-targeting-units-of-code-examples-invoicetest-php "Permalink to this code") assertEquals(new Money, (new Invoice)\->amount()); } } The `PHPUnit\Framework\Attributes\UsesClass`, `PHPUnit\Framework\Attributes\UsesMethod`, and `PHPUnit\Framework\Attributes\UsesFunction` attributes can be used to specify units of code that should be ignored for code coverage, but which are allowed to be used by the code that is covered. This is explained in the section on [unintentionally covered code](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-unintentionally-covered-code) . In the example shown above, the `#[CoversClass(Invoice::class)]` attribute tells PHPUnit that the tests of this test case class intend to cover the code of the `Invoice` class. When the tests of this test case class are run, only code coverage information for the `Invoice` class will be processed and code coverage information for all other code that may also be run while these tests are running will be ignored. In the example shown above, the `#[UsesClass(Money::class)]` attribute tells PHPUnit that it is expected and allowed that code from the `Money` class is also run while the tests of this test case class are run. This is important when it comes to considering a test risky when it runs code that is not expected to be run. As it is technically not possible to test a subclass in isolation from its base class(es), the `#[CoversClass]` and `#[UsesClass]` attributes consider the class whose name has been specified as well as all of its parent classes, if it has any. The `PHPUnit\Framework\Attributes\CoversNothing` attribute can be used to specify that tests should not contribute to code coverage at all. This can be helpful when writing integration tests and to make sure you only generate code coverage with smaller tests. Example 7.2 A test that specifies that it does not want to contribute to code coverage[](https://docs.phpunit.de/en/12.4/code-coverage.html#code-coverage-targeting-units-of-code-examples-guestbookintegrationtest-php "Permalink to this code") generate(); $this\->assertMatchesRegularExpression( '/^\[a-f0-9\]{8}-\[a-f0-9\]{4}$/', sprintf( 'Failed asserting that "%s" is a valid order ID.', $orderId, ), ); } } You can enhance this concrete test case by extracting a domain-specific assertion. Example 10.2 A concrete test case using a domain-specific assertion[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#id3 "Permalink to this code") generate(); $this\->assertStringIsOrderId($orderId); } private function assertStringIsOrderId(string $value): void { $this\->assertMatchesRegularExpression( '/^\[a-f0-9\]{8}-\[a-f0-9\]{4}$/', $value, sprintf( 'Failed asserting that "%s" is a valid order ID.', $value, ), ); } } Extracting abstract test cases[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#extracting-abstract-test-cases "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------------------------------- You can extend PHPUnit by extracting abstract test cases to share functionality with other concrete test cases via vertical inheritance. For example, you may want to pull the domain-specific assertion from above into an abstract test case. Example 10.3 An abstract test case with a domain-specific assertion[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#id4 "Permalink to this code") assertMatchesRegularExpression( '/^\[a-f0-9\]{8}-\[a-f0-9\]{4}$/', $value, sprintf( 'Failed asserting that "%s" is a valid order ID.', $value, ), ); } } You can then enhance a concrete test case by extending the abstract test case. Example 10.4 A concrete test case extending an abstract test case with a domain-specific assertion[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#id5 "Permalink to this code") generate(); $this\->assertStringIsOrderId($orderId); } } Extracting traits[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#extracting-traits "Permalink to this heading") --------------------------------------------------------------------------------------------------------------------------- You can extend PHPUnit by extracting traits to share functionality with concrete test cases via horizontal inheritance. For example, you may want to pull the domain-specific assertion from above into a trait. Example 10.5 A trait with a domain-specific assertion[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#id6 "Permalink to this code") assertMatchesRegularExpression( '/^\[a-f0-9\]{8}-\[a-f0-9\]{4}$/', $value, sprintf( 'Failed asserting that "%s" is a valid order ID.', $value, ), ); } } You can then enhance a concrete test case by using the trait. Example 10.6 A concrete test case using a trait with a domain-specific assertion[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#id7 "Permalink to this code") generate(); $this\->assertStringIsOrderId($orderId); } } Extending the Test Runner[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#extending-the-test-runner "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------------------- You can extend PHPUnit by implementing and registering an extension. ### Implementing an extension[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#implementing-an-extension "Permalink to this heading") A PHPUnit extension is a class that implements the `PHPUnit\Runner\Extension\Extension` interface. The extension interface declares a `bootstrap()` method that accepts the PHPUnit configuration, the extension facade, and the extension parameter collection. Example 10.7 An example extension registering an ExampleSubscriber and an ExampleTracer[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#id8 "Permalink to this code") noOutput()) { return; } $message \= 'the-default-message'; if ($parameters\->has('message')) { $message \= $parameters\->get('message'); } $facade\->registerSubscriber(new ExampleSubscriber($message)); $facade\->registerTracer(new ExampleTracer); } } The PHPUnit configuration is an instance of `PHPUnit\TextUI\Configuration\Configuration` and gives you access to the configuration of PHPUnit after merging configuration options from defaults, the XML configuration file, and command-line options. You can inspect the configuration object to adjust the behavior of your extension. For example, you may want to extend PHPUnit with an extension that renders output on the console. If that is the case, you may be interested to know whether a user of PHPUnit wants to use colors or prefers a monochrome output. The parameter collection is an instance of `PHPUnit\Runner\Extension\ParameterCollection` and gives you access to extension parameters a user has provided via PHPUnit’s XML configuration file. You can use the parameter collection to allow users of the extension to configure the behavior of your extension. Note You must verify and process the values from the parameter collection yourself. PHPUnit has no functionality for verifying or casting the values from the parameter collection to other types. The extension facade is an instance of `PHPUnit\Runner\Extension\Facade` and allows you to register event subscribers and event tracers using the methods `registerSubscribers()`, `registerSubscriber()`, and `registerTracer()`. The extension facade also provides the following methods for test runner extensions to indicate to the test runner that they intend to replace default functionality or require certain functionality to be activated: The `replacesProgressOutput()` method can be used to disable the test runner’s default progress output while it runs the tests. The `replacesResultOutput()` method can be used to disable the test runner’s default result output after it finished running the tests. The `replacesOutput()` method combines the effects of `replacesProgressOutput()` and `replacesResultOutput()` (see above). The `requiresCodeCoverageCollection()` method can be used to activate the collection of code coverage information. The `requiresExportOfObjects()` method can be used to activate the export of objects for events such as `Test\AssertionSucceeded` and `Test\AssertionFailed`, for example. #### Implementing an event subscriber[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#implementing-an-event-subscriber "Permalink to this heading") An event subscriber is a class that implements an event subscriber interface. An event subscriber interface declares a single `notify()` method that accepts an instance of the corresponding event class. Example 10.8 An ExampleSubscriber printing a message when PHPUnit emits the ExecutionFinished event[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#id9 "Permalink to this code") message . PHP\_EOL; } } After registering an event subscriber with the extension facade, PHPUnit will notify the event subscriber when emitting an event of the corresponding event class. Note You can not create an event subscriber that implements more than one event subscriber interface at a time. If you want to subscribe to more than one event, you need to implement at least one event subscriber for each event you are interested in. #### Implementing an event tracer[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#implementing-an-event-tracer "Permalink to this heading") An event tracer is a class that implements the `PHPUnit\Event\Tracer\Tracer` interface. The tracer interface declares a single `trace()` method that accepts an event. Example 10.9 An ExampleTracer receiving all events[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#id10 "Permalink to this code") #### Sharing an extension as a Composer package[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#sharing-an-extension-as-a-composer-package "Permalink to this heading") When users of your extension prefer to install PHPUnit as a Composer package, it is best to make your extension available as a Composer package. ### Registering an extension[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#registering-an-extension "Permalink to this heading") You can register one or more PHPUnit extensions from PHARs or from Composer package using the [extensions](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-extensions) , [bootstrap](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-extensions-bootstrap) , and [parameters](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-extensions-extension-arguments) elements of the [PHPUnit XML configuration file](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration) . #### Registering an extension from a PHAR[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#registering-an-extension-from-a-phar "Permalink to this heading") When you install PHPUnit as a PHAR, it is best to load extensions from a PHAR. You can use the [extensionsDirectory](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-phpunit-extensionsdirectory) attribute of the [phpunit](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-phpunit) element to configure the directory from which PHPUnit should load extensions as a PHAR. Example 10.11 An XML configuration registering an ExampleExtension with parameters, loaded from an extensions directory[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#id12 "Permalink to this code") #### Registering an extension from a Composer package[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#registering-an-extension-from-a-composer-package "Permalink to this heading") When you install PHPUnit as a Composer package, it is best to load extensions from Composer packages. You do not need to configure the [extensionsDirectory](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-phpunit-extensionsdirectory) attribute, as extensions from Composer packages will be available through the autoloading mechanism of Composer. Example 10.12 An XML configuration registering an ExampleExtension with parameters[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#id13 "Permalink to this code") ### Debugging PHPUnit[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#debugging-phpunit "Permalink to this heading") The test runner’s `--log-events-text` CLI option can be used to write a plain text representation for each event to a stream. In the example shown below, we use `--no-output` to disable both the default progress output as well as the default result output. Then we use `--log-events-text php://stdout` to write event information to standard output: Example 10.13 Output of “phpunit –no-output –log-events-text php://stdout” command[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#extending-phpunit-event-system-event-system-debugging-phpunit-examples-logging-events "Permalink to this code") phpunit --no-output --log-events-text php://stdout PHPUnit Started (PHPUnit 10.0.0 using PHP 8.2.1 (cli) on Linux) Test Runner Configured Test Suite Loaded (2 tests) Event Facade Sealed Test Runner Started Test Suite Sorted Test Runner Execution Started (2 tests) Test Suite Started (ExampleTest, 2 tests) Test Preparation Started (ExampleTest::testOne) Test Prepared (ExampleTest::testOne) Assertion Succeeded (Constraint: is true) Test Passed (ExampleTest::testOne) Test Finished (ExampleTest::testOne) Test Preparation Started (ExampleTest::testTwo) Test Prepared (ExampleTest::testTwo) Assertion Failed (Constraint: is identical to 'foo', Value: 'bar') Test Failed (ExampleTest::testTwo) Failed asserting that two strings are identical. Test Finished (ExampleTest::testTwo) Test Suite Finished (ExampleTest, 2 tests) Test Runner Execution Finished Test Runner Finished PHPUnit Finished (Shell Exit Code: 1) Alternatively, the `--log-events-verbose-text` CLI option can be used to include information about resource consumption (time since the test runner was started, time since the previous event, and memory usage): Example 10.14 Output of “phpunit –no-output –log-events-verbose-text php://stdout” command[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#extending-phpunit-event-system-event-system-debugging-phpunit-examples-logging-events-verbose "Permalink to this code") phpunit --no-output --log-events-verbose-text php://stdout \[00:00:00.000046482 / 00:00:00.000006987\] \[4194304 bytes\] PHPUnit Started (PHPUnit 10.0.0 using PHP 8.2.1 (cli) on Linux) \[00:00:00.048195557 / 00:00:00.048149075\] \[4194304 bytes\] Test Runner Configured \[00:00:00.067646038 / 00:00:00.019450481\] \[6291456 bytes\] Test Suite Loaded (2 tests) \[00:00:00.075942220 / 00:00:00.008296182\] \[6291456 bytes\] Event Facade Sealed \[00:00:00.076452360 / 00:00:00.000510140\] \[6291456 bytes\] Test Runner Started \[00:00:00.084421682 / 00:00:00.007969322\] \[6291456 bytes\] Test Suite Sorted \[00:00:00.084664485 / 00:00:00.000242803\] \[6291456 bytes\] Test Runner Execution Started (2 tests) \[00:00:00.085240320 / 00:00:00.000575835\] \[6291456 bytes\] Test Suite Started (ExampleTest, 2 tests) \[00:00:00.086992385 / 00:00:00.001752065\] \[6291456 bytes\] Test Preparation Started (ExampleTest::testOne) \[00:00:00.087443560 / 00:00:00.000451175\] \[6291456 bytes\] Test Prepared (ExampleTest::testOne) \[00:00:00.088237489 / 00:00:00.000793929\] \[6291456 bytes\] Assertion Succeeded (Constraint: is true) \[00:00:00.089076305 / 00:00:00.000838816\] \[6291456 bytes\] Test Passed (ExampleTest::testOne) \[00:00:00.091027624 / 00:00:00.001951319\] \[6291456 bytes\] Test Finished (ExampleTest::testOne) \[00:00:00.091110095 / 00:00:00.000082471\] \[6291456 bytes\] Test Preparation Started (ExampleTest::testTwo) \[00:00:00.091158739 / 00:00:00.000048644\] \[6291456 bytes\] Test Prepared (ExampleTest::testTwo) \[00:00:00.091991799 / 00:00:00.000833060\] \[6291456 bytes\] Assertion Failed (Constraint: is identical to 'foo', Value: 'bar') \[00:00:00.099242925 / 00:00:00.007251126\] \[8388608 bytes\] Test Failed (ExampleTest::testTwo) Failed asserting that two strings are identical. \[00:00:00.099386498 / 00:00:00.000143573\] \[8388608 bytes\] Test Finished (ExampleTest::testTwo) \[00:00:00.099437634 / 00:00:00.000051136\] \[8388608 bytes\] Test Suite Finished (ExampleTest, 2 tests) \[00:00:00.103014760 / 00:00:00.003577126\] \[8388608 bytes\] Test Runner Execution Finished \[00:00:00.103207309 / 00:00:00.000192549\] \[8388608 bytes\] Test Runner Finished \[00:00:00.105879902 / 00:00:00.002672593\] \[8388608 bytes\] PHPUnit Finished (Shell Exit Code: 1) Wrapping the Test Runner[](https://docs.phpunit.de/en/12.4/extending-phpunit.html#wrapping-the-test-runner "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------------------- The `PHPUnit\TextUI\Application` class is the entry point for PHPUnit’s own CLI test runner. It is not meant to be (re)used by developers who want to wrap PHPUnit to build something such as ParaTest. For the actual running of tests, `PHPUnit\TextUI\Application` uses `PHPUnit\TextUI\TestRunner::run()`. `PHPUnit\TextUI\TestRunner::run()` requires a `PHPUnit\TextUI\Configuration\Configuration`, a `PHPUnit\Runner\ResultCache\ResultCache`, and a `PHPUnit\Framework\TestSuite`. A `PHPUnit\TextUI\Configuration\Configuration` can be built using `PHPUnit\TextUI\Configuration\Builder::build()`. You need to pass `$_SERVER['argv']` to this method. The method then parses CLI arguments/options and loads an XML configuration file, if one can be loaded. A `PHPUnit\Framework\TestSuite` can be built from a `PHPUnit\TextUI\Configuration\Configuration` using `PHPUnit\TextUI\Configuration\TestSuiteBuilder::build()`. While it is marked `@internal`, `PHPUnit\TextUI\TestRunner` is meant to be (re)used by developers who want to wrap PHPUnit’s test runner. --- # 9. Error Handling — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 9\. Error Handling * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/error-handling.rst) * * * 9\. Error Handling[](https://docs.phpunit.de/en/12.4/error-handling.html#error-handling "Permalink to this heading") ====================================================================================================================== PHPUnit’s test runner registers an [error handler](https://www.php.net/manual/en/function.set-error-handler.php) and processes `E_DEPRECATED`, `E_USER_DEPRECATED`, `E_NOTICE`, `E_USER_NOTICE`, `E_STRICT`, `E_WARNING`, and `E_USER_WARNING` errors. We will use the term “issues” to refer to `E_DEPRECATED`, `E_USER_DEPRECATED`, `E_NOTICE`, `E_USER_NOTICE`, `E_STRICT`, `E_WARNING`, and `E_USER_WARNING` errors for the remainder of this chapter. The error handler is only active while a test is running and only processes issues triggered by test code or code that is called from test code. It ignores issues triggered by PHPUnit’s own code as well as code from PHPUnit’s dependencies. Other error handlers When PHPUnit’s test runner becomes aware (after it called `set_error_handler()` to register its error handler) that another error handler was registered then it immediately unregisters its error handler so that the previously registered error handler remains active. Consequently, the features described in this chapter are not available when you use your own error handler. Your own error handler should follow best practices Your own error handler should ignore errors emitted by code it is not responsible for, for instance PHPUnit’s code. The error handler emits events that are, for instance, subscribed to and used by the default progress and result printers as well as loggers. Here is the code that we will use for the examples in the remainder of this chapter: . ├── phpunit.xml ├── src │   └── FirstPartyClass.php ├── tests │   └── FirstPartyClassTest.php └── vendor ├── autoload.php └── ThirdPartyClass.php 4 directories, 5 files Example 9.1 tests/FirstPartyClassTest.php[](https://docs.phpunit.de/en/12.4/error-handling.html#id3 "Permalink to this code") assertTrue((new FirstPartyClass)\->method()); } public function testTwo(): void { $this\->assertTrue((new ThirdPartyClass)\->anotherMethod()); } } Example 9.2 src/FirstPartyClass.php[](https://docs.phpunit.de/en/12.4/error-handling.html#id4 "Permalink to this code") method(); trigger\_error('deprecation in first-party code', E\_USER\_DEPRECATED); return true; } } Example 9.3 vendor/ThirdPartyClass.php[](https://docs.phpunit.de/en/12.4/error-handling.html#id5 "Permalink to this code") method(); } } Example 9.4 phpunit.xml[](https://docs.phpunit.de/en/12.4/error-handling.html#id6 "Permalink to this code") tests PHPUnit’s test runner prints `D`, `N`, and `W`, respectively, for tests that execute code which triggers an issue (`D` for deprecations, `N` for notices, and `W` for warnings). Shown below is the default output PHPUnit’s test runner prints for the example shown above: $ ./tools/phpunit PHPUnit 11.1.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.3.4 Configuration: /path/to/example/phpunit.xml DD 1 / 1 (100%) Time: 00:00.002, Memory: 8.00 MB OK, but there were issues! Tests: 2, Assertions: 2, Deprecations: 2. Detailed information, for instance which issue was triggered where, is only printed when `--display-deprecations`, `--display-notices`, or `--display-warnings` is used: $ ./tools/phpunit --display-deprecations PHPUnit 11.1.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.3.4 Configuration: /path/to/example/phpunit.xml DD 1 / 1 (100%) Time: 00:00.002, Memory: 8.00 MB 2 tests triggered 2 deprecations: 1) /path/to/vendor/ThirdPartyClass.php:10 deprecation in third-party code Triggered by: \* exampleFirstPartyClassTest::testOne /path/to/tests/FirstPartyClassTest.php:17 \* exampleFirstPartyClassTest::testTwo /path/to/tests/FirstPartyClassTest.php:22 2) /path/to/src/FirstPartyClass.php:13 deprecation in first-party code Triggered by: \* exampleFirstPartyClassTest::testOne /path/to/tests/FirstPartyClassTest.php:17 \* exampleFirstPartyClassTest::testTwo /path/to/tests/FirstPartyClassTest.php:22 OK, but there were issues! Tests: 2, Assertions: 2, Deprecations: 2. Limiting issues to “your code”[](https://docs.phpunit.de/en/12.4/error-handling.html#limiting-issues-to-your-code "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------------------------ The reporting of issues can be limited to “your code”, excluding third-party code from directories such as `vendor`, for example. You can configure what you consider “your code” in PHPUnit’s XML configuration file (see [The Element](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source) ): Example 9.5 phpunit.xml[](https://docs.phpunit.de/en/12.4/error-handling.html#id7 "Permalink to this code") tests src Here is what the output of PHPUnit’s test runner will look like after we configured (see above) it to restrict the reporting of issues to our own code: $ ./tools/phpunit --display-deprecations PHPUnit 11.1.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.3.4 Configuration: /path/to/example/phpunit.xml DD 1 / 1 (100%) Time: 00:00.002, Memory: 8.00 MB 2 tests triggered 2 deprecations: 1) /path/to/vendor/ThirdPartyClass.php:10 deprecation in third-party code Triggered by: \* exampleFirstPartyClassTest::testOne /path/to/tests/FirstPartyClassTest.php:17 \* exampleFirstPartyClassTest::testTwo /path/to/tests/FirstPartyClassTest.php:22 2) /path/to/src/FirstPartyClass.php:13 deprecation in first-party code Triggered by: \* exampleFirstPartyClassTest::testOne /path/to/tests/FirstPartyClassTest.php:17 OK, but there were issues! Tests: 2, Assertions: 2, Deprecations: 2. As you can see in the output shown above, deprecations triggered by third-party code located in the `vendor` directory are not reported anymore. The following attributes can be used on the `` element to configure how PHPUnit uses the information what your code is: * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-ignoreselfdeprecations) setting can be used to ignore deprecations triggered by first-party code in first-party code * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-ignoredirectdeprecations) setting can be used to ignore deprecations triggered by first-party code in third-party code * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-ignoreindirectdeprecations) setting can be used to ignore deprecations triggered by third-party code * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-restrictnotices) setting can be used to ignore notices in third-party code * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-restrictwarnings) setting can be used to ignore warnings in third-party code Ignoring issue suppression[](https://docs.phpunit.de/en/12.4/error-handling.html#ignoring-issue-suppression "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------------------ By default, the error handler registered by PHPUnit’s test runner respects the suppression operator (`@`). This means that issues triggered using `@trigger_error()`, for example, will not be reported by the default progress and result printers. The suppression of issues using the suppression operator (`@`) can be ignored by configuration settings in PHPUnit’s XML configuration file: * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-ignoresuppressionofdeprecations) setting can be used to ignore the suppression of `E_USER_DEPRECATED` issues * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-ignoresuppressionofphpdeprecations) setting can be used to ignore the suppression of `E_DEPRECATED` issues * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-ignoresuppressionofnotices) setting can be used to ignore the suppression of `E_USER_NOTICES` issues * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-ignoresuppressionofphpnotices) setting can be used to ignore the suppression of `E_NOTICE` and `E_STRICT` issues * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-ignoresuppressionofwarnings) setting can be used to ignore the suppression of `E_USER_WARNING` issues * [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-ignoresuppressionofphpwarnings) setting can be used to ignore the suppression of `E_WARNING` issues Ignoring previously reported issues[](https://docs.phpunit.de/en/12.4/error-handling.html#ignoring-previously-reported-issues "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------ PHPUnit’s test runner supports declaring the currently reported list of issues. Issues that are on this so-called baseline are no longer reported. This allows you to focus on new issues that are triggered by new or changed code. When you run your test suite using the `--generate-baseline` CLI option then PHPUnit’s test runner will write a list of all issues that are triggered to an XML file: $ phpunit --generate-baseline baseline.xml PHPUnit 11.1.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.10 Configuration: /path/to/example/phpunit.xml D 1 / 1 (100%) Time: 00:00.008, Memory: 4.00 MB OK, but there were issues! Tests: 1, Assertions: 1, Deprecations: 1. Baseline written to /path/to/example/baseline.xml. When you run your test suite using the `--use-baseline` CLI option (or if you have configured a baseline in your XML configuration file for PHPUnit using the [The Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-source-baseline) setting) then PHPUnit’s test runner will use this list of already known issues to ignore them for the current run: $ phpunit --use-baseline baseline.xml PHPUnit 11.1.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.10 Configuration: /path/to/example/phpunit.xml . 1 / 1 (100%) Time: 00:00.007, Memory: 4.00 MB OK (1 test, 1 assertion) 2 issues were ignored by baseline. Expecting Deprecations (`E_USER_DEPRECATED`)[](https://docs.phpunit.de/en/12.4/error-handling.html#expecting-deprecations-e-user-deprecated "Permalink to this heading") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The `expectUserDeprecationMessage()` method can be used to expect that an `E_USER_DEPRECATED` issue with a specified message is triggered. Example 9.6 Usage of expectUserDeprecationMessage()[](https://docs.phpunit.de/en/12.4/error-handling.html#id8 "Permalink to this code") expectUserDeprecationMessage('the-deprecation-message'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/DeprecationExpectationTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) DeprecationExpectationTest::testFailure Expected deprecation with message "the-deprecation-message" was not triggered FAILURES! Tests: 1, Assertions: 1, Failures: 1. Alternatively, the `$this->expectUserDeprecationMessageMatches()` can be used to expect that an `E_USER_DEPRECATED` issue is triggered where the deprecation message matches a specified regular expression. This can be used together with the `#[IgnoreDeprecations]` attribute to not let the test fail. Disabling PHPUnit’s error handler[](https://docs.phpunit.de/en/12.4/error-handling.html#disabling-phpunit-s-error-handler "Permalink to this heading") -------------------------------------------------------------------------------------------------------------------------------------------------------- When you want to test your own [error handler](https://www.php.net/manual/en/function.set-error-handler.php) or want to test that unit of code under test triggers an expected issue, for instance, the error handler registered by PHPUnit’s test runner will interfere with what you want to achieve. The `#[WithoutErrorHandler]` attribute can be used in such a case to disable PHPUnit’s error handler for a test method. --- # 3. Events — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 3\. Events * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/events.rst) * * * 3\. Events[](https://docs.phpunit.de/en/12.4/events.html#events "Permalink to this heading") ============================================================================================== Application[](https://docs.phpunit.de/en/12.4/events.html#application "Permalink to this heading") ---------------------------------------------------------------------------------------------------- `PHPUnit\Event\Application\Started` > The PHPUnit CLI application was started `PHPUnit\Event\Application\Finished` > The PHPUnit CLI application has finished TestRunner[](https://docs.phpunit.de/en/12.4/events.html#testrunner "Permalink to this heading") -------------------------------------------------------------------------------------------------- `PHPUnit\Event\TestRunner\Configured` > The test runner was configured `PHPUnit\Event\TestRunner\BootstrapFinished` > The test runner finished executing the configured bootstrap script `PHPUnit\Event\TestRunner\ExtensionLoadedFromPhar` > The test runner loaded an extension from a PHP Archive (PHAR) `PHPUnit\Event\TestRunner\ExtensionBootstrapped` > The test runner bootstrapped an extension `PHPUnit\Event\TestRunner\Started` > The test runner started running `PHPUnit\Event\TestRunner\ExecutionStarted` > The test runner started executing tests `PHPUnit\Event\TestRunner\DeprecationTriggered` > A deprecation in the test runner was triggered `PHPUnit\Event\TestRunner\WarningTriggered` > A warning in the test runner was triggered `PHPUnit\Event\TestRunner\ExecutionFinished` > The test runner finished executing tests `PHPUnit\Event\TestRunner\Finished` > The test runner finished running TestSuite[](https://docs.phpunit.de/en/12.4/events.html#testsuite "Permalink to this heading") ------------------------------------------------------------------------------------------------ `PHPUnit\Event\TestSuite\Loaded` > The test suite was loaded `PHPUnit\Event\TestSuite\Filtered` > The test suite was filtered `PHPUnit\Event\TestSuite\Sorted` > The test suite was sorted `PHPUnit\Event\TestRunner\ExecutionStarted` > The test runner started executing tests `PHPUnit\Event\TestSuite\Skipped` > The execution of a test suite was skipped `PHPUnit\Event\TestSuite\Started` > The execution of a test suite was started `PHPUnit\Event\TestSuite\Finished` > The execution of a test suite has finished Test[](https://docs.phpunit.de/en/12.4/events.html#test "Permalink to this heading") -------------------------------------------------------------------------------------- `PHPUnit\Event\Test\PreparationStarted` > The preparation of a test for execution was started `PHPUnit\Event\Test\BeforeFirstTestMethodCalled` > A “before first test” method was called for a test case class `PHPUnit\Event\Test\BeforeFirstTestMethodErrored` > A “before first test” method errored for a test case class `PHPUnit\Event\Test\BeforeFirstTestMethodFinished` > All “before first test” methods were called for a test case class `PHPUnit\Event\Test\BeforeTestMethodCalled` > A “before test” method was called for a test method `PHPUnit\Event\Test\BeforeTestMethodErrored` > A “before test” method errored for a test method `PHPUnit\Event\Test\BeforeTestMethodFinished` > All “before test” methods were called for a test method `PHPUnit\Event\Test\PreConditionCalled` > A “precondition” method was called for a test method `PHPUnit\Event\Test\PreConditionErrored` > A “precondition” method errored for a test method `PHPUnit\Event\Test\PreConditionFinished` > All “precondition” methods were called for a test method `PHPUnit\Event\Test\TestPrepared` > A test was prepared for execution `PHPUnit\Event\Test\ComparatorRegistered` > A test registered a custom `Comparator` for `assertEquals()` `PHPUnit\Event\Test\MockObjectCreated` > A test created a mock object `PHPUnit\Event\Test\MockObjectForIntersectionOfInterfacesCreated` > A test created a mock object for an intersection of interfaces `PHPUnit\Event\Test\MockObjectForTraitCreated` > A test created a mock object for a trait `PHPUnit\Event\Test\MockObjectForAbstractClassCreated` > A test created a mock object for an abstract class `PHPUnit\Event\Test\MockObjectFromWsdlCreated` > A test created a mock object from a WSDL file `PHPUnit\Event\Test\PartialMockObjectCreated` > A test created a partial mock object `PHPUnit\Event\Test\TestProxyCreated` > A test created a test proxy `PHPUnit\Event\Test\TestStubCreated` > A test created a test stub `PHPUnit\Event\Test\TestStubForIntersectionOfInterfacesCreated` > A test created a test stub for an intersection of interfaces `PHPUnit\Event\Test\Errored` > A test errored `PHPUnit\Event\Test\Failed` > A test failed `PHPUnit\Event\Test\Passed` > A test passed `PHPUnit\Event\Test\PrintedUnexpectedOutput` > A test printed unexpected output `PHPUnit\Event\Test\ConsideredRisky` > A test was considered risky `PHPUnit\Event\Test\MarkedIncomplete` > A test was marked incomplete `PHPUnit\Event\Test\Skipped` > A test was skipped `PHPUnit\Event\Test\PhpunitDeprecationTriggered` > A test triggered a PHPUnit deprecation `PHPUnit\Event\Test\PhpDeprecationTriggered` > A test triggered a PHP deprecation `PHPUnit\Event\Test\DeprecationTriggered` > A test triggered a deprecation (neither a PHPUnit nor a PHP deprecation) `PHPUnit\Event\Test\PhpunitErrorTriggered` > A test triggered a PHPUnit error `PHPUnit\Event\Test\ErrorTriggered` > A test triggered an error (not a PHPUnit error) `PHPUnit\Event\Test\PhpNoticeTriggered` > A test triggered a PHP notice `PHPUnit\Event\Test\NoticeTriggered` > A test triggered a notice (not a PHP notice) `PHPUnit\Event\Test\PhpunitWarningTriggered` > A test triggered a PHPUnit warning `PHPUnit\Event\Test\PhpWarningTriggered` > A test triggered a PHP warning `PHPUnit\Event\Test\WarningTriggered` > A test triggered a warning (neither a PHPUnit nor a PHP warning) `PHPUnit\Event\Test\Finished` > The execution of a test method finished `PHPUnit\Event\Test\PostConditionCalled` > A “postcondition” method was called for a test method `PHPUnit\Event\Test\PostConditionErrored` > A “postcondition” method errored for a test method `PHPUnit\Event\Test\PostConditionFinished` > All “postcondition” methods were called for a test method `PHPUnit\Event\Test\AfterTestMethodCalled` > An “after test” method was called for a test method `PHPUnit\Event\Test\AfterTestMethodErrored` > An “after test” method errored for a test method `PHPUnit\Event\Test\AfterTestMethodFinished` > All “after test” methods were called for a test method `PHPUnit\Event\Test\AfterLastTestMethodCalled` > An “after last test” method was called for a test case class `PHPUnit\Event\Test\AfterLastTestMethodErrored` > An “after last test” method errored for a test case class `PHPUnit\Event\Test\AfterLastTestMethodFinished` > All “after last test” methods were called for a test case class --- # 2. Attributes — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 2\. Attributes * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/attributes.rst) * * * 2\. Attributes[](https://docs.phpunit.de/en/12.4/attributes.html#attributes "Permalink to this heading") ========================================================================================================== [Attributes](https://wiki.php.net/rfc/attributes_v2) 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`[](https://docs.phpunit.de/en/12.4/attributes.html#test "Permalink to this heading") -------------------------------------------------------------------------------------------- | 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.16 Using the `Test` attribute[](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-test-examples-exampletest-php "Permalink to this code") assertSame($expected, $a + $b); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/DataTest.php PHPUnit 12.4.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`[](https://docs.phpunit.de/en/12.4/attributes.html#testwithjson "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | no | yes | yes | The `TestWithJson(string $json)` attribute can be used to define a [data provider](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-data-providers) for a test method without having to implement a static data provider method. Example 2.18 Using the `TestWithJson` attribute[](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-testwithjson-examples-exampletest-php "Permalink to this code") assertSame($expected, $a + $b); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/DataTest.php PHPUnit 12.4.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[](https://docs.phpunit.de/en/12.4/attributes.html#test-dependencies "Permalink to this heading") -------------------------------------------------------------------------------------------------------------------- ### `Depends`[](https://docs.phpunit.de/en/12.4/attributes.html#depends "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | no | yes | yes | The `Depends(string $methodName)` attribute can be used to specify that a test [depends](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-test-dependencies) 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`[](https://docs.phpunit.de/en/12.4/attributes.html#dependsusingdeepclone "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | no | yes | yes | The `DependsUsingDeepClone(string $methodName)` attribute can be used to specify that a test [depends](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-test-dependencies) 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`[](https://docs.phpunit.de/en/12.4/attributes.html#dependsusingshallowclone "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | no | yes | yes | The `DependsUsingShallowClone(string $methodName)` attribute can be used to specify that a test [depends](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-test-dependencies) 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`[](https://docs.phpunit.de/en/12.4/attributes.html#dependsexternal "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | no | yes | yes | The `DependsExternal(string $className, string $methodName)` attribute can be used to specify that a test [depends](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-test-dependencies) 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`[](https://docs.phpunit.de/en/12.4/attributes.html#dependsexternalusingdeepclone "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | no | yes | yes | The `DependsExternalUsingDeepClone(string $className, string $methodName)` attribute can be used to specify that a test [depends](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-test-dependencies) 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`[](https://docs.phpunit.de/en/12.4/attributes.html#dependsexternalusingshallowclone "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | no | yes | yes | The `DependsExternalUsingShallowClone(string $className, string $methodName)` attribute can be used to specify that a test [depends](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-test-dependencies) 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`[](https://docs.phpunit.de/en/12.4/attributes.html#dependsonclass "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | no | yes | yes | The `DependsOnClass(string $className)` attribute can be used to specify that a test [depends](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-test-dependencies) 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`[](https://docs.phpunit.de/en/12.4/attributes.html#dependsonclassusingdeepclone "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | no | yes | yes | The `DependsOnClassUsingDeepClone(string $className)` attribute can be used to specify that a test [depends](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-test-dependencies) 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`[](https://docs.phpunit.de/en/12.4/attributes.html#dependsonclassusingshallowclone "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | no | yes | yes | The `DependsOnClassUsingShallowClone(string $className)` attribute can be used to specify that a test [depends](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-test-dependencies) 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[](https://docs.phpunit.de/en/12.4/attributes.html#testdox "Permalink to this heading") ------------------------------------------------------------------------------------------------ ### `TestDox`[](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-testdox "Permalink to this heading") | 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.19 Using the `TestDox` attribute[](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-testdox-examples-exampletest-php "Permalink to this code") 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.4.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`[](https://docs.phpunit.de/en/12.4/attributes.html#testdoxformatter "Permalink to this heading") | 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.21 Using the `TestDoxFormatter` attribute[](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-testdoxformatter-examples-exampletest-php "Permalink to this code") 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.4.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`[](https://docs.phpunit.de/en/12.4/attributes.html#testdoxformatterexternal "Permalink to this heading") | 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[](https://docs.phpunit.de/en/12.4/attributes.html#test-groups "Permalink to this heading") -------------------------------------------------------------------------------------------------------- ### `Group`[](https://docs.phpunit.de/en/12.4/attributes.html#group "Permalink to this heading") | 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](https://docs.phpunit.de/en/12.4/textui.html#textui-command-line-options-selection) which tests should be run. The strings `small`, `medium`, and `large` may not be used as group names. ### `Small`[](https://docs.phpunit.de/en/12.4/attributes.html#small "Permalink to this heading") | 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](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-test-execution-timeout) , 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](https://docs.phpunit.de/en/12.4/code-coverage.html#code-coverage) report compared to tests that are marked [medium](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-medium) or [large](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-large) . ### `Medium`[](https://docs.phpunit.de/en/12.4/attributes.html#medium "Permalink to this heading") | 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](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-test-execution-timeout) , 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](https://docs.phpunit.de/en/12.4/code-coverage.html#code-coverage) report compared to tests that are marked [large](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-large) and by a lighter shade of green compared to test that are marked small [small](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-small) . ### `Large`[](https://docs.phpunit.de/en/12.4/attributes.html#large "Permalink to this heading") | 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](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-test-execution-timeout) , 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](https://docs.phpunit.de/en/12.4/code-coverage.html#code-coverage) report compared to tests that are marked [medium](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-medium) or [small](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-small) . ### `Ticket`[](https://docs.phpunit.de/en/12.4/attributes.html#ticket "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | yes | yes | yes | The `Ticket(string $text)` attribute is an alias for `Group(string $text)`. Template Methods[](https://docs.phpunit.de/en/12.4/attributes.html#template-methods "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------ ### `BeforeClass`[](https://docs.phpunit.de/en/12.4/attributes.html#beforeclass "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#before "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#precondition "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#postcondition "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#after "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#afterclass "Permalink to this heading") | 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[](https://docs.phpunit.de/en/12.4/attributes.html#test-isolation "Permalink to this heading") -------------------------------------------------------------------------------------------------------------- ### `BackupGlobals`[](https://docs.phpunit.de/en/12.4/attributes.html#backupglobals "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#excludeglobalvariablefrombackup "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#backupstaticproperties "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#excludestaticpropertyfrombackup "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#runinseparateprocess "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#runtestsinseparateprocesses "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#runclassinseparateprocess "Permalink to this heading") | 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`[](https://docs.phpunit.de/en/12.4/attributes.html#preserveglobalstate "Permalink to this heading") | 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. Skipping Tests[](https://docs.phpunit.de/en/12.4/attributes.html#skipping-tests "Permalink to this heading") -------------------------------------------------------------------------------------------------------------- ### `RequiresPhp`[](https://docs.phpunit.de/en/12.4/attributes.html#requiresphp "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | yes | yes | no | The `RequiresPhp(string $versionRequirement)` attribute can be used to [skip the execution of a test](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-skipping-tests-using-attributes) when the PHP version used to run PHPUnit does not match the specified version requirement. `$versionRequirement` can either be a [version number string](https://www.php.net/manual/en/function.version-compare.php) that is optionally preceded by an operator supported by PHP’s `version_compare()` function or a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints) in the syntax that is supported by Composer. Here are some examples: * `#[RequiresPhp('8.3.0')]` * `#[RequiresPhp('>= 8.3.0')]` * `#[RequiresPhp('^8.3')]` ### `RequiresPhpExtension`[](https://docs.phpunit.de/en/12.4/attributes.html#requiresphpextension "Permalink to this heading") | 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](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-skipping-tests-using-attributes) 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](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-requiresphp) . Here are some examples: * `#[RequiresPhpExtension('mysqli')]` * `#[RequiresPhpExtension('mysqli', '>= 8.3.0')]` * `#[RequiresPhpExtension('mysqli', '^8.3')]` ### `RequiresSetting`[](https://docs.phpunit.de/en/12.4/attributes.html#requiressetting "Permalink to this heading") | 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](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-skipping-tests-using-attributes) when the specified PHP configuration setting is not set to the expected value. ### `RequiresPhpunit`[](https://docs.phpunit.de/en/12.4/attributes.html#requiresphpunit "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | yes | yes | no | The `RequiresPhpunit(string $versionRequirement)` attribute can be used to [skip the execution of a test](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-skipping-tests-using-attributes) when the PHPUnit version does not match the specified version requirement. `$versionRequirement` can either be a [version number string](https://www.php.net/manual/en/function.version-compare.php) that is optionally preceded by an operator supported by PHP’s `version_compare()` function or a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints) in the syntax that is supported by Composer. Here are some examples: * `#[RequiresPhpunit('10.1.0')]` * `#[RequiresPhpunit('>= 10.1.0')]` * `#[RequiresPhpunit('^10.1')]` ### `RequiresPhpunitExtension`[](https://docs.phpunit.de/en/12.4/attributes.html#requiresphpunitextension "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | yes | yes | yes | The `RequiresPhpunitExtension(string $extensionClass)` attribute can be used to [skip the execution of a test](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-skipping-tests-using-attributes) when the PHPUnit extension identified by its bootstrap class is not available. ### `RequiresFunction`[](https://docs.phpunit.de/en/12.4/attributes.html#requiresfunction "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | yes | yes | yes | The `RequiresFunction(string $functionName)` attribute can be used to [skip the execution of a test](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-skipping-tests-using-attributes) when the specified global function is not declared. ### `RequiresMethod`[](https://docs.phpunit.de/en/12.4/attributes.html#requiresmethod "Permalink to this heading") | 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](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-skipping-tests-using-attributes) when the specified method is not declared. ### `RequiresOperatingSystem`[](https://docs.phpunit.de/en/12.4/attributes.html#requiresoperatingsystem "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | yes | yes | no | The `RequiresOperatingSystem(string $regularExpression)` attribute can be used to [skip the execution of a test](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-skipping-tests-using-attributes) when the specified regular expression does not match the value of the `PHP_OS` constant provided by PHP. ### `RequiresOperatingSystemFamily`[](https://docs.phpunit.de/en/12.4/attributes.html#requiresoperatingsystemfamily "Permalink to this heading") | Class Level | Method Level | Repeatable | | --- | --- | --- | | yes | yes | no | The `RequiresOperatingSystemFamily(string $operatingSystemFamily)` attribute can be used to [skip the execution of a test](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-skipping-tests-using-attributes) when the specified string is not identical to the value of the `PHP_OS_FAMILY` constant provided by PHP. ### `RequiresEnvironmentVariable`[](https://docs.phpunit.de/en/12.4/attributes.html#requiresenvironmentvariable "Permalink to this heading") | 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](https://docs.phpunit.de/en/12.4/writing-tests-for-phpunit.html#writing-tests-for-phpunit-skipping-tests-skipping-tests-using-attributes) when the specified environment variable is not set. Optionally, using the the `$value` argument, a required value can be specified for the environment variable. --- # 5. Copyright — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 5\. Copyright * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/copyright.rst) * * * 5\. Copyright[](https://docs.phpunit.de/en/12.4/copyright.html#copyright "Permalink to this heading") ======================================================================================================= Copyright (c) 2025 Sebastian Bergmann. This work is licensed under the Creative Commons Attribution 3.0 Unported License. A summary of the license is given below, followed by the full legal text. -------------------------------------------------------------------- You are free: \* to Share - to copy, distribute and transmit the work \* to Remix - to adapt the work Under the following conditions: Attribution. You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work). \* For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to this web page. \* Any of the above conditions can be waived if you get permission from the copyright holder. \* Nothing in this license impairs or restricts the author's moral rights. Your fair dealing and other rights are in no way affected by the above. This is a human-readable summary of the Legal Code (the full license) below. ==================================================================== Creative Commons Legal Code Attribution 3.0 Unported CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. License THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 1. Definitions a. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. b. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License. c. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. d. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. e. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. f. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three- dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. g. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. h. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. i. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. 2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. 3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: a. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; b. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; c. to Distribute and Publicly Perform the Work including as incorporated in Collections; and, d. to Distribute and Publicly Perform Adaptations. e. For the avoidance of doubt: i. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; ii. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and, iii. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License. The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved. 4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: a. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested. b. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv), consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. c. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. 5. Representations, Warranties and Disclaimer UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. Termination a. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. b. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. 8. Miscellaneous a. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. b. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. c. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. d. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. e. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. f. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor. Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of this License. Creative Commons may be contacted at http://creativecommons.org/. ==================================================================== --- # 4. The XML Configuration File — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 4\. The XML Configuration File * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/configuration.rst) * * * 4\. The XML Configuration File[](https://docs.phpunit.de/en/12.4/configuration.html#the-xml-configuration-file "Permalink to this heading") ============================================================================================================================================= The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-phpunit-element "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------- ### The `backupGlobals` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-backupglobals-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) PHPUnit can optionally backup all global and super-global variables before each test and restore this backup after each test. This attribute configures this operation for all tests. This configuration can be overridden using the `BackupGlobals` attribute on the test case class and test method level. ### The `backupStaticProperties` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-backupstaticproperties-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) PHPUnit can optionally backup all static properties in all declared classes before each test and restore this backup after each test. This attribute configures this operation for all tests. This configuration can be overridden using the `BackupStaticProperties` attribute on the test case class and test method level. ### The `bootstrap` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-bootstrap-attribute "Permalink to this heading") This attribute configures the bootstrap script that is loaded before the tests are executed. This script usually only registers the autoloader callback that is used to load the code under test. ### The `cacheDirectory` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-cachedirectory-attribute "Permalink to this heading") This attribute configures the directory in which PHPUnit caches information such as test results (see below) or the result of static code analysis that is performed for code coverage reporting. ### The `cacheResult` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-cacheresult-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `true`) This attribute configures the caching of test results. This caching is required for ordering tests by defects or duration with the `executionOrder` attribute (see [The executionOrder Attribute](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-phpunit-executionorder) ). ### The `colors` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-colors-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether colors are used in PHPUnit’s output. Setting this attribute to `true` is equivalent to using the `--colors=auto` CLI option. Setting this attribute to `false` is equivalent to using the `--colors=never` CLI option. ### The `columns` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-columns-attribute "Permalink to this heading") Possible values: integer or string `max` (default: `80`) This attribute configures the number of columns to use for progress output. If `max` is defined as value, the number of columns will be maximum of the current terminal. ### The `controlGarbageCollector` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-controlgarbagecollector-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) When the PHP runtime automatically performs [garbage collection](https://www.php.net/manual/en/features.gc.php) then this may happen in the middle of the preparation (fixture setup) of a test or in the middle of the execution of a test. This can have a negative impact on test execution performance. Configuring `controlGarbageCollector="true"` has the following effects: * Deactivate automatic garbage collection using `gc_disable()` before the first test is run * Trigger garbage collection using `gc_collect_cycles()` before the first test is run * Trigger garbage collection using `gc_collect_cycles()` after each n-th test * Trigger garbage collection after using `gc_collect_cycles()` after the last test was run * Activate automatic garbage collection using `gc_enable()` after the last test was run The number of tests to execute before garbage collection is triggered is controlled by `numberOfTestsBeforeGarbageCollection` (see below). ### The `numberOfTestsBeforeGarbageCollection` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-numberoftestsbeforegarbagecollection-attribute "Permalink to this heading") Possible values: integer (default: `100`) Configures the number of tests to execute before garbage collection is triggered (see above). ### The `requireCoverageMetadata` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-requirecoveragemetadata-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether a test will be marked as risky (see [Unintentionally Covered Code](https://docs.phpunit.de/en/12.4/risky-tests.html#risky-tests-unintentionally-covered-code) ) when it does not indicate the code it intends to cover using an attribute. ### The `processIsolation` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-processisolation-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether each test should be run in a separate PHP process for increased isolation. ### The `stopOnDefect` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-stopondefect-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the test suite execution should be stopped after the first error, failure, warning, or risky test. ### The `stopOnError` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponerror-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the test suite execution should be stopped after the first error. ### The `stopOnFailure` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponfailure-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the test suite execution should be stopped after the first failure. ### The `stopOnWarning` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponwarning-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the test suite execution should be stopped after the first test warning. ### The `stopOnRisky` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponrisky-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the test suite execution should be stopped after the first risky test. ### The `stopOnDeprecation` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-stopondeprecation-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the test suite execution should be stopped after first test that triggered a deprecation (`E_DEPRECATED`, `E_USER_DEPRECATED`, or PHPUnit deprecation). ### The `stopOnNotice` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponnotice-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the test suite execution should be stopped after first test that triggered a notice (`E_STRICT`, `E_NOTICE`, or `E_USER_NOTICE`). ### The `stopOnSkipped` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponskipped-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the test suite execution should be stopped after first skipped test. ### The `stopOnIncomplete` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-stoponincomplete-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the test suite execution should be stopped after first incomplete test. ### The `failOnAllIssues` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-failonallissues-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the PHPUnit test runner should exit with a shell exit code that indicates failure when an issue is triggered. Backward Compatibility Please note that if you configure `failOnAllIssues` to `true` then you opt in to failing on additional issues in later versions of PHPUnit that will be put under the control of this setting. This is not considered to be a break of backward compatibility and rather the expected behaviour of this setting. ### The `failOnEmptyTestSuite` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-failonemptytestsuite-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the PHPUnit test runner should exit with a shell exit code that indicates failure when the configured test suite is empty. ### The `failOnWarning` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-failonwarning-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the PHPUnit test runner should exit with a shell exit code that indicates failure when all tests are successful but there are tests that had warnings. ### The `failOnRisky` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-failonrisky-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the PHPUnit test runner should exit with a shell exit code that indicates failure when all tests are successful but there are tests that were marked as risky. ### The `failOnDeprecation` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-failondeprecation-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the PHPUnit test runner should exit with a shell exit code that indicates failure when all tests are successful but there are tests that triggered a deprecation (`E_DEPRECATED` or `E_USER_DEPRECATED`). ### The `failOnPhpunitDeprecation` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-failonphpunitdeprecation-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the PHPUnit test runner should exit with a shell exit code that indicates failure when all tests are successful but PHPUnit deprecations were triggered. ### The `failOnNotice` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-failonnotice-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the PHPUnit test runner should exit with a shell exit code that indicates failure when all tests are successful but there are tests that triggered a notice (`E_STRICT`, `E_NOTICE`, or `E_USER_NOTICE`). ### The `failOnSkipped` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-failonskipped-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the PHPUnit test runner should exit with a shell exit code that indicates failure when all tests are successful but there are tests that were marked as skipped. ### The `failOnIncomplete` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-failonincomplete-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the PHPUnit test runner should exit with a shell exit code that indicates failure when all tests are successful but there are tests that were marked as incomplete. ### The `beStrictAboutChangesToGlobalState` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-bestrictaboutchangestoglobalstate-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether PHPUnit should mark a test as risky when global state is manipulated by the code under test (or the test code). ### The `beStrictAboutOutputDuringTests` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-bestrictaboutoutputduringtests-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether PHPUnit should mark a test as risky when the code under test (or the test code) prints output. ### The `beStrictAboutTestsThatDoNotTestAnything` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-bestrictaboutteststhatdonottestanything-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `true`) This attribute configures whether PHPUnit should mark a test as risky when no assertions are performed (expectations are also considered). ### The `beStrictAboutCoverageMetadata` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-bestrictaboutcoveragemetadata-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether PHPUnit should mark a test as risky when it executes code that is not specified to be covered or used using an attribute. ### The `enforceTimeLimit` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-enforcetimelimit-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether time limits should be enforced. ### The `defaultTimeLimit` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-defaulttimelimit-attribute "Permalink to this heading") Possible values: integer (default: `0`) This attribute configures the default time limit (in seconds). ### The `timeoutForSmallTests` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-timeoutforsmalltests-attribute "Permalink to this heading") Possible values: integer (default: `1`) This attribute configures the time limit for tests attributed with `Small` (in seconds). ### The `timeoutForMediumTests` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-timeoutformediumtests-attribute "Permalink to this heading") Possible values: integer (default: `10`) This attribute configures the time limit for tests attributed with `Medium` (in seconds). ### The `timeoutForLargeTests` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-timeoutforlargetests-attribute "Permalink to this heading") Possible values: integer (default: `60`) This attribute configures the time limit for tests attributed with `Large` (in seconds). ### The `defaultTestSuite` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-defaulttestsuite-attribute "Permalink to this heading") This attribute configures the name of the default test suite. ### The `stderr` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-stderr-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether PHPUnit should print its output to `stderr` instead of `stdout`. ### The `reverseDefectList` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-reversedefectlist-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether tests that are not successful should be printed in reverse order. ### The `registerMockObjectsFromTestArgumentsRecursively` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-registermockobjectsfromtestargumentsrecursively-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether arrays and object graphs that are passed from one test to another using the `Depends*` attributes should be recursively scanned for mock objects. ### The `extensionsDirectory` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-extensionsdirectory-attribute "Permalink to this heading") When `phpunit.phar` is used then this attribute may be used to configure a directory from which all `*.phar` files will be loaded as extensions for the PHPUnit test runner. ### The `executionOrder` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-executionorder-attribute "Permalink to this heading") Possible values: `default`, `defects`, `depends`, `no-depends`, `duration`, `random`, `reverse`, `size` (default: `default`) Using multiple values is possible. These need to be separated by `,`. This attribute configures the order in which tests are executed. * `default`: ordered as PHPUnit found the tests * `defects`: ordered by defect (errored, failed, warning, incomplete, risky, skipped, unknown, passed), requires enabled [result cache](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-phpunit-cacheresult) * `depends`: ordered by dependency (tests without dependencies first, dependent tests last) * `depends,defects`: ordered by dependency first, then ordered by defects * `depends,duration`: ordered by dependency first, then ordered by duration * `depends,random`: ordered by dependency first, then ordered randomly * `depends,reverse`: ordered by dependency first, then ordered in reverse * `duration`: ordered by duration (fastest test first, slowest test last), requires enabled [result cache](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-phpunit-cacheresult) * `no-depends`: not ordered by dependency * `no-depends,defects`: not ordered by dependency, then ordered by defects * `no-depends,duration`: not ordered by dependency, then ordered by duration * `no-depends,random`: not ordered by dependency, then ordered randomly * `no-depends,reverse`: not ordered by dependency, then ordered in reverse * `no-depends,size`: not ordered by dependency, then ordered by size * `random`: ordered randomly * `reverse`: ordered as PHPUnit found the tests, then ordered in reverse * `size`: ordered by size (small, medium, large, unknown), also see (see [Small](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-small) , [Medium](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-medium) , and [Large](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-large) ) ### The `resolveDependencies` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-resolvedependencies-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `true`) This attribute configures whether dependencies between tests (expressed using the `Depends*` attributes) should be resolved. ### The `testdox` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-testdox-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether the output should be printed in TestDox format. ### The `testdoxSummary` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-testdoxsummary-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether TestDox output for non-successful tests should be repeated after the regular TestDox output. ### The `displayDetailsOnAllIssues` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonallissues-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether details on all issues should be printed. Backward Compatibility Please note that if you configure `displayDetailsOnAllIssues` to `true` then you opt in to printing additional issues in later versions of PHPUnit that will be put under the control of this setting. This is not considered to be a break of backward compatibility and rather the expected behaviour of this setting. ### The `displayDetailsOnIncompleteTests` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonincompletetests-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether details on incomplete tests should be printed. ### The `displayDetailsOnSkippedTests` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonskippedtests-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether details on skipped tests should be printed. ### The `displayDetailsOnTestsThatTriggerDeprecations` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonteststhattriggerdeprecations-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether details on tests that triggered deprecations should be printed. ### The `displayDetailsOnPhpunitDeprecations` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonphpunitdeprecations-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether details on PHPUnit deprecations should be printed. ### The `displayDetailsOnTestsThatTriggerErrors` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonteststhattriggererrors-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether details on tests that triggered errors should be printed. ### The `displayDetailsOnTestsThatTriggerNotices` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonteststhattriggernotices-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether details on tests that triggered notices should be printed. ### The `displayDetailsOnTestsThatTriggerWarnings` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-displaydetailsonteststhattriggerwarnings-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether details on tests that triggered warnings should be printed. ### The `shortenArraysForExportThreshold` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-shortenarraysforexportthreshold-attribute "Permalink to this heading") Possible values: integer (default: `0`) This attribute configures whether the export of arrays should be limited to a specified number of elements. When set to `0` (default) then the export of arrays is not limited. The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-testsuites-element "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------------- Parent element: `` This element is the root for one or more `` elements that are used to configure the tests that are to be executed. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-testsuite-element "Permalink to this heading") Parent element: `` A `` element must have a `name` attribute and may have one or more `` and/or `` child elements that configure directories and/or files, respectively, that should be searched for tests. Files and directories can be excluded by using `` child elements. tests/unit tests/integration #### The `bootstrap` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#id1 "Permalink to this heading") Possible values: string The `bootstrap` attribute can be used to configure an additional bootstrap script for a test suite. With the configuration shown above: Invoking the PHPUnit test runner with `phpunit` loads `vendor/autoload.php` and `tests/integration/bootstrap.php`. Invoking the PHPUnit test runner with `phpunit --testsuite unit` loads only `vendor/autoload.php`. Invoking the PHPUnit test runner with `phpunit --testsuite integration` loads `vendor/autoload.php` and `tests/integration/bootstrap.php`. The script configured using the `bootstrap` attribute on the `` element is always loaded. Each bootstrap script, even if configured multiple times, is only loaded once. #### The `phpVersion` and `phpVersionOperator` Attributes[](https://docs.phpunit.de/en/12.4/configuration.html#the-phpversion-and-phpversionoperator-attributes "Permalink to this heading") Possible values: string A required PHP version can be specified using the `phpVersion` and `phpVersionOperator` attributes: tests/unit In the example above, the tests from the `tests/unit` directory are only added to the test suite if the PHP version is at least 8.0.0. The `phpVersionOperator` attribute is optional and defaults to `>=`. #### The `groups` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-groups-attribute "Permalink to this heading") Possible values: string The tests that are found using `` and `` elements can be added to a comma-separated list of groups: tests/foo-bar The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-source-element "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------- Parent element: `` Configures the project’s source code files. This is used to restrict code coverage analysis and reporting of deprecations, notices, and warnings to your own code, for instance, while excluding code from third-party dependencies. In the following, we refer to code that is configured using this element as “your code” or “first-party code”. We refer to code that is not “your code” as “third-party code”. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-include-element "Permalink to this heading") Parent element: `` Configures a set of files to be included in the list of the project’s source code files. src The example shown above instructs PHPUnit to include all source code files with `.php` suffix in the `src` directory and its sub-directories. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-exclude-element "Permalink to this heading") Parent element: `` Configures a set of files to be excluded from the list of the project’s source code files. src src/generated src/autoload.php The example shown above instructs PHPUnit to include all source code files with `.php` suffix in the `src` directory and its sub-directories, but to exclude all files with `.php` suffix in the `src/generated` directory and its sub-directories as well as the `src/autoload.php` file. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-directory-element "Permalink to this heading") Parent elements: ``, `` Configures a directory and its sub-directories for inclusion in or exclusion from the list of the project’s source code files. #### The `prefix` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-prefix-attribute "Permalink to this heading") Possible values: string Configures a prefix-based filter that is applied to the names of files in the directory and its sub-directories. #### The `suffix` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-suffix-attribute "Permalink to this heading") Possible values: string (default: `'.php'`) Configures a suffix-based filter that is applied to the names of files in the directory and its sub-directories. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-file-element "Permalink to this heading") Parent elements: ``, `` Configures a file for inclusion in or exclusion from the list of the project’s source code files. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-deprecationtrigger-element "Permalink to this heading") Parent element: `` Some libraries use a wrapper around PHP’s `trigger_error()` function such as `symfony/deprecation-contracts` or `doctrine/deprecations`. Using such a wrapper adds an additional stack frame that needs to be considered when reporting of the location where a deprecation was triggered. The `` element, together with its child elements `` and `` can be used to configure functions or methods, respectively, as deprecation triggers. #### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-function-element "Permalink to this heading") Parent element: `` trigger\_deprecation The example configuration shown above configures the global function `trigger_deprecation()` as a deprecation trigger. #### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-method-element "Permalink to this heading") Parent element: `` DeprecationTrigger::triggerDeprecation The example configuration shown above configures the `public` `static` method `triggerDeprecation()` of the `DeprecationTrigger` class as a deprecation trigger. ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoreselfdeprecations-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Ignore deprecations (`E_DEPRECATED` and `E_USER_DEPRECATED`) triggered by first-party code in first-party code. ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoredirectdeprecations-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Ignore deprecations (`E_DEPRECATED` and `E_USER_DEPRECATED`) triggered by first-party code in third-party code. ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoreindirectdeprecations-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`, suggested: `true`) Ignore deprecations (`E_DEPRECATED` and `E_USER_DEPRECATED`) triggered by third-party code. ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-restrictnotices-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Restricts the reporting of `E_STRICT`, `E_NOTICE`, and `E_USER_NOTICE` [errors](https://www.php.net/manual/en/errorfunc.constants.php) to the list of the project’s source code files. ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-restrictwarnings-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Restricts the reporting of `E_WARNING` and `E_USER_WARNING` [errors](https://www.php.net/manual/en/errorfunc.constants.php) to the list of the project’s source code files. ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-baseline-attribute "Permalink to this heading") Possible values: string The baseline file to be used when running the test suite. ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofdeprecations-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Ignore the suppression (using the `@` operator) of `E_USER_DEPRECATED` [errors](https://www.php.net/manual/en/errorfunc.constants.php) . ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofphpdeprecations-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Ignore the suppression (using the `@` operator) of `E_DEPRECATED` [errors](https://www.php.net/manual/en/errorfunc.constants.php) . ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionoferrors-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Ignore the suppression (using the `@` operator) of `E_USER_ERROR` [errors](https://www.php.net/manual/en/errorfunc.constants.php) . ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofnotices-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Ignore the suppression (using the `@` operator) of `E_USER_NOTICE` [errors](https://www.php.net/manual/en/errorfunc.constants.php) . ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofphpnotices-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Ignore the suppression (using the `@` operator) of `E_STRICT` and `E_NOTICE` [errors](https://www.php.net/manual/en/errorfunc.constants.php) . ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofwarnings-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Ignore the suppression (using the `@` operator) of `E_USER_WARNING` [errors](https://www.php.net/manual/en/errorfunc.constants.php) . ### The `` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoresuppressionofphpwarnings-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) Ignore the suppression (using the `@` operator) of `E_WARNING` [errors](https://www.php.net/manual/en/errorfunc.constants.php) . The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-coverage-element "Permalink to this heading") --------------------------------------------------------------------------------------------------------------------------------- Parent element: `` The `` element and its children can be used to configure code coverage: ### The `includeUncoveredFiles` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-includeuncoveredfiles-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `true`) When set to `true`, all source code files that are configured to be considered for code coverage analysis will be included in the code coverage report(s). This includes source code files that are not executed while the tests are running. ### The `ignoreDeprecatedCodeUnits` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-ignoredeprecatedcodeunits-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether code units annotated with `@deprecated` should be ignored from code coverage. ### The `pathCoverage` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-pathcoverage-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) When set to `false`, only line coverage data will be collected, processed, and reported. When set to `true`, line coverage, branch coverage, and path coverage data will be collected, processed, and reported. This requires a code coverage driver that supports path coverage. Path Coverage is currently only implemented by Xdebug. ### The `disableCodeCoverageIgnore` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-disablecodecoverageignore-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) This attribute configures whether metadata to ignore code should be ignored. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-report-element "Permalink to this heading") Parent element: `` Configures the code coverage reports to be generated. #### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-clover-element "Permalink to this heading") Parent element: `` Configures a code coverage report in Clover XML format. ##### The `outputFile` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-outputfile-attribute "Permalink to this heading") Possible values: string The file to which the Clover XML report is written. #### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-cobertura-element "Permalink to this heading") Parent element: `` Configures a code coverage report in Cobertura XML format. ##### The `outputFile` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#id10 "Permalink to this heading") Possible values: string The file to which the Cobertura XML report is written. #### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-crap4j-element "Permalink to this heading") Parent element: `` Configures a code coverage report in Crap4J XML format. ##### The `outputFile` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#id11 "Permalink to this heading") Possible values: string The file to which the Crap4J XML report is written. ##### The `threshold` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-threshold-attribute "Permalink to this heading") Possible values: integer (default: `50`) #### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-html-element "Permalink to this heading") Parent element: `` Configures a code coverage report in HTML format. ##### The `outputDirectory` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-outputdirectory-attribute "Permalink to this heading") The directory to which the HTML report is written. ##### The `lowUpperBound` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-lowupperbound-attribute "Permalink to this heading") Possible values: integer (default: `50`) The upper bound of what should be considered “low coverage”. ##### The `highLowerBound` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-highlowerbound-attribute "Permalink to this heading") Possible values: integer (default: `90`) The lower bound of what should be considered “high coverage”. ##### The `colorSuccessHigh` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-colorsuccesshigh-attribute "Permalink to this heading") Possible values: string (default: `#99cb84`) The color used to indicate that a line of code is covered by small (and larger) tests, for instance. ##### The `colorSuccessMedium` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-colorsuccessmedium-attribute "Permalink to this heading") Possible values: string (default: `#c3e3b5`) The color used to indicate that a line of code is covered by medium (and large) tests, for instance. ##### The `colorSuccessLow` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-colorsuccesslow-attribute "Permalink to this heading") Possible values: string (default: `#dff0d8`) The color used to indicate that a line of code is covered by large tests, for instance. ##### The `colorWarning` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-colorwarning-attribute "Permalink to this heading") Possible values: string (default: `#fcf8e3`) The color used to indicate that a line of code cannot be covered, for instance. ##### The `colorDanger` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-colordanger-attribute "Permalink to this heading") Possible values: string (default: `#f2dede`) The color used to indicate that a line of code can be covered but is not covered, for instance. ##### The `customCssFile` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-customcssfile-attribute "Permalink to this heading") Possible values: string The path to a custom CSS file. #### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-php-element "Permalink to this heading") Parent element: `` Configures a code coverage report in PHP format. ##### The `outputFile` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#id12 "Permalink to this heading") Possible values: string The file to which the PHP report is written. #### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-text-element "Permalink to this heading") Parent element: `` Configures a code coverage report in text format. ##### The `outputFile` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#id13 "Permalink to this heading") Possible values: string The file to which the text report is written. ##### The `showUncoveredFiles` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-showuncoveredfiles-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) ##### The `showOnlySummary` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#the-showonlysummary-attribute "Permalink to this heading") Possible values: `true` or `false` (default: `false`) #### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-xml-element "Permalink to this heading") Parent element: `` Configures a code coverage report in PHPUnit XML format. ##### The `outputDirectory` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#id14 "Permalink to this heading") Possible values: string The directory to which the PHPUnit XML report is written. The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-logging-element "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------- Parent element: `` The `` element and its children can be used to configure the logging of the test execution. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-junit-element "Permalink to this heading") Parent element: `` Configures a test result logfile in JUnit XML format. #### The `outputFile` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#id15 "Permalink to this heading") Possible values: string The file to which the test result logfile in JUnit XML format is written. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-teamcity-element "Permalink to this heading") Parent element: `` Configures a test result logfile in TeamCity format. #### The `outputFile` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#id16 "Permalink to this heading") Possible values: string The file to which the test result logfile in TeamCity format is written. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-testdoxhtml-element "Permalink to this heading") Parent element: `` Configures a test result logfile in TestDox HTML format. #### The `outputFile` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#id17 "Permalink to this heading") Possible values: string The file to which the test result logfile in TestDox HTML format is written. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-testdoxtext-element "Permalink to this heading") Parent element: `` Configures a test result logfile in TestDox text format. #### The `outputFile` Attribute[](https://docs.phpunit.de/en/12.4/configuration.html#id18 "Permalink to this heading") Possible values: string The file to which the test result logfile in TestDox text format is written. The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-groups-element "Permalink to this heading") ----------------------------------------------------------------------------------------------------------------------------- Parent element: `` The `` element and its ``, ``, and `` children can be used to select groups of tests marked with the `Group` attribute (documented in [Group](https://docs.phpunit.de/en/12.4/attributes.html#appendixes-attributes-group) ) that should (not) be run: name name The example shown above is equivalent to invoking the PHPUnit test runner with `--group name --exclude-group name`. The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-extensions-element "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------------- Parent element: `` The `` element and its `` children can be used to register test runner extensions. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-bootstrap-element "Permalink to this heading") Parent element: `` #### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-parameter-element "Permalink to this heading") Parent element: `` The `` element can be used to configure parameters that are passed to the extension for bootstrapping. The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#appendixes-configuration-php "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------------------ Parent element: `` The `` element and its children can be used to configure PHP settings, constants, and global variables. It can also be used to prepend the `include_path`. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-includepath-element "Permalink to this heading") Parent element: `` This element can be used to prepend a path to the `include_path`. ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-ini-element "Permalink to this heading") Parent element: `` This element can be used to set a PHP configuration setting. The XML configuration above corresponds to the following PHP code: ini\_set('foo', 'bar'); ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-const-element "Permalink to this heading") Parent element: `` This element can be used to set a global constant. The XML configuration above corresponds to the following PHP code: define('foo', 'bar'); ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-var-element "Permalink to this heading") Parent element: `` This element can be used to set a global variable. The XML configuration above corresponds to the following PHP code: $GLOBALS\['foo'\] \= 'bar'; ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-env-element "Permalink to this heading") Parent element: `` This element can be used to set a value in the super-global array `$_ENV`. The XML configuration above corresponds to the following PHP code: $\_ENV\['foo'\] \= 'bar'; By default, environment variables are not overwritten if they exist already. To force overwriting existing variables, use the `force` attribute: ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-get-element "Permalink to this heading") Parent element: `` This element can be used to set a value in the super-global array `$_GET`. The XML configuration above corresponds to the following PHP code: $\_GET\['foo'\] \= 'bar'; ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-post-element "Permalink to this heading") Parent element: `` This element can be used to set a value in the super-global array `$_POST`. The XML configuration above corresponds to the following PHP code: $\_POST\['foo'\] \= 'bar'; ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-cookie-element "Permalink to this heading") Parent element: `` This element can be used to set a value in the super-global array `$_COOKIE`. The XML configuration above corresponds to the following PHP code: $\_COOKIE\['foo'\] \= 'bar'; ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-server-element "Permalink to this heading") Parent element: `` This element can be used to set a value in the super-global array `$_SERVER`. The XML configuration above corresponds to the following PHP code: $\_SERVER\['foo'\] \= 'bar'; ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-files-element "Permalink to this heading") Parent element: `` This element can be used to set a value in the super-global array `$_FILES`. The XML configuration above corresponds to the following PHP code: $\_FILES\['foo'\] \= 'bar'; ### The `` Element[](https://docs.phpunit.de/en/12.4/configuration.html#the-request-element "Permalink to this heading") Parent element: `` This element can be used to set a value in the super-global array `$_REQUEST`. The XML configuration above corresponds to the following PHP code: $\_REQUEST\['foo'\] \= 'bar'; --- # 1. Assertions — PHPUnit 12.4 Manual * [](https://docs.phpunit.de/en/12.4/index.html) * 1\. Assertions * [Edit on GitHub](https://github.com/sebastianbergmann/phpunit-documentation-english/blob/12.4/src/assertions.rst) * * * 1\. Assertions[](https://docs.phpunit.de/en/12.4/assertions.html#assertions "Permalink to this heading") ========================================================================================================== This appendix lists the various assertion methods that are available. Static vs. Non-Static Usage of Assertion Methods[](https://docs.phpunit.de/en/12.4/assertions.html#static-vs-non-static-usage-of-assertion-methods "Permalink to this heading") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- PHPUnit’s assertions are implemented in `PHPUnit\Framework\Assert`. `PHPUnit\Framework\TestCase` inherits from `PHPUnit\Framework\Assert`. The assertion methods are declared static and can be invoked from any context using `PHPUnit\Framework\Assert::assertTrue()`, for instance, or using `$this->assertTrue()` or `self::assertTrue()`, for instance, in a class that extends `PHPUnit\Framework\TestCase`. You can even use global function wrappers such as `assertTrue()`. A common question, especially from developers new to PHPUnit, is whether using `$this->assertTrue()` or `self::assertTrue()`, for instance, is “the right way” to invoke an assertion. The short answer is: there is no right way. And there is no wrong way, either. It is a matter of personal preference. For most people it just “feels right” to use `$this->assertTrue()` because the test method is invoked on a test object. The fact that the assertion methods are declared static allows for (re)using them outside the scope of a test object. Lastly, the global function wrappers allow developers to type less characters (`assertTrue()` instead of `$this->assertTrue()` or `self::assertTrue()`). Boolean[](https://docs.phpunit.de/en/12.4/assertions.html#boolean "Permalink to this heading") ------------------------------------------------------------------------------------------------ ### `assertTrue()`[](https://docs.phpunit.de/en/12.4/assertions.html#asserttrue "Permalink to this heading") `assertTrue(bool $condition[, string $message])` Reports an error identified by `$message` if `$condition` is `false`. `assertNotTrue()` is the inverse of this assertion and takes the same arguments. Example 1.1 Usage of assertTrue()[](https://docs.phpunit.de/en/12.4/assertions.html#id1 "Permalink to this code") assertTrue(false); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/TrueTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) TrueTest::testFailure Failed asserting that false is true. /path/to/tests/TrueTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertFalse()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertfalse "Permalink to this heading") `assertFalse(bool $condition[, string $message])` Reports an error identified by `$message` if `$condition` is `true`. `assertNotFalse()` is the inverse of this assertion and takes the same arguments. Example 1.2 Usage of assertFalse()[](https://docs.phpunit.de/en/12.4/assertions.html#id2 "Permalink to this code") assertFalse(true); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/FalseTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) FalseTest::testFailure Failed asserting that true is false. /path/to/tests/FalseTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Identity[](https://docs.phpunit.de/en/12.4/assertions.html#appendixes-assertions-identity "Permalink to this heading") ------------------------------------------------------------------------------------------------------------------------ ### `assertSame()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertsame "Permalink to this heading") `assertSame(mixed $expected, mixed $actual[, string $message])` Reports an error identified by `$message` if the two variables `$expected` and `$actual` do not have the same type and value. `assertNotSame()` is the inverse of this assertion and takes the same arguments. Example 1.3 Usage of assertSame()[](https://docs.phpunit.de/en/12.4/assertions.html#id3 "Permalink to this code") assertSame('2204', 2204); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/SameWithMixedTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) SameWithMixedTest::testFailure Failed asserting that 2204 is identical to '2204'. /path/to/tests/SameWithMixedTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. `assertSame(object $expected, object $actual[, string $message])` Reports an error identified by `$message` if the two variables `$expected` and `$actual` do not reference the same object. Example 1.4 Usage of assertSame() with objects[](https://docs.phpunit.de/en/12.4/assertions.html#id4 "Permalink to this code") assertSame(new stdClass, new stdClass); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/SameWithObjectsTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) SameWithObjectsTest::testFailure Failed asserting that two variables reference the same object. /path/to/tests/SameWithObjectsTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Identity is checked using the `===` operator. ### `assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertarrayisidenticaltoarrayonlyconsideringlistofkeys "Permalink to this heading") `assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys(array $expected, array $actual, array $keysToBeConsidered[, string $message])` Reports an error identified by `$message` if two arrays are not identical while only considering array elements for which the keys have been specified. Example 1.5 Usage of assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys()[](https://docs.phpunit.de/en/12.4/assertions.html#id5 "Permalink to this code") assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys( \[\ 'timestamp' \=> time(),\ 'foo' \=> 'bar',\ \], \[\ 'timestamp' \=> time(),\ 'foo' \=> 'baz',\ \], \[\ 'foo',\ \], ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ArrayIsIdenticalToArrayOnlyConsideringListOfKeysTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ArrayIsIdenticalToArrayOnlyConsideringListOfKeysTest::testFailure Failed asserting that two arrays are identical. --- Expected +++ Actual @@ @@ Array &0 \[\ - 'foo' => 'bar',\ + 'foo' => 'baz',\ \] /path/to/tests/ArrayIsIdenticalToArrayOnlyConsideringListOfKeysTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertArrayIsIdenticalToArrayIgnoringListOfKeys()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertarrayisidenticaltoarrayignoringlistofkeys "Permalink to this heading") `assertArrayIsIdenticalToArrayIgnoringListOfKeys(array $expected, array $actual, array $keysToBeIgnored[, string $message])` Reports an error identified by `$message` if two arrays are not identical while only ignoring array elements for which the keys have been specified. Example 1.6 Usage of assertArrayIsIdenticalToArrayIgnoringListOfKeys()[](https://docs.phpunit.de/en/12.4/assertions.html#id6 "Permalink to this code") assertArrayIsIdenticalToArrayIgnoringListOfKeys( \[\ 'timestamp' \=> time(),\ 'foo' \=> 'bar',\ \], \[\ 'timestamp' \=> time(),\ 'foo' \=> 'baz',\ \], \[\ 'timestamp',\ \], ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ArrayIsIdenticalToArrayIgnoringListOfKeysTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ArrayIsIdenticalToArrayIgnoringListOfKeysTest::testFailure Failed asserting that two arrays are identical. --- Expected +++ Actual @@ @@ Array &0 \[\ - 'foo' => 'bar',\ + 'foo' => 'baz',\ \] /path/to/tests/ArrayIsIdenticalToArrayIgnoringListOfKeysTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Equality[](https://docs.phpunit.de/en/12.4/assertions.html#equality "Permalink to this heading") -------------------------------------------------------------------------------------------------- ### `assertEquals()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertequals "Permalink to this heading") `assertEquals(mixed $expected, mixed $actual[, string $message])` Reports an error identified by `$message` if the two variables `$expected` and `$actual` are not equal. `assertNotEquals()` is the inverse of this assertion and takes the same arguments. Example 1.7 Usage of assertEquals()[](https://docs.phpunit.de/en/12.4/assertions.html#id7 "Permalink to this code") assertEquals(1, 0); } public function testFailure2(): void { $this\->assertEquals('bar', 'baz'); } public function testFailure3(): void { $this\->assertEquals("foo\\nbar\\nbaz\\n", "foo\\nbah\\nbaz\\n"); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/EqualsTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 FFF 3 / 3 (100%) Time: 00:00.001, Memory: 15.81 MB There were 3 failures: 1) EqualsTest::testFailure Failed asserting that 0 matches expected 1. /path/to/tests/EqualsTest.php:8 2) EqualsTest::testFailure2 Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'bar' +'baz' /path/to/tests/EqualsTest.php:13 3) EqualsTest::testFailure3 Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ 'foo\\n -bar\\n +bah\\n baz\\n ' /path/to/tests/EqualsTest.php:18 FAILURES! Tests: 3, Assertions: 3, Failures: 3. Equality is checked using the `==` operator, but more specialized comparisons are used for specific argument types for `$expected` and `$actual`, see below. `assertEquals(DateTimeInterface $expected, DateTimeInterface $actual[, string $message])` Reports an error identified by `$message` if the two points in time represented by the two `DateTimeInterface` objects `$expected` and `$actual` are not equal. Example 1.8 Usage of assertEquals() with DateTimeImmutable objects[](https://docs.phpunit.de/en/12.4/assertions.html#id8 "Permalink to this code") assertEquals($expected, $actual); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/EqualsWithDateTimeImmutableTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00.001, Memory: 15.81 MB There was 1 failure: 1) EqualsWithDateTimeImmutableTest::testFailure Failed asserting that two DateTime objects are equal. --- Expected +++ Actual @@ @@ -2023-02-23T01:23:45.000000+0100 +2023-02-23T01:23:46.000000+0100 /path/to/tests/EqualsWithDateTimeImmutableTest.php:11 FAILURES! Tests: 1, Assertions: 1, Failures: 1. `assertEquals(DOMDocument $expected, DOMDocument $actual[, string $message])` Reports an error identified by `$message` if the uncommented canonical form of the XML documents represented by the two `DOMDocument` objects `$expected` and `$actual` are not equal. Example 1.9 Usage of assertEquals() with DOMDocument objects[](https://docs.phpunit.de/en/12.4/assertions.html#id9 "Permalink to this code") loadXML(''); $actual \= new DOMDocument; $actual\->loadXML(''); $this\->assertEquals($expected, $actual); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/EqualsWithDomDocumentTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) EqualsWithDomDocumentTest::testFailure Failed asserting that two DOM documents are equal. --- Expected +++ Actual @@ @@ - - - + + + /path/to/tests/EqualsWithDomDocumentTest.php:14 FAILURES! Tests: 1, Assertions: 1, Failures: 1. `assertEquals(object $expected, object $actual[, string $message])` Reports an error identified by `$message` if the two objects `$expected` and `$actual` do not have equal property values. Example 1.10 Usage of assertEquals() with objects[](https://docs.phpunit.de/en/12.4/assertions.html#id10 "Permalink to this code") foo \= 'foo'; $expected\->bar \= 'bar'; $actual \= new stdClass; $actual\->foo \= 'bar'; $actual\->baz \= 'bar'; $this\->assertEquals($expected, $actual); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/EqualsWithObjectsTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) EqualsWithObjectsTest::testFailure Failed asserting that two objects are equal. --- Expected +++ Actual @@ @@ stdClass Object ( - 'foo' => 'foo' - 'bar' => 'bar' + 'foo' => 'bar' + 'baz' => 'bar' ) /path/to/tests/EqualsWithObjectsTest.php:16 FAILURES! Tests: 1, Assertions: 1, Failures: 1. `assertEquals(array $expected, array $actual[, string $message])` Reports an error identified by `$message` if the two arrays `$expected` and `$actual` are not equal. Example 1.11 Usage of assertEquals() with arrays[](https://docs.phpunit.de/en/12.4/assertions.html#id11 "Permalink to this code") assertEquals(\['a', 'b', 'c'\], \['a', 'c', 'd'\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/EqualsWithArraysTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) EqualsWithArraysTest::testFailure Failed asserting that two arrays are equal. --- Expected +++ Actual @@ @@ Array ( 0 => 'a' - 1 => 'b' - 2 => 'c' + 1 => 'c' + 2 => 'd' ) /path/to/tests/EqualsWithArraysTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertEqualsCanonicalizing()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertequalscanonicalizing "Permalink to this heading") `assertEqualsCanonicalizing(mixed $expected, mixed $actual[, string $message])` Reports an error identified by `$message` if the two variables `$expected` and `$actual` are not equal. The contents of `$expected` and `$actual` are canonicalized before they are compared. For instance, when the two variables `$expected` and `$actual` are arrays, then these arrays are sorted before they are compared. When `$expected` and `$actual` are objects, each object is converted to an array containing all private, protected and public properties. `assertNotEqualsCanonicalizing()` is the inverse of this assertion and takes the same arguments. Example 1.12 Usage of assertEqualsCanonicalizing()[](https://docs.phpunit.de/en/12.4/assertions.html#id12 "Permalink to this code") assertEqualsCanonicalizing(\[3, 2, 1\], \[2, 3, 0, 1\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/EqualsWithArraysCanonicalizingTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) EqualsWithArraysCanonicalizingTest::testFailure Failed asserting that two arrays are equal. --- Expected +++ Actual @@ @@ Array ( - 0 => 1 - 1 => 2 - 2 => 3 + 0 => 0 + 1 => 1 + 2 => 2 + 3 => 3 ) /path/to/tests/EqualsWithArraysCanonicalizingTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertEqualsIgnoringCase()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertequalsignoringcase "Permalink to this heading") `assertEqualsIgnoringCase(mixed $expected, mixed $actual[, string $message])` Reports an error identified by `$message` if the two variables `$expected` and `$actual` are not equal. Differences in casing are ignored for the comparison of `$expected` and `$actual`. `assertNotEqualsIgnoringCase()` is the inverse of this assertion and takes the same arguments. Example 1.13 Usage of assertEqualsIgnoringCase()[](https://docs.phpunit.de/en/12.4/assertions.html#id13 "Permalink to this code") assertEqualsIgnoringCase('foo', 'BAR'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/EqualsWithStringsIgnoringCaseTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) EqualsWithStringsIgnoringCaseTest::testFailure Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'foo' +'BAR' /path/to/tests/EqualsWithStringsIgnoringCaseTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertEqualsWithDelta()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertequalswithdelta "Permalink to this heading") `assertEqualsWithDelta(mixed $expected, mixed $actual, float $delta[, string $message])` Reports an error identified by `$message` if the absolute difference between `$expected` and `$actual` is greater than `$delta`. Please read “[What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) ” to understand why `$delta` is necessary. `assertNotEqualsWithDelta()` is the inverse of this assertion and takes the same arguments. Example 1.14 Usage of assertEqualsWithDelta()[](https://docs.phpunit.de/en/12.4/assertions.html#id14 "Permalink to this code") assertEqualsWithDelta(1.0, 1.5, 0.1); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/EqualsWithFloatsAndDeltaTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) EqualsWithFloatsAndDeltaTest::testFailure Failed asserting that 1.5 matches expected 1.0. /path/to/tests/EqualsWithFloatsAndDeltaTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertObjectEquals()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertobjectequals "Permalink to this heading") `assertObjectEquals(object $expected, object $actual, string $method = 'equals'[, string $message])` Reports an error identified by `$message` if `$actual` is not equal to `$expected` according to `$actual->$method($expected)`. It is a bad practice to use `assertEquals()` (and its inverse, `assertNotEquals()`) on objects without registering a custom comparator that customizes how objects are compared. Unfortunately, though, implementing custom comparators for each and every object you want to assert in your tests is inconvenient at best. The most common use case for custom comparators are Value Objects. These objects usually have an `equals(self $other): bool` method (or a method just like that but with a different name) for comparing two instances of the Value Object’s type. `assertObjectEquals()` makes custom comparison of objects convenient for this common use case: `assertObjectNotEquals()` is the inverse of this assertion and takes the same arguments. Example 1.15 Usage of assertObjectEquals()[](https://docs.phpunit.de/en/12.4/assertions.html#id15 "Permalink to this code") assertObjectEquals($a, $b); // This fails $this\->assertObjectEquals($a, $c); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ObjectEqualsTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ObjectEqualsTest::testSomething Failed asserting that two objects are equal. /path/to/tests/ObjectEqualsTest.php:16 FAILURES! Tests: 1, Assertions: 2, Failures: 1. Example 1.16 Email value object with equals() method[](https://docs.phpunit.de/en/12.4/assertions.html#id16 "Permalink to this code") ensureIsValidEmail($email); $this\->email \= $email; } public function asString(): string { return $this\->email; } public function equals(self $other): bool { return $this\->asString() \=== $other\->asString(); } private function ensureIsValidEmail(string $email): void { // ... } } Please note: * A method with name `$method` must exist on the `$actual` object * The method must accept exactly one argument * The respective parameter must have a declared type * The `$expected` object must be compatible with this declared type * The method must have a declared `bool` return type If any of the aforementioned assumptions is not fulfilled or if `$actual->$method($expected)` returns `false` then the assertion fails. ### `assertFileEquals()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertfileequals "Permalink to this heading") `assertFileEquals(string $expected, string $actual[, string $message])` Reports an error identified by `$message` if the file specified by `$expected` does not have the same contents as the file specified by `$actual`. `assertFileNotEquals()` is the inverse of this assertion and takes the same arguments. `assertFileEqualsCanonicalizing()` (and `assertFileNotEqualsCanonicalizing()`) as well as `assertFileEqualsIgnoringCase()` (and `assertFileNotEqualsIgnoringCase()`) do for files what `assertEqualsCanonicalizing()` (and `assertNotEqualsCanonicalizing()`) as well as `assertEqualsIgnoringCase()` (and `assertNotEqualsIgnoringCase()`) do for strings. Example 1.17 Usage of assertFileEquals()[](https://docs.phpunit.de/en/12.4/assertions.html#id17 "Permalink to this code") assertFileEquals( \_\_DIR\_\_ . '/expected.txt', \_\_DIR\_\_ . '/actual.txt', ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/FileEqualsTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) FileEqualsTest::testFailure Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'expected\\n +'actual\\n ' /path/to/tests/FileEqualsTest.php:8 FAILURES! Tests: 1, Assertions: 3, Failures: 1. ### `assertArrayIsEqualToArrayOnlyConsideringListOfKeys()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertarrayisequaltoarrayonlyconsideringlistofkeys "Permalink to this heading") `assertArrayIsEqualToArrayOnlyConsideringListOfKeys(array $expected, array $actual, array $keysToBeConsidered[, string $message])` Reports an error identified by `$message` if two arrays are not equal while only considering array elements for which the keys have been specified. Example 1.18 Usage of assertArrayIsEqualToArrayOnlyConsideringListOfKeys()[](https://docs.phpunit.de/en/12.4/assertions.html#id18 "Permalink to this code") assertArrayIsEqualToArrayOnlyConsideringListOfKeys( \[\ 'timestamp' \=> time(),\ 'foo' \=> 'bar',\ \], \[\ 'timestamp' \=> time(),\ 'foo' \=> 'baz',\ \], \[\ 'foo',\ \], ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ArrayIsEqualToArrayOnlyConsideringListOfKeysTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ArrayIsEqualToArrayOnlyConsideringListOfKeysTest::testFailure Failed asserting that two arrays are equal. --- Expected +++ Actual @@ @@ Array ( - 'foo' => 'bar' + 'foo' => 'baz' ) /path/to/tests/ArrayIsEqualToArrayOnlyConsideringListOfKeysTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertArrayIsEqualToArrayIgnoringListOfKeys()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertarrayisequaltoarrayignoringlistofkeys "Permalink to this heading") `assertArrayIsEqualToArrayIgnoringListOfKeys(array $expected, array $actual, array $keysToBeIgnored[, string $message])` Reports an error identified by `$message` if two arrays are not equal while only ignoring array elements for which the keys have been specified. Example 1.19 Usage of assertArrayIsEqualToArrayIgnoringListOfKeys()[](https://docs.phpunit.de/en/12.4/assertions.html#id19 "Permalink to this code") assertArrayIsEqualToArrayIgnoringListOfKeys( \[\ 'timestamp' \=> time(),\ 'foo' \=> 'bar',\ \], \[\ 'timestamp' \=> time(),\ 'foo' \=> 'baz',\ \], \[\ 'timestamp',\ \], ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ArrayIsEqualToArrayIgnoringListOfKeysTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ArrayIsEqualToArrayIgnoringListOfKeysTest::testFailure Failed asserting that two arrays are equal. --- Expected +++ Actual @@ @@ Array ( - 'foo' => 'bar' + 'foo' => 'baz' ) /path/to/tests/ArrayIsEqualToArrayIgnoringListOfKeysTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Iterable[](https://docs.phpunit.de/en/12.4/assertions.html#iterable "Permalink to this heading") -------------------------------------------------------------------------------------------------- ### `assertArrayHasKey()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertarrayhaskey "Permalink to this heading") `assertArrayHasKey(int|string $key, array|ArrayAccess $array[, string $message])` Reports an error identified by `$message` if `$array` does not have the `$key`. `assertArrayNotHasKey()` is the inverse of this assertion and takes the same arguments. Example 1.20 Usage of assertArrayHasKey()[](https://docs.phpunit.de/en/12.4/assertions.html#id20 "Permalink to this code") assertArrayHasKey('foo', \['bar' \=> 'baz'\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ArrayHasKeyTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ArrayHasKeyTest::testFailure Failed asserting that an array has the key 'foo'. /path/to/tests/ArrayHasKeyTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContains()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontains "Permalink to this heading") `assertContains(mixed $needle, iterable $haystack[, string $message])` Reports an error identified by `$message` if `$needle` is not an element of `$haystack`. `assertNotContains()` is the inverse of this assertion and takes the same arguments. Example 1.21 Usage of assertContains()[](https://docs.phpunit.de/en/12.4/assertions.html#id21 "Permalink to this code") assertContains(4, \[1, 2, 3\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsTest::testFailure Failed asserting that an array contains 4. /path/to/tests/ContainsTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Whether `$needle` is an element of `$haystack` is checked using the `===` operator. You can use `assertContainsEquals()` (and `assertNotContainsEquals()`) if you need the comparison logic implemented by the `==` operator. ### `assertContainsOnly()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonly "Permalink to this heading") `assertContainsOnly(string $type, iterable $haystack[, boolean $isNativeType = null, string $message = ''])` Reports an error identified by `$message` if `$haystack` does not contain only variables of type `$type`. `$isNativeType` is a flag used to indicate whether `$type` is a native PHP type. These are the strings supported for `$type` when `$isNativeType` is `true`: `array`, `bool`, `boolean`, `callable`, `double`, `float`, `int`, `integer`, `iterable`, `null`, `numeric`, `object`, `real`, `resource`, `scalar`, or `string`. `assertNotContainsOnly()` is the inverse of this assertion and takes the same arguments. Example 1.22 Usage of assertContainsOnly()[](https://docs.phpunit.de/en/12.4/assertions.html#id22 "Permalink to this code") assertContainsOnly('string', \['1', '2', 3\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyTest::testFailure Failed asserting that Array &0 \[\ 0 => '1',\ 1 => '2',\ 2 => 3,\ \] contains only values of type "string". /path/to/tests/ContainsOnlyTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1, PHPUnit Deprecations: 1. Deprecation: `assertContainsOnly()` is deprecated As of PHPUnit 12.0, the `assertContainsOnly()` method is hard-deprecated. Using this method will trigger a deprecation warning. The method will be removed in PHPUnit 13. ### `assertContainsOnlyArray()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyarray "Permalink to this heading") `assertContainsOnlyArray(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `array`. `assertContainsNotOnlyArray()` is the inverse of this assertion and takes the same arguments. Example 1.23 Usage of assertContainsOnlyArray()[](https://docs.phpunit.de/en/12.4/assertions.html#id23 "Permalink to this code") assertContainsOnlyArray(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyArrayTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyArrayTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "array". /path/to/tests/ContainsOnlyArrayTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyBool()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlybool "Permalink to this heading") `assertContainsOnlyBool(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `bool`. `assertContainsNotOnlyBool()` is the inverse of this assertion and takes the same arguments. Example 1.24 Usage of assertContainsOnlyBool()[](https://docs.phpunit.de/en/12.4/assertions.html#id24 "Permalink to this code") assertContainsOnlyBool(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyBoolTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyBoolTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "bool". /path/to/tests/ContainsOnlyBoolTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyCallable()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlycallable "Permalink to this heading") `assertContainsOnlyCallable(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `callable`. `assertContainsNotOnlyCallable()` is the inverse of this assertion and takes the same arguments. Example 1.25 Usage of assertContainsOnlyCallable()[](https://docs.phpunit.de/en/12.4/assertions.html#id25 "Permalink to this code") assertContainsOnlyCallable(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyCallableTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyCallableTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "callable". /path/to/tests/ContainsOnlyCallableTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyFloat()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyfloat "Permalink to this heading") `assertContainsOnlyFloat(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `float`. `assertContainsNotOnlyFloat()` is the inverse of this assertion and takes the same arguments. Example 1.26 Usage of assertContainsOnlyFloat()[](https://docs.phpunit.de/en/12.4/assertions.html#id26 "Permalink to this code") assertContainsOnlyFloat(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyFloatTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyFloatTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "float". /path/to/tests/ContainsOnlyFloatTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyInt()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyint "Permalink to this heading") `assertContainsOnlyInt(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `int`. `assertContainsNotOnlyInt()` is the inverse of this assertion and takes the same arguments. Example 1.27 Usage of assertContainsOnlyInt()[](https://docs.phpunit.de/en/12.4/assertions.html#id27 "Permalink to this code") assertContainsOnlyInt(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyIntTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyIntTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "int". /path/to/tests/ContainsOnlyIntTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyIterable()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyiterable "Permalink to this heading") `assertContainsOnlyIterable(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `iterable`. `assertContainsNotOnlyInt()` is the inverse of this assertion and takes the same arguments. Example 1.28 Usage of assertContainsOnlyIterable()[](https://docs.phpunit.de/en/12.4/assertions.html#id28 "Permalink to this code") assertContainsOnlyIterable(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyIterableTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyIterableTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "iterable". /path/to/tests/ContainsOnlyIterableTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyNull()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlynull "Permalink to this heading") `assertContainsOnlyNull(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `null`. `assertContainsNotOnlyNull()` is the inverse of this assertion and takes the same arguments. Example 1.29 Usage of assertContainsOnlyNull()[](https://docs.phpunit.de/en/12.4/assertions.html#id29 "Permalink to this code") assertContainsOnlyNull(\['string'\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyNullTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyNullTest::testFailure Failed asserting that Array &0 \[\ 0 => 'string',\ \] contains only values of type "null". /path/to/tests/ContainsOnlyNullTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyNumeric()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlynumeric "Permalink to this heading") `assertContainsOnlyNumeric(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `numeric`. `assertContainsNotOnlyNumeric()` is the inverse of this assertion and takes the same arguments. Example 1.30 Usage of assertContainsOnlyNumeric()[](https://docs.phpunit.de/en/12.4/assertions.html#id30 "Permalink to this code") assertContainsOnlyNumeric(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyNumericTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyNumericTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "numeric". /path/to/tests/ContainsOnlyNumericTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyObject()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyobject "Permalink to this heading") `assertContainsOnlyObject(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `object`. `assertContainsNotOnlyObject()` is the inverse of this assertion and takes the same arguments. Example 1.31 Usage of assertContainsOnlyObject()[](https://docs.phpunit.de/en/12.4/assertions.html#id31 "Permalink to this code") assertContainsOnlyObject(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyObjectTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyObjectTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "object". /path/to/tests/ContainsOnlyObjectTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyResource()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyresource "Permalink to this heading") `assertContainsOnlyResource(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `resource`. `assertContainsNotOnlyResource()` is the inverse of this assertion and takes the same arguments. Example 1.32 Usage of assertContainsOnlyResource()[](https://docs.phpunit.de/en/12.4/assertions.html#id32 "Permalink to this code") assertContainsOnlyResource(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyResourceTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyResourceTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "resource". /path/to/tests/ContainsOnlyResourceTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyClosedResource()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyclosedresource "Permalink to this heading") `assertContainsOnlyClosedResource(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `resource (closed)`. `assertContainsNotOnlyClosedResource()` is the inverse of this assertion and takes the same arguments. Example 1.33 Usage of assertContainsOnlyClosedResource()[](https://docs.phpunit.de/en/12.4/assertions.html#id33 "Permalink to this code") assertContainsOnlyClosedResource(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyClosedResourceTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyClosedResourceTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "resource (closed)". /path/to/tests/ContainsOnlyClosedResourceTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyScalar()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyscalar "Permalink to this heading") `assertContainsOnlyScalar(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `scalar`. `assertContainsNotOnlyScalar()` is the inverse of this assertion and takes the same arguments. Example 1.34 Usage of assertContainsOnlyScalar()[](https://docs.phpunit.de/en/12.4/assertions.html#id34 "Permalink to this code") assertContainsOnlyScalar(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyScalarTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyScalarTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "scalar". /path/to/tests/ContainsOnlyScalarTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyString()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlystring "Permalink to this heading") `assertContainsOnlyString(iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only values of type `string`. `assertContainsNotOnlyString()` is the inverse of this assertion and takes the same arguments. Example 1.35 Usage of assertContainsOnlyString()[](https://docs.phpunit.de/en/12.4/assertions.html#id35 "Permalink to this code") assertContainsOnlyString(\[null\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyStringTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyStringTest::testFailure Failed asserting that Array &0 \[\ 0 => null,\ \] contains only values of type "string". /path/to/tests/ContainsOnlyStringTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertContainsOnlyInstancesOf()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcontainsonlyinstancesof "Permalink to this heading") `assertContainsOnlyInstancesOf(string $type, iterable $haystack[, string $message])` Reports an error identified by `$message` if `$haystack` does not contain only instances of class or interface `$type`. `assertContainsNotOnlyInstancesOf()` is the inverse of this assertion and takes the same arguments. Example 1.36 Usage of assertContainsOnlyInstancesOf()[](https://docs.phpunit.de/en/12.4/assertions.html#id36 "Permalink to this code") assertContainsOnlyInstancesOf( Foo::class, \[new Foo, new Bar, new Foo\], ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ContainsOnlyInstancesOfTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ContainsOnlyInstancesOfTest::testFailure Failed asserting that Array &0 \[\ 0 => Foo Object #464 (),\ 1 => Bar Object #383 (),\ 2 => Foo Object #370 (),\ \] contains only values of type "Foo". /path/to/tests/ContainsOnlyInstancesOfTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Objects[](https://docs.phpunit.de/en/12.4/assertions.html#objects "Permalink to this heading") ------------------------------------------------------------------------------------------------ ### `assertObjectHasProperty()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertobjecthasproperty "Permalink to this heading") `assertObjectHasProperty(string $propertyName, object $object, string $message = '')` Reports an error identified by `$message` if `$object` does not have a property with the name `$propertyName`. `assertObjectNotHasProperty()` is the inverse of this assertion and takes the same arguments. Example 1.37 Usage of assertObjectHasProperty()[](https://docs.phpunit.de/en/12.4/assertions.html#id37 "Permalink to this code") assertObjectHasProperty('propertyName', new stdClass); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/ObjectHasPropertyTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) ObjectHasPropertyTest::testFailure Failed asserting that object of class "stdClass" has property "propertyName". /path/to/tests/ObjectHasPropertyTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Cardinality[](https://docs.phpunit.de/en/12.4/assertions.html#cardinality "Permalink to this heading") -------------------------------------------------------------------------------------------------------- ### `assertCount()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertcount "Permalink to this heading") `assertCount(int $expectedCount, Countable|iterable $haystack[, string $message])` Reports an error identified by `$message` if the number of elements in `$haystack` is not `$expectedCount`. `assertNotCount()` is the inverse of this assertion and takes the same arguments. Example 1.38 Usage of assertCount()[](https://docs.phpunit.de/en/12.4/assertions.html#id38 "Permalink to this code") assertCount(0, \['foo'\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/CountTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) CountTest::testFailure Failed asserting that actual size 1 matches expected size 0. /path/to/tests/CountTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Note Please note that `assertCount()` and `assertNotCount()` do not support generators. Generators can only be iterated over once and they cannot be cloned. Passing a generator to `assertCount()` or `assertNotCount()` would therefore change the state of something that is supposed to be only verified. ### `assertSameSize()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertsamesize "Permalink to this heading") `assertSameSize(Countable|iterable $expected, Countable|iterable $actual[, string $message])` Reports an error identified by `$message` if the sizes of `$actual` and `$expected` are not the same. `assertNotSameSize()` is the inverse of this assertion and takes the same arguments. Example 1.39 Usage of assertSameSize()[](https://docs.phpunit.de/en/12.4/assertions.html#id39 "Permalink to this code") assertSameSize(\[1, 2\], \[1\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/SameSizeTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) SameSizeTest::testFailure Failed asserting that actual size 1 matches expected size 2. /path/to/tests/SameSizeTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Note Please note that `assertSameSize()` and `assertNotSameSize()` do not support generators. Generators can only be iterated over once and they cannot be cloned. Passing a generator to `assertSameSize()` or `assertNotSameSize()` would therefore change the state of something that is supposed to be only verified. ### `assertEmpty()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertempty "Permalink to this heading") `assertEmpty(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not empty. `assertNotEmpty()` is the inverse of this assertion and takes the same arguments. Example 1.40 Usage of assertEmpty()[](https://docs.phpunit.de/en/12.4/assertions.html#id40 "Permalink to this code") assertEmpty(\['foo'\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/EmptyTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) EmptyTest::testFailure Failed asserting that an array is empty. /path/to/tests/EmptyTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Note Please note that `assertEmpty()` and `assertNotEmpty()` do not support generators. Generators can only be iterated over once and they cannot be cloned. Passing a generator to `assertEmpty()` or `assertNotEmpty()` would therefore change the state of something that is supposed to be only verified. ### `assertGreaterThan()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertgreaterthan "Permalink to this heading") `assertGreaterThan(mixed $expected, mixed $actual[, string $message])` Reports an error identified by `$message` if the value of `$actual` is not greater than the value of `$expected`. Example 1.41 Usage of assertGreaterThan()[](https://docs.phpunit.de/en/12.4/assertions.html#id41 "Permalink to this code") assertGreaterThan(2, 1); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/GreaterThanTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) GreaterThanTest::testFailure Failed asserting that 1 is greater than 2. /path/to/tests/GreaterThanTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertGreaterThanOrEqual()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertgreaterthanorequal "Permalink to this heading") `assertGreaterThanOrEqual(mixed $expected, mixed $actual[, string $message])` Reports an error identified by `$message` if the value of `$actual` is not greater than or equal to the value of `$expected`. Example 1.42 Usage of assertGreaterThanOrEqual()[](https://docs.phpunit.de/en/12.4/assertions.html#id42 "Permalink to this code") assertGreaterThanOrEqual(2, 1); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/GreaterThanOrEqualTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) GreaterThanOrEqualTest::testFailure Failed asserting that 1 is equal to 2 or is greater than 2. /path/to/tests/GreaterThanOrEqualTest.php:8 FAILURES! Tests: 1, Assertions: 2, Failures: 1. ### `assertLessThan()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertlessthan "Permalink to this heading") `assertLessThan(mixed $expected, mixed $actual[, string $message])` Reports an error identified by `$message` if the value of `$actual` is not less than the value of `$expected`. Example 1.43 Usage of assertLessThan()[](https://docs.phpunit.de/en/12.4/assertions.html#id43 "Permalink to this code") assertLessThan(1, 2); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/LessThanTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) LessThanTest::testFailure Failed asserting that 2 is less than 1. /path/to/tests/LessThanTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertLessThanOrEqual()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertlessthanorequal "Permalink to this heading") `assertLessThanOrEqual(mixed $expected, mixed $actual[, string $message])` Reports an error identified by `$message` if the value of `$actual` is not less than or equal to the value of `$expected`. Example 1.44 Usage of assertLessThanOrEqual()[](https://docs.phpunit.de/en/12.4/assertions.html#id44 "Permalink to this code") assertLessThanOrEqual(1, 2); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/LessThanOrEqualTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) LessThanOrEqualTest::testFailure Failed asserting that 2 is equal to 1 or is less than 1. /path/to/tests/LessThanOrEqualTest.php:8 FAILURES! Tests: 1, Assertions: 2, Failures: 1. Types[](https://docs.phpunit.de/en/12.4/assertions.html#types "Permalink to this heading") -------------------------------------------------------------------------------------------- ### `assertInstanceOf()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertinstanceof "Permalink to this heading") `assertInstanceOf(string $expected, mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not an instance of `$expected`. `assertNotInstanceOf()` is the inverse of this assertion and takes the same arguments. Example 1.45 Usage of assertInstanceOf()[](https://docs.phpunit.de/en/12.4/assertions.html#id45 "Permalink to this code") assertInstanceOf(RuntimeException::class, new Exception); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/InstanceOfTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) InstanceOfTest::testFailure Failed asserting that an instance of class Exception is an instance of class RuntimeException. /path/to/tests/InstanceOfTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsArray()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisarray "Permalink to this heading") `assertIsArray(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `array`. `assertIsNotArray()` is the inverse of this assertion and takes the same arguments. Example 1.46 Usage of assertIsArray()[](https://docs.phpunit.de/en/12.4/assertions.html#id46 "Permalink to this code") assertIsArray(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsArrayTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsArrayTest::testFailure Failed asserting that null is of type array. /path/to/tests/IsArrayTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsList()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertislist "Permalink to this heading") `assertIsList(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not an array where the keys are consecutive numbers from 0 to `count($actual) - 1`. Example 1.47 Usage of assertIsList()[](https://docs.phpunit.de/en/12.4/assertions.html#id47 "Permalink to this code") assertIsList(\[1 \=> 'foo', '3' \=> 'bar'\]); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsListTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsListTest::testFailure Failed asserting that an array is a list. /path/to/tests/IsListTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsBool()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisbool "Permalink to this heading") `assertIsBool(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `bool`. `assertIsNotBool()` is the inverse of this assertion and takes the same arguments. Example 1.48 Usage of assertIsBool()[](https://docs.phpunit.de/en/12.4/assertions.html#id48 "Permalink to this code") assertIsBool(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsBoolTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsBoolTest::testFailure Failed asserting that null is of type bool. /path/to/tests/IsBoolTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsCallable()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertiscallable "Permalink to this heading") `assertIsCallable(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `callable`. `assertIsNotCallable()` is the inverse of this assertion and takes the same arguments. Example 1.49 Usage of assertIsCallable()[](https://docs.phpunit.de/en/12.4/assertions.html#id49 "Permalink to this code") assertIsCallable(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsCallableTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsCallableTest::testFailure Failed asserting that null is of type callable. /path/to/tests/IsCallableTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsFloat()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisfloat "Permalink to this heading") `assertIsFloat(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `float`. `assertIsNotFloat()` is the inverse of this assertion and takes the same arguments. Example 1.50 Usage of assertIsFloat()[](https://docs.phpunit.de/en/12.4/assertions.html#id50 "Permalink to this code") assertIsFloat(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsFloatTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsFloatTest::testFailure Failed asserting that null is of type float. /path/to/tests/IsFloatTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsInt()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisint "Permalink to this heading") `assertIsInt(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `int`. `assertIsNotInt()` is the inverse of this assertion and takes the same arguments. Example 1.51 Usage of assertIsInt()[](https://docs.phpunit.de/en/12.4/assertions.html#id51 "Permalink to this code") assertIsInt(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsIntTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsIntTest::testFailure Failed asserting that null is of type int. /path/to/tests/IsIntTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsIterable()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisiterable "Permalink to this heading") `assertIsIterable(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `iterable`. `assertIsNotIterable()` is the inverse of this assertion and takes the same arguments. Example 1.52 Usage of assertIsIterable()[](https://docs.phpunit.de/en/12.4/assertions.html#id52 "Permalink to this code") assertIsIterable(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsIterableTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsIterableTest::testFailure Failed asserting that null is of type iterable. /path/to/tests/IsIterableTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsNumeric()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisnumeric "Permalink to this heading") `assertIsNumeric(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `numeric`. `assertIsNotNumeric()` is the inverse of this assertion and takes the same arguments. Example 1.53 Usage of assertIsNumeric()[](https://docs.phpunit.de/en/12.4/assertions.html#id53 "Permalink to this code") assertIsNumeric(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsNumericTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsNumericTest::testFailure Failed asserting that null is of type numeric. /path/to/tests/IsNumericTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsObject()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisobject "Permalink to this heading") `assertIsObject(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `object`. `assertIsNotObject()` is the inverse of this assertion and takes the same arguments. Example 1.54 Usage of assertIsObject()[](https://docs.phpunit.de/en/12.4/assertions.html#id54 "Permalink to this code") assertIsObject(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsObjectTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsObjectTest::testFailure Failed asserting that null is of type object. /path/to/tests/IsObjectTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsResource()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisresource "Permalink to this heading") `assertIsResource(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `resource`. `assertIsNotResource()` is the inverse of this assertion and takes the same arguments. `assertIsClosedResource()` (and `assertIsNotClosedResource()`) are provided to explicitly check for closed resources. Example 1.55 Usage of assertIsResource()[](https://docs.phpunit.de/en/12.4/assertions.html#id55 "Permalink to this code") assertIsResource(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsResourceTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsResourceTest::testFailure Failed asserting that null is of type resource. /path/to/tests/IsResourceTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsScalar()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisscalar "Permalink to this heading") `assertIsScalar(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `scalar`. `assertIsNotScalar()` is the inverse of this assertion and takes the same arguments. Example 1.56 Usage of assertIsScalar()[](https://docs.phpunit.de/en/12.4/assertions.html#id56 "Permalink to this code") assertIsScalar(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsScalarTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsScalarTest::testFailure Failed asserting that null is of type scalar. /path/to/tests/IsScalarTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsString()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisstring "Permalink to this heading") `assertIsString(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not of type `string`. `assertIsNotString()` is the inverse of this assertion and takes the same arguments. Example 1.57 Usage of assertIsString()[](https://docs.phpunit.de/en/12.4/assertions.html#id57 "Permalink to this code") assertIsString(null); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsStringTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) IsStringTest::testFailure Failed asserting that null is of type string. /path/to/tests/IsStringTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertNull()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertnull "Permalink to this heading") `assertNull(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not `null`. `assertNotNull()` is the inverse of this assertion and takes the same arguments. Example 1.58 Usage of assertNull()[](https://docs.phpunit.de/en/12.4/assertions.html#id58 "Permalink to this code") assertNull('foo'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/NullTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) NullTest::testFailure Failed asserting that 'foo' is null. /path/to/tests/NullTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Strings[](https://docs.phpunit.de/en/12.4/assertions.html#strings "Permalink to this heading") ------------------------------------------------------------------------------------------------ ### `assertStringStartsWith()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertstringstartswith "Permalink to this heading") `assertStringStartsWith(string $prefix, string $string[, string $message])` Reports an error identified by `$message` if the `$string` does not start with `$prefix`. `assertStringStartsNotWith()` is the inverse of this assertion and takes the same arguments. Example 1.59 Usage of assertStringStartsWith()[](https://docs.phpunit.de/en/12.4/assertions.html#id59 "Permalink to this code") assertStringStartsWith('prefix', 'foo'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/StringStartsWithTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) StringStartsWithTest::testFailure Failed asserting that 'foo' starts with "prefix". /path/to/tests/StringStartsWithTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertStringEndsWith()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertstringendswith "Permalink to this heading") `assertStringEndsWith(string $suffix, string $string[, string $message])` Reports an error identified by `$message` if the `$string` does not end with `$suffix`. `assertStringEndsNotWith()` is the inverse of this assertion and takes the same arguments. Example 1.60 Usage of assertStringEndsWith()[](https://docs.phpunit.de/en/12.4/assertions.html#id60 "Permalink to this code") assertStringEndsWith('suffix', 'foo'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/StringEndsWithTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) StringEndsWithTest::testFailure Failed asserting that 'foo' ends with "suffix". /path/to/tests/StringEndsWithTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertStringContainsString()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertstringcontainsstring "Permalink to this heading") `assertStringContainsString(string $needle, string $haystack[, string $message])` Reports an error identified by `$message` if `$needle` is not a substring of `$haystack`. `assertStringNotContainsString()` is the inverse of this assertion and takes the same arguments. `assertStringContainsStringIgnoringLineEndings()` takes the same arguments and can be used if line endings should be ignored. Example 1.61 Usage of assertStringContainsString()[](https://docs.phpunit.de/en/12.4/assertions.html#id61 "Permalink to this code") assertStringContainsString('foo', 'bar'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/StringContainsStringTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00.002, Memory: 15.81 MB There was 1 failure: 1) StringContainsStringTest::testFailure Failed asserting that 'bar' \[ASCII\](length: 3) contains "foo" \[ASCII\](length: 3). /path/to/tests/StringContainsStringTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertStringContainsStringIgnoringCase()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertstringcontainsstringignoringcase "Permalink to this heading") `assertStringContainsStringIgnoringCase(string $needle, string $haystack[, string $message])` Reports an error identified by `$message` if `$needle` is not a substring of `$haystack`. Differences in casing are ignored when `$needle` is searched for in `$haystack`. This also works for Unicode characters with diacritics (accents, umlauts, circumflex, etc.) as long as both strings have the same [Normalization Form](https://www.php.net/manual/en/class.normalizer.php) . `assertStringNotContainsStringIgnoringCase()` is the inverse of this assertion and takes the same arguments. Example 1.62 Usage of assertStringContainsStringIgnoringCase()[](https://docs.phpunit.de/en/12.4/assertions.html#id62 "Permalink to this code") assertStringContainsStringIgnoringCase('foo', 'bar'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/StringContainsStringIgnoringCaseTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) StringContainsStringIgnoringCaseTest::testFailure Failed asserting that 'bar' \[Encoding ignored\](length: 3) contains "foo" \[Encoding ignored\](length: 3). /path/to/tests/StringContainsStringIgnoringCaseTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertStringEqualsStringIgnoringLineEndings()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertstringequalsstringignoringlineendings "Permalink to this heading") `assertStringEqualsStringIgnoringLineEndings(string $expected, string $actual[, string $message])` Reports an error identified by `$message` if the two strings `$expected` and `$actual` are not equal while ignoring line endings. ### `assertMatchesRegularExpression()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertmatchesregularexpression "Permalink to this heading") `assertMatchesRegularExpression(string $pattern, string $string[, string $message])` Reports an error identified by `$message` if `$string` does not match the regular expression `$pattern`. `assertDoesNotMatchRegularExpression()` is the inverse of this assertion and takes the same arguments. Example 1.63 Usage of assertMatchesRegularExpression()[](https://docs.phpunit.de/en/12.4/assertions.html#id63 "Permalink to this code") assertMatchesRegularExpression('/foo/', 'bar'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/MatchesRegularExpressionTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) MatchesRegularExpressionTest::testFailure Failed asserting that 'bar' matches PCRE pattern "/foo/". /path/to/tests/MatchesRegularExpressionTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertStringMatchesFormat()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertstringmatchesformat "Permalink to this heading") `assertStringMatchesFormat(string $format, string $string[, string $message])` Reports an error identified by `$message` if the `$string` does not match the `$format` string. Example 1.64 Usage of assertStringMatchesFormat()[](https://docs.phpunit.de/en/12.4/assertions.html#id64 "Permalink to this code") assertStringMatchesFormat('%i', 'foo'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/StringMatchesFormatTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) StringMatchesFormatTest::testFailure Failed asserting that string matches format description. --- Expected +++ Actual @@ @@ -%i +foo /path/to/tests/StringMatchesFormatTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. The format string may contain the following placeholders: * `%e`: Represents a directory separator, for example `/` on Linux. * `%s`: One or more of anything (character or white space) except the end of line character. * `%S`: Zero or more of anything (character or white space) except the end of line character. * `%a`: One or more of anything (character or white space) including the end of line character. * `%A`: Zero or more of anything (character or white space) including the end of line character. * `%w`: Zero or more white space characters. * `%i`: A signed integer value, for example `+3142`, `-3142`. * `%d`: An unsigned integer value, for example `123456`. * `%x`: One or more hexadecimal character. That is, characters in the range `0-9`, `a-f`, `A-F`. * `%f`: A floating point number, for example: `3.142`, `-3.142`, `3.142E-10`, `3.142e+10`. * `%c`: A single character of any sort. * `%%`: A literal percent character: `%`. ### `assertStringMatchesFormatFile()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertstringmatchesformatfile "Permalink to this heading") `assertStringMatchesFormatFile(string $formatFile, string $string[, string $message])` Reports an error identified by `$message` if the `$string` does not match the contents of the `$formatFile`. Example 1.65 Usage of assertStringMatchesFormatFile()[](https://docs.phpunit.de/en/12.4/assertions.html#id65 "Permalink to this code") assertStringMatchesFormatFile( \_\_DIR\_\_ . '/expected-format.txt', 'foo', ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/StringMatchesFormatFileTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) StringMatchesFormatFileTest::testFailure Failed asserting that string matches format description. --- Expected +++ Actual @@ @@ -%i +foo /path/to/tests/StringMatchesFormatFileTest.php:8 FAILURES! Tests: 1, Assertions: 3, Failures: 1. ### `assertFileMatchesFormat()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertfilematchesformat "Permalink to this heading") `assertFileMatchesFormat(string $format, string $actualFile[, string $message])` Reports an error identified by `$message` if the contents of `$actualFile` does not match the `$format` string. ### `assertFileMatchesFormatFile()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertfilematchesformatfile "Permalink to this heading") `assertFileMatchesFormat(string $formatFile, string $actualFile[, string $message])` Reports an error identified by `$message` if the contents of `$actualFile` does not match the contents of the `$formatFile`. ### `assertStringEqualsFile()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertstringequalsfile "Permalink to this heading") `assertStringEqualsFile(string $expectedFile, string $actualString[, string $message])` Reports an error identified by `$message` if the file specified by `$expectedFile` does not have `$actualString` as its contents. `assertStringNotEqualsFile()` is the inverse of this assertion and takes the same arguments. `assertStringEqualsFileCanonicalizing()` (and `assertStringNotEqualsFileCanonicalizing()`) as well as `assertStringEqualsFileIgnoringCase()` (and `assertStringNotEqualsFileIgnoringCase()`) do for files what `assertEqualsCanonicalizing()` (and `assertNotEqualsCanonicalizing()`) as well as `assertEqualsIgnoringCase()` (and `assertNotEqualsIgnoringCase()`) do for strings. Example 1.66 Usage of assertStringEqualsFile()[](https://docs.phpunit.de/en/12.4/assertions.html#id66 "Permalink to this code") assertStringEqualsFile( \_\_DIR\_\_ . '/expected.txt', 'actual', ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/StringEqualsFileTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) StringEqualsFileTest::testFailure Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'expected\\n -' +'actual' /path/to/tests/StringEqualsFileTest.php:8 FAILURES! Tests: 1, Assertions: 2, Failures: 1. JSON[](https://docs.phpunit.de/en/12.4/assertions.html#json "Permalink to this heading") ------------------------------------------------------------------------------------------ ### `assertJson()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertjson "Permalink to this heading") `assertJson(string $actual[, string $message])` Reports an error identified by `$message` if the value of `$actual` is not valid JSON. Example 1.67 Usage of assertJson()[](https://docs.phpunit.de/en/12.4/assertions.html#id67 "Permalink to this code") assertJson('not-a-json-string'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/JsonTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) JsonTest::testFailure Failed asserting that a string is valid JSON (Syntax error, malformed JSON). /path/to/tests/JsonTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertJsonFileEqualsJsonFile()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertjsonfileequalsjsonfile "Permalink to this heading") `assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile[, string $message])` Reports an error identified by `$message` if the value of `$actualFile` does not match the value of `$expectedFile`. `assertJsonFileNotEqualsJsonFile()` is the inverse of this assertion and takes the same arguments. Example 1.68 Usage of assertJsonFileEqualsJsonFile()[](https://docs.phpunit.de/en/12.4/assertions.html#id68 "Permalink to this code") assertJsonFileEqualsJsonFile( \_\_DIR\_\_ . '/expected.json', \_\_DIR\_\_ . '/actual.json', ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/JsonFileEqualsJsonFileTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) JsonFileEqualsJsonFileTest::testFailure Failed asserting that '{"mascot":"elephant"}\\n ' matches JSON string "{"mascot":"elePHPant"} ". --- Expected +++ Actual @@ @@ { - "mascot": "elePHPant" + "mascot": "elephant" } /path/to/tests/JsonFileEqualsJsonFileTest.php:8 FAILURES! Tests: 1, Assertions: 7, Failures: 1. ### `assertJsonStringEqualsJsonFile()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertjsonstringequalsjsonfile "Permalink to this heading") `assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson[, string $message])` Reports an error identified by `$message` if the value of `$actualJson` does not match the value of `$expectedFile`. `assertJsonStringNotEqualsJsonFile()` is the inverse of this assertion and takes the same arguments. Example 1.69 Usage of assertJsonStringEqualsJsonFile()[](https://docs.phpunit.de/en/12.4/assertions.html#id69 "Permalink to this code") assertJsonStringEqualsJsonFile( \_\_DIR\_\_ . '/expected.json', json\_encode(\['mascot' \=> 'elephant'\]), ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/JsonStringEqualsJsonFileTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) JsonStringEqualsJsonFileTest::testFailure Failed asserting that '{"mascot":"elephant"}' matches JSON string "{"mascot":"elePHPant"} ". --- Expected +++ Actual @@ @@ { - "mascot": "elePHPant" + "mascot": "elephant" } /path/to/tests/JsonStringEqualsJsonFileTest.php:8 FAILURES! Tests: 1, Assertions: 5, Failures: 1. ### `assertJsonStringEqualsJsonString()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertjsonstringequalsjsonstring "Permalink to this heading") `assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson[, string $message])` Reports an error identified by `$message` if the value of `$actualJson` does not match the value of `$expectedJson`. `assertJsonStringNotEqualsJsonString()` is the inverse of this assertion and takes the same arguments. Example 1.70 Usage of assertJsonStringEqualsJsonString()[](https://docs.phpunit.de/en/12.4/assertions.html#id70 "Permalink to this code") assertJsonStringEqualsJsonString( json\_encode(\['mascot' \=> 'elePHPant'\]), json\_encode(\['mascot' \=> 'elephant'\]), ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/JsonStringEqualsJsonStringTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) JsonStringEqualsJsonStringTest::testFailure Failed asserting that '{"mascot":"elephant"}' matches JSON string "{"mascot":"elePHPant"}". --- Expected +++ Actual @@ @@ { - "mascot": "elePHPant" + "mascot": "elephant" } /path/to/tests/JsonStringEqualsJsonStringTest.php:8 FAILURES! Tests: 1, Assertions: 3, Failures: 1. XML[](https://docs.phpunit.de/en/12.4/assertions.html#xml "Permalink to this heading") ---------------------------------------------------------------------------------------- ### `assertXmlFileEqualsXmlFile()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertxmlfileequalsxmlfile "Permalink to this heading") `assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile[, string $message])` Reports an error identified by `$message` if the XML document in `$actualFile` is not equal to the XML document in `$expectedFile`. `assertXmlFileNotEqualsXmlFile()` is the inverse of this assertion and takes the same arguments. Example 1.71 Usage of assertXmlFileEqualsXmlFile()[](https://docs.phpunit.de/en/12.4/assertions.html#id71 "Permalink to this code") assertXmlFileEqualsXmlFile( \_\_DIR\_\_ . '/expected.xml', \_\_DIR\_\_ . '/actual.xml', ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/XmlFileEqualsXmlFileTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) XmlFileEqualsXmlFileTest::testFailure Failed asserting that two DOM documents are equal. --- Expected +++ Actual @@ @@ - + /path/to/tests/XmlFileEqualsXmlFileTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertXmlStringEqualsXmlFile()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertxmlstringequalsxmlfile "Permalink to this heading") `assertXmlStringEqualsXmlFile(string $expectedFile, string $actualXml[, string $message])` Reports an error identified by `$message` if the XML document in `$actualXml` is not equal to the XML document in `$expectedFile`. `assertXmlStringNotEqualsXmlFile()` is the inverse of this assertion and takes the same arguments. Example 1.72 Usage of assertXmlStringEqualsXmlFile()[](https://docs.phpunit.de/en/12.4/assertions.html#id72 "Permalink to this code") assertXmlStringEqualsXmlFile( \_\_DIR\_\_ . '/expected.xml', '', ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/XmlStringEqualsXmlFileTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) XmlStringEqualsXmlFileTest::testFailure Failed asserting that two DOM documents are equal. --- Expected +++ Actual @@ @@ - + /path/to/tests/XmlStringEqualsXmlFileTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertXmlStringEqualsXmlString()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertxmlstringequalsxmlstring "Permalink to this heading") `assertXmlStringEqualsXmlString(string $expectedXml, string $actualXml[, string $message])` Reports an error identified by `$message` if the XML document in `$actualXml` is not equal to the XML document in `$expectedXml`. `assertXmlStringNotEqualsXmlString()` is the inverse of this assertion and takes the same arguments. Example 1.73 Usage of assertXmlStringEqualsXmlString()[](https://docs.phpunit.de/en/12.4/assertions.html#id73 "Permalink to this code") assertXmlStringEqualsXmlString( '', '', ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/XmlStringEqualsXmlStringTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) XmlStringEqualsXmlStringTest::testFailure Failed asserting that two DOM documents are equal. --- Expected +++ Actual @@ @@ - + /path/to/tests/XmlStringEqualsXmlStringTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Filesystem[](https://docs.phpunit.de/en/12.4/assertions.html#filesystem "Permalink to this heading") ------------------------------------------------------------------------------------------------------ ### `assertDirectoryExists()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertdirectoryexists "Permalink to this heading") `assertDirectoryExists(string $directory[, string $message])` Reports an error identified by `$message` if the directory specified by `$directory` does not exist. `assertDirectoryDoesNotExist()` is the inverse of this assertion and takes the same arguments. Example 1.74 Usage of assertDirectoryExists()[](https://docs.phpunit.de/en/12.4/assertions.html#id74 "Permalink to this code") assertDirectoryExists('/path/to/directory'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/DirectoryExistsTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) DirectoryExistsTest::testFailure Failed asserting that directory "/path/to/directory" exists. /path/to/tests/DirectoryExistsTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertDirectoryIsReadable()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertdirectoryisreadable "Permalink to this heading") `assertDirectoryIsReadable(string $directory[, string $message])` Reports an error identified by `$message` if the directory specified by `$directory` is not a directory or is not readable. `assertDirectoryIsNotReadable()` is the inverse of this assertion and takes the same arguments. Example 1.75 Usage of assertDirectoryIsReadable()[](https://docs.phpunit.de/en/12.4/assertions.html#id75 "Permalink to this code") assertDirectoryIsReadable('/path/to/directory'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/DirectoryIsReadableTest.php PHPUnit 10.0.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.3 F Time: 00:00, Memory: 14.29 MB There was 1 failure: 1) DirectoryIsReadableTest::testFailure Failed asserting that "/path/to/directory" is readable. /path/to/DirectoryIsReadableTest.php:6 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertDirectoryIsWritable()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertdirectoryiswritable "Permalink to this heading") `assertDirectoryIsWritable(string $directory[, string $message])` Reports an error identified by `$message` if the directory specified by `$directory` is not a directory or is not writable. `assertDirectoryIsNotWritable()` is the inverse of this assertion and takes the same arguments. Example 1.76 Usage of assertDirectoryIsWritable()[](https://docs.phpunit.de/en/12.4/assertions.html#id76 "Permalink to this code") assertDirectoryIsReadable('/path/to/directory'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/DirectoryIsWritableTest.php PHPUnit 10.0.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.3 F Time: 00:00, Memory: 14.29 MB There was 1 failure: 1) DirectoryIsWritableTest::testFailure Failed asserting that "/path/to/directory" is writable. /path/to/DirectoryIsWritableTest.php:6 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertFileExists()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertfileexists "Permalink to this heading") `assertFileExists(string $filename[, string $message])` Reports an error identified by `$message` if the file specified by `$filename` does not exist. `assertFileDoesNotExist()` is the inverse of this assertion and takes the same arguments. Example 1.77 Usage of assertFileExists()[](https://docs.phpunit.de/en/12.4/assertions.html#id77 "Permalink to this code") assertFileExists('/path/to/file'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/FileExistsTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) FileExistsTest::testFailure Failed asserting that file "/path/to/file" exists. /path/to/tests/FileExistsTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertFileIsReadable()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertfileisreadable "Permalink to this heading") `assertFileIsReadable(string $filename[, string $message])` Reports an error identified by `$message` if the file specified by `$filename` is not a file or is not readable. `assertFileIsNotReadable()` is the inverse of this assertion and takes the same arguments. Example 1.78 Usage of assertFileIsReadable()[](https://docs.phpunit.de/en/12.4/assertions.html#id78 "Permalink to this code") assertFileIsReadable('/path/to/file'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/FileIsReadableTest.php PHPUnit 10.0.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.3 F Time: 00:00, Memory: 14.29 MB There was 1 failure: 1) FileIsReadableTest::testFailure Failed asserting that "/path/to/file" is readable. /path/to/FileIsReadableTest.php:6 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertFileIsWritable()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertfileiswritable "Permalink to this heading") `assertFileIsWritable(string $filename[, string $message])` Reports an error identified by `$message` if the file specified by `$filename` is not a file or is not writable. `assertFileIsNotWritable()` is the inverse of this assertion and takes the same arguments. Example 1.79 Usage of assertFileIsWritable()[](https://docs.phpunit.de/en/12.4/assertions.html#id79 "Permalink to this code") assertFileIsWritable('/path/to/file'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/FileIsWritableTest.php PHPUnit 10.0.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.3 F Time: 00:00, Memory: 14.29 MB There was 1 failure: 1) FileIsWritableTest::testFailure Failed asserting that "/path/to/file" is writable. /path/to/FileIsWritableTest.php:6 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsReadable()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertisreadable "Permalink to this heading") `assertIsReadable(string $filename[, string $message])` Reports an error identified by `$message` if the file or directory specified by `$filename` is not readable. `assertIsNotReadable()` is the inverse of this assertion and takes the same arguments. Example 1.80 Usage of assertIsReadable()[](https://docs.phpunit.de/en/12.4/assertions.html#id80 "Permalink to this code") assertIsReadable('/path/to/unreadable'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsReadableTest.php PHPUnit 10.0.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.3 F Time: 00:00, Memory: 14.29 MB There was 1 failure: 1) IsReadableTest::testFailure Failed asserting that "/path/to/unreadable" is readable. /path/to/IsReadableTest.php:6 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertIsWritable()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertiswritable "Permalink to this heading") `assertIsWritable(string $filename[, string $message])` Reports an error identified by `$message` if the file or directory specified by `$filename` is not writable. `assertIsNotWritable()` is the inverse of this assertion and takes the same arguments. Example 1.81 Usage of assertIsWritable()[](https://docs.phpunit.de/en/12.4/assertions.html#id81 "Permalink to this code") assertIsWritable('/path/to/unwritable'); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/IsWritableTest.php PHPUnit 10.0.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.2.3 F Time: 00:00, Memory: 14.29 MB There was 1 failure: 1) IsWritableTest::testFailure Failed asserting that "/path/to/unwritable" is writable. /path/to/IsWritableTest.php:6 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Math[](https://docs.phpunit.de/en/12.4/assertions.html#math "Permalink to this heading") ------------------------------------------------------------------------------------------ ### `assertInfinite()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertinfinite "Permalink to this heading") `assertInfinite(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not `INF`. `assertFinite()` is the inverse of this assertion and takes the same arguments. Example 1.82 Usage of assertInfinite()[](https://docs.phpunit.de/en/12.4/assertions.html#id82 "Permalink to this code") assertInfinite(1); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/InfiniteTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) InfiniteTest::testFailure Failed asserting that 1 is infinite. /path/to/tests/InfiniteTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. ### `assertNan()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertnan "Permalink to this heading") `assertNan(mixed $actual[, string $message])` Reports an error identified by `$message` if `$actual` is not `NAN`. Example 1.83 Usage of assertNan()[](https://docs.phpunit.de/en/12.4/assertions.html#id83 "Permalink to this code") assertNan(1); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/NanTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) NanTest::testFailure Failed asserting that 1 is nan. /path/to/tests/NanTest.php:8 FAILURES! Tests: 1, Assertions: 1, Failures: 1. Constraints[](https://docs.phpunit.de/en/12.4/assertions.html#constraints "Permalink to this heading") -------------------------------------------------------------------------------------------------------- ### `assertThat()`[](https://docs.phpunit.de/en/12.4/assertions.html#assertthat "Permalink to this heading") `assertThat(mixed $value, PHPUnit\Framework\Constraint $constraint[, string $message])` Reports an error identified by `$message` if the `$value` does not match the `$constraint`. More complex assertions can be formulated using the `PHPUnit\Framework\Constraint` classes. They can be evaluated using the `assertThat()` method. This example shows how the `logicalNot()` and `equalTo()` constraints can be used, for instance, to express the same assertion as `assertNotEquals()`: Example 1.84 Usage of assertThat()[](https://docs.phpunit.de/en/12.4/assertions.html#id84 "Permalink to this code") assertThat( $theBiscuit, $this\->logicalNot( $this\->equalTo($myBiscuit), ), ); } } Running the test shown above yields the output shown below: ./tools/phpunit tests/BiscuitTest.php PHPUnit 12.3.11 by Sebastian Bergmann and contributors. Runtime: PHP 8.4.12 F 1 / 1 (100%) Time: 00:00, Memory: 15.81 MB There was 1 failure: 1) BiscuitTest::testEquals Failed asserting that Biscuit Object #464 ( 'name' => 'Ginger', ) is equal to Biscuit Object #383 ( 'name' => 'Ginger', ). /path/to/tests/BiscuitTest.php:11 FAILURES! Tests: 1, Assertions: 1, Failures: 1. [Table 1.1](https://docs.phpunit.de/en/12.4/assertions.html#appendixes-assertions-assertthat-tables-constraints) shows the available `PHPUnit\Framework\Constraint` classes. | | | | --- | --- |Table 1.1 Constraints[](https://docs.phpunit.de/en/12.4/assertions.html#appendixes-assertions-assertthat-tables-constraints "Permalink to this table") | Constraint | Meaning | | --- | --- | | `PHPUnit\Framework\Constraint\IsAnything anything()` | Constraint that accepts any input value. | | `PHPUnit\Framework\Constraint\ArrayHasKey arrayHasKey(mixed $key)` | Constraint that asserts that the array has a given key. | | `PHPUnit\Framework\Constraint\TraversableContains contains(mixed $value)` | Constraint that asserts that the `array` or object that implements the `Iterator` interface contains a given value. | | `PHPUnit\Framework\Constraint\TraversableContainsOnly containsOnly(string $type)` | Constraint that asserts that the `array` or object that implements the `Iterator` interface contains only values of a given type. | | `PHPUnit\Framework\Constraint\TraversableContainsOnly containsOnlyInstancesOf(string $classname)` | Constraint that asserts that the `array` or object that implements the `Iterator` interface contains only instances of a given classname. | | `PHPUnit\Framework\Constraint\IsEqual equalTo($value, $delta = 0, $maxDepth = 10)` | Constraint that checks if one value is equal to another. | | `PHPUnit\Framework\Constraint\DirectoryExists directoryExists()` | Constraint that checks if the directory exists. | | `PHPUnit\Framework\Constraint\FileExists fileExists()` | Constraint that checks if the file(name) exists. | | `PHPUnit\Framework\Constraint\IsReadable isReadable()` | Constraint that checks if the file(name) is readable. | | `PHPUnit\Framework\Constraint\IsWritable isWritable()` | Constraint that checks if the file(name) is writable. | | `PHPUnit\Framework\Constraint\GreaterThan greaterThan(mixed $value)` | Constraint that asserts that the value is greater than a given value. | | `PHPUnit\Framework\Constraint\LogicalOr greaterThanOrEqual(mixed $value)` | Constraint that asserts that the value is greater than or equal to a given value. | | `PHPUnit\Framework\Constraint\IsIdentical identicalTo(mixed $value)` | Constraint that asserts that one value is identical to another. | | `PHPUnit\Framework\Constraint\IsFalse isFalse()` | Constraint that asserts that the value is `false`. | | `PHPUnit\Framework\Constraint\IsInstanceOf isInstanceOf(string $className)` | Constraint that asserts that the object is an instance of a given class. | | `PHPUnit\Framework\Constraint\IsNull isNull()` | Constraint that asserts that the value is `null`. | | `PHPUnit\Framework\Constraint\IsTrue isTrue()` | Constraint that asserts that the value is `true`. | | `PHPUnit\Framework\Constraint\IsType isType(string $type)` | Constraint that asserts that the value is of a specified type. | | `PHPUnit\Framework\Constraint\LessThan lessThan(mixed $value)` | Constraint that asserts that the value is smaller than a given value. | | `PHPUnit\Framework\Constraint\LogicalOr lessThanOrEqual(mixed $value)` | Constraint that asserts that the value is smaller than or equal to a given value. | | `logicalAnd()` | Logical AND. | | `logicalNot(PHPUnit\Framework\Constraint $constraint)` | Logical NOT. | | `logicalOr()` | Logical OR. | | `logicalXor()` | Logical XOR. | | `PHPUnit\Framework\Constraint\PCREMatch matchesRegularExpression(string $pattern)` | Constraint that asserts that the string matches a regular expression. | | `PHPUnit\Framework\Constraint\StringContains stringContains(string $string, bool $case)` | Constraint that asserts that the string contains a given string. | | `PHPUnit\Framework\Constraint\StringEndsWith stringEndsWith(string $suffix)` | Constraint that asserts that the string ends with a given suffix. | | `PHPUnit\Framework\Constraint\StringStartsWith stringStartsWith(string $prefix)` | Constraint that asserts that the string starts with a given prefix. | ---