PHPUnit🔗
Create a test file in the tests
folder following the same path that your source file and add the suffix Test
.
For example:
- Source file:
src/Application/Command/FoobarCommandHandler
- Test file:
tests/Application/Command/FoobarCommandHandlerTest
Using Prophecy🔗
The class you want to test has dependencies:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
Your test:
1 2 3 4 5 6 7 8 |
|
-
Create an instance of the class you want to test
1 2
<?php $handler = new FoobarCommandHandler();
-
Look for dependencies and create mocks for each of them:
1 2 3 4 5
<?php $repository = $this->prophesize(FoobarRepositoryInterface::class); $checker = $this->prophesize(FoobarCheckerInterface::class); $handler = new FoobarCommandHandler($repository->reveal(), $checker->reveal());
-
Call the method you want to test and look for parameters you need to pass
1 2 3 4 5 6 7 8 9
<?php $repository = $this->prophesize(FoobarRepositoryInterface::class); $checker = $this->prophesize(FoobarCheckerInterface::class); $handler = new FoobarCommandHandler($repository->reveal(), $checker->reveal()); $command = new FoobarCommand('My title'); $handler->handle($command);
-
Look if the method you test returns something, if so, test the return value with
assertEquals
1 2 3 4 5 6 7 8 9 10 11
<?php $repository = $this->prophesize(FoobarRepositoryInterface::class); $checker = $this->prophesize(FoobarCheckerInterface::class); $handler = new FoobarCommandHandler($repository->reveal(), $checker->reveal()); $command = new FoobarCommand('My title'); $expected = new Foobar('MyTitle'); $this->assertEquals($expected, $handler->handle($command));
-
Look for methods call on your class dependencies and mock them. Check if they should be called or not, if they must return something, etc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// Mocks $repository = $this->prophesize(FoobarRepositoryInterface::class); $checker = $this->prophesize(FoobarCheckerInterface::class); // Tested class $handler = new FoobarCommandHandler($repository->reveal(), $checker->reveal()); // Input $command = new FoobarCommand('My title'); // Expected $expected = new Foobar('MyTitle'); // Asserts $checker->check($expected)->shouldBeCalled()->willReturn(true); $repository->add($expected)->shouldBeCalled(); $this->assertEquals($expected, $handler->handle($command));
-
Run the test
-
Test other scenarios
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// Mocks $repository = $this->prophesize(FoobarRepositoryInterface::class); $checker = $this->prophesize(FoobarCheckerInterface::class); // Tested class $handler = new FoobarCommandHandler($repository->reveal(), $checker->reveal()); // Input $command = new FoobarCommand('My title'); // Expected $expected = new Foobar('MyTitle'); // Asserts $checker->check($expected)->shouldBeCalled()->willReturn(false); $repository->add($expected)->shouldNotBeCalled(); $this->expectException(Exception::class); $this->assertEquals($expected, $handler->handle($command));
Not using Prophecy🔗
The class you want to test has no dependencies:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Your test:
1 2 3 4 5 6 7 8 |
|
-
Create the instance of your class
1 2
<?php $computer = new ScoreComputer();
-
Call the method you want to test and look for parameters you need to pass
1 2 3 4 5 6
<?php $computer = new ScoreComputer(); $foobar = new Foobar('foobar', 24); $computer->compute($foobar);
-
Look if the method you test returns something, if so, test the return value with
assertEquals
1 2 3 4 5 6
<?php $computer = new ScoreComputer(); $foobar = new Foobar('foobar', 24); $this->assertEquals(100, $computer->compute($foobar));
-
Run the test
Using data providers🔗
If the method you are testing has many use cases which depend on parameters or dependencies return values, you can use data provider to cover all use cases.
-
Put expected value and variables that can influence the result as parameters
1 2 3 4 5 6 7 8 9 10 11 12 13
<?php class ScoreComputerTest { public function testCompute($expected, $title, $value) { $computer = new ScoreComputer(); $foobar = new Foobar($title, $value); $this->assertEquals($expected, $computer->compute($foobar)); } }
-
Create a
dataProvider
static method to return data sets1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
<?php class ScoreComputerTest { public static function provideScores() { return [ // if title is foobar, the score will be 100 not matter the value [100, 'foobar', 30], // if title is not foobar, the score will be equal to 0.9 * the value [27, 'my title', 30], [90, 'my title', 100], [63, 'hello', 70], ]; } /** * @dataProvider provideScores */ public function testCompute($expected, $title, $value) { $computer = new ScoreComputer(); $foobar = new Foobar($title, $value); $this->assertEquals($expected, $computer->compute($foobar)); } }
Your test will be run 4 times with these different parameters and will cover all possibilities.
Run tests🔗
In elao projects🔗
To run your tests, use the command make test
in your container.
Other way🔗
It's also useful to run your tests with the PHPUnit command-line test runner through the bin/phpunit
command.
-
Run all tests
1
bin/phpunit
-
Run one specific test
Use this command to run tests for specific directory or class
or1
bin/phpunit tests/Application/Command
1
bin/phpunit tests/Application/Command/FoobarCommandHandlerTest.php
-
Run tests with additional options
Use the
--filter
option to run a specific test method1
bin/phpunit --filter 'tests\\Application\\Command\\FoobarCommandHandlerTest::testHandle'
To get more 'readable' results, use the
--testdox
option
Result:1
bin/phpunit tests/Application/Command/FoobarCommandHandlerTest.php --testdox
1 2 3 4 5 6 7 8 9
Testing App\Tests\Application\DownloadFoobarCommandHandlerTest Zip Archive Factory (App\Tests\Application\DownloadFoobarCommandHandler) ✔ Test 1 // (extract from class name) ✔ Test 2 ✔ Test 3 Time: 00:04.929, Memory: 34.00 MB OK (3 tests, 12 assertions)
Sources🔗
Check the official PHPUnit documentation right here