Introduction
I’ve been creating some unit tests and functional tests for a Symfony application that I’m currently developing and I wanted to share some of those experiences. PHPUnit has number command line options that you can specify when running it, including a very useful “–coverage-text
” option which is what I show here.
Creating Test Code
It’s a good idea to create both unit and functional tests. Unit tests should be used to test any of your Symfony Entities, and Function tests would test the controller, the web pages as part of your application, and any forms that you may have.
Here is some sample code, that creates a Client
object and calls 6 of its methods (getters and setters) and performs assertions:
public function testCreateClient(){
$client = new Client();
$client->setUserAgent("My Browser Type");
$client->setClientIP("192.168.100.1");
$now = new \DateTime("now");
$client->setTimeSubmit( $now );
$this->assertEquals("My Browser Type", $client->getUserAgent());
$this->assertEquals("192.168.100.1", $client->getClientIP());
$this->assertEquals($now, $client->getTimeSubmit());
}
The above code essentially creates a Client
object and then sets various properties of the object and then later gets the properties of the object to perform assertions.
Running the PHPUnit Code Coverage
To run the code coverage on the individual file, I would call the command like so:
./vendor/bin/phpunit --coverage-text tests/AppBundle/Entity/ClientTest.php
The above command executes the “phpunit
” binary and then passes the “–coverage-text
” option and then specifies the path to the unit test case file (called ClientTest.php). Below is an example of what the screenshot looks like when run.
As you can see above, it shows you it ran 2 tests and 8 assertions and those tests passed (they are green to indicate passing). There is a timestamp showing when the report was run, and is followed by a summary.
If you take a look closely at the Summary section, this has important details regarding code coverage. For example, it shows Classes at 0.00% coverage. You may wonder why it is only 0.00% which doesn’t seem right.
According to PHPUnit’s documentation, class coverage is only complete when “all of its methods are covered”. Notice at the bottom of the screenshot, under the “\AppBundle\Entity::Client” area, it shows in yellow, that only 6/7 methods are covered.
The problem was that I was not testing all methods of the Client
class, and I needed to add the “getClientId()
” method. The client test code now looks like the following:
public function testCreateClient(){
$client = new Client();
$client->setUserAgent("My Browser Type");
$client->setClientIP("192.168.100.1");
$now = new \DateTime("now");
$client->setTimeSubmit( $now );
$this->assertEquals("My Browser Type", $client->getUserAgent());
$this->assertEquals("192.168.100.1", $client->getClientIP());
$this->assertEquals($now, $client->getTimeSubmit());
$this->assertLessThan(3, $client->getClientId());
}
Now if we run the phpunit test with code coverage, we get a different result:
This is better. Now in the Summary area, we have “1/30” Classes covered. In other words, we need to develop test cases for 29 other classes. If we look at the bottom for the methods of the Client Entity, all 7 methods have been tested (100% coverage).
NOTE: Event though this shows 100% coverage, this does not mean that all scenarios of testing the Class have been covered. For example, it’s also a good idea to perform negative tests.
Hopefully this helps someone out!