PHPUnit PHP testing framework

Version 11.0 · source

Start here

composer require --dev phpunit/phpunit
Install it
vendor/bin/phpunit
Run all tests
vendor/bin/phpunit <path>
Run a file or dir
vendor/bin/phpunit --filter <name>
Run matching tests
vendor/bin/phpunit --testdox
Readable results
vendor/bin/phpunit --stop-on-failure
Stop at first failure
vendor/bin/phpunit --generate-configuration
Create phpunit.xml
vendor/bin/phpunit --coverage-text
Coverage summary

Concepts

  1. phpunit.xml suites, source
  2. Test classes *Test.php
  3. Result dots, F, E, R
  4. Reports coverage, JUnit

Run and select

vendor/bin/phpunit
Run the configured tests
vendor/bin/phpunit <path>
Run one file or directory
vendor/bin/phpunit --filter <pattern>
Run tests whose name matches
Matches class, method and data set names; repeating --filter combines with AND.
--testsuite <name>
Run one suite from the config
--group <name>
Run tests in a group
--exclude-group <name>
Skip a group

Execution

--stop-on-failure
Stop at the first failure
--fail-on-warning
Exit non-zero on warnings
--order-by <order>
Reorder tests
Orders: default, defects, depends, duration, no-depends, random, reverse, size.

Output

--testdox
Show results as readable sentences
--display-deprecations
Show deprecation details
--display-warnings
Show warning details

Coverage

--coverage-text
Print a coverage table
--coverage-html <dir>
Write an HTML report
XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html <dir>
Coverage with Xdebug

Configuration

--generate-configuration
Interactively create phpunit.xml
-c <file>
Use another config file
Minimal phpunit.xml
<phpunit bootstrap="vendor/autoload.php" colors="true"         failOnWarning="true" failOnRisky="true"         cacheDirectory=".phpunit.cache">  <testsuites>    <testsuite name="unit"><directory>tests/unit</directory></testsuite>  </testsuites>  <source><include><directory suffix=".php">src</directory></include></source></phpunit>

Writing tests

A basic test
use PHPUnit\Framework\TestCase;final class CartTest extends TestCase{    protected function setUp(): void { $this->cart = new Cart; }    #[Test]    public function adds_items(): void    {        $this->cart->add('apple');        $this->assertCount(1, $this->cart);    }}
assertSame($expected, $actual)
Same type and value (===)
assertEquals($expected, $actual)
Loosely equal (==)
assertTrue($cond) / assertFalse($cond)
Boolean checks
assertNull($v) / assertNotNull($v)
Null checks
assertCount($n, $items)
Number of elements
assertInstanceOf(<Class>::class, $v)
Value is of a class
assertEqualsWithDelta($a, $b, $delta)
Floats within tolerance
$this->expectException(<Class>::class)
Expect a thrown exception
Call it before the code that throws.
setUp() / tearDown()
Run before and after each test
setUpBeforeClass() / tearDownAfterClass()
Run once per class (static)

Attributes

#[Test]
Mark a method as a test
#[DataProvider('<method>')]
Feed data sets from a static method
#[TestWith([<args>])]
Inline data set
#[Group('<name>')]
Put a test in a group
Data provider
#[DataProvider('sums')]public function test_sum(int $a, int $b, int $want): void{    $this->assertSame($want, $a + $b);}public static function sums(): array{    return ['zero' => [0, 0, 0], 'one' => [1, 0, 1]];}

Test doubles

$this->createStub(<Class>::class)
Canned-answer double, no expectations
$this->createMock(<Class>::class)
Double that can verify calls
$stub->method('<m>')->willReturn($v)
Fix a return value
->willReturnMap([[<args>, $ret]])
Return by argument
->willThrowException(new <Ex>)
Make the method throw
$mock->expects($this->once())->method('<m>')
Require exactly one call

Recipes

Focused loop on one test
vendor/bin/phpunit --filter test_adds_items --testdox# add --stop-on-failure and --display-deprecations when debugging
HTML coverage report
XDEBUG_MODE=coverage vendor/bin/phpunit \  --coverage-html build/coverage --coverage-textxdg-open build/coverage/index.html
CI run with strict flags
vendor/bin/phpunit --fail-on-warning --fail-on-risky \  --log-junit build/junit.xml --coverage-clover build/clover.xml