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 a 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(); // Create a Client object.
   $client->setUserAgent("My Browser Type");
   $client->setClientIP("192.168.100.1");
   $now = new \DateTime("now");
   $client->setTimeSubmit( $now );

   // Verify settings.
   $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.

PHPunit_code_coverage

As you can see above it shows you it ran 2 tests and 8 assertions and those tests passes (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 on 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(); // Create a Client object.
   $client->setUserAgent("My Browser Type");
   $client->setClientIP("192.168.100.1");
   $now = new \DateTime("now");
   $client->setTimeSubmit( $now );

   // Verify settings.
   $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()); // Test 7th Method.
}

Now if we run the phpunit test with code coverage, we get a different result:

PHPunit_code_coverage2

This is better. Now in the Summary area we have “1/30” Classes covered. In otherwords, 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!

Advertisements