Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get 100% Code Coverage with PHPUnit

I am writing a Zend Framework application and unit testing it with PHPUnit. In general, things are going swimmingly however I have a small, but annoying issue with PHPUnit and code coverage - it sometimes tells me that a particular line is not tested, and I don't know how to force it to be tested.

In the following code, for example, I launch two tests: one with a GET request, one with a POST request. The tests pass, and that's all fine. When I look at the code coverage, however, it shows me that the 'else' line is not executed.

public function editAction()
{        
    if ($request->isPost()) {
        // do actions related to POST
    } else {
        // do action related to GET
    }
}

Any ideas? As a side issue, do you usually persevere with unit tests until you get 100% code coverage? Or is this not really practical?

Thanks muchly...

like image 772
DatsunBing Avatar asked Nov 28 '22 18:11

DatsunBing


1 Answers

I was the project lead on the Zend Framework a few years ago, through the release of ZF 1.0. I worked pretty hard on raising the coverage of testing for all components, and we had a policy that a component must have a certain minimum code coverage to be adopted into ZF from the incubator.

However, you're right, trying to get 100% code coverage from tests for all your classes isn't really practical. Some of the classes in ZF have 100% coverage, but for these, one or more of the following was true:

  • The class was trivially simple.
  • The tests took extraordinary work to write. E.g. complex setup code to create conditions to exercise all the obscure corner cases. Look at the unit tests for Zend_Db that I wrote! Though it's beneficial to force yourself to test these corner cases, because I guarantee that it'll lead you to code that you need to fix.
  • The class had to be refactored to be more "testable". This is often a good thing anyway, because you end up with better OO code, with less coupling, fewer static elements, etc. See the classes and tests for Zend_Log.

But we also realized that 100% code coverage is sometimes an artificial goal. A test suite that achieves less tan 100% coverage may nevertheless be adequate. And a test suite that does get to 100% coverage doesn't necessarily assure quality.

It would be very easy to get 100% code coverage for the following function. But did we test for division by zero?

function div($numerator, $denominator) {
    return $numerator / $denominator;
}

So you should use code coverage as one metric of testing, but not the ultimate goal.

like image 105
Bill Karwin Avatar answered Dec 05 '22 15:12

Bill Karwin