Tag Archives: php

Chasing 100% Coverage

Unit tests, as we all know, are A Good Thing™. It stands to reason then that 100% unit test coverage must also be A Good Thing™, and therefore is something that should be strived for at all costs. I’d argue this is wrong though.

100% unit1 test coverage can be exceptionally difficult to achieve in real world applications without jumping through a whole load of hoops that end up being counterproductive. The edges of your system often talk to other systems which can be difficult to isolate or mock out. You can often be left chasing that last few percent and making counterintuitive changes to achieve them. At this point I’d say it’s better to leave the clean, readable, untested code in and just accept 100% coverage isn’t always possible.

This leads to another problem though. Once you’re not hitting 100% coverage you need to be sure that code that isn’t covered is actually code you can’t cover. As your code base gets bigger the amount a single missed line of code affects your coverage gets smaller.

PHPUnit takes a pragmatic approach to this issue; it allows you to mark blocks of code as being untestable. The net result is that it simply ignores these blocks of code in its coverage calculations allowing you to get 100% coverage of testable code.

Quite a few people who I’ve told about this have declared this to be ‘cheating’, however, lets look at a very real issue I have in one of my bits of Java code. I have code that uses the list of locales that can be retrieved by Java. It uses the US as default since it’s reasonable to assume that the US locale will be set up on a system. While highly improbably, it’s not impossible for a system to lack the US locale and the code handles this gracefully. Unit testing this code path is impossible as it involves changes to the environment. I could conceivably handle this in functional tests, but it’s not easy. I could remove the check and just let the code fall over in a crumpled heap in this case, but then if it ever does happen someone is going to have a nasty stack trace to deal with rather than a clear and concise error message.

If I could mark that single block of code as untestable I would then be able to see if the rest of my code was 100% covered at a glance. As it is I’ve got 99 point something coverage and I need to drill into the coverage results to ensure the missing coverage comes from that one class. Royal pain in the behind.

I am willing to concede that the ability to mark code as untestable can be abused, but then that’s what code reviews are for. If someone knows how to unit test a block of code that’s marked as untestable they can fail the review and give advice to the developer that submitted the code.

1 People seem to get unit and functional tests muddled up. A unit test should be able to run in isolation with no dependency on environment or other systems. Functional tests, on the other hand, can make assumptions about the environment and can require that other systems are running and correctly configured. The classic example is a database. Unit tests should mock out the database connection and used canned data within the unit tests. Functional tests can connect to a real database pre-populated with test data. Typically functional tests also test much larger blocks of code than individual unit tests do.

Is PHP an enterprise language?

During the last nor(DEV): we tried something a little different: a Question Time style panel where the ‘audience’ asked a panel of guests a series of contentious questions. These were then debated by both the panel and the audience. While the questions may have been pre-prepared the debate that followed was not, which resulted in some interesting discussion.

One of the questions that interested me the most was regarding PHP and its status as an ‘Enterprise’ level language. With my recent experience with PHP I’ve found my attitudes to it have changed drastically. This has resulted in, for me, a startling conclusion.

Historically I’ve been a Java developer. While we know Java is an enterprise language (it says so on the tin), I didn’t start out that way. While I’ve dabbled in Ada (university) and C++ (early graphics programming for fun) my first commercial programming was done in Perl and TCL. I may have been at a large enterprise, but, by my own definition, I come from a Script Kiddie background. Perhaps I’m a little more open to scripting languages than others.

That said, I’ve always felt that scripting languages have somehow been less than ‘proper‘ languages like Java. Still, right tool for the job and all that, and given I’m not getting away from PHP anytime soon1 I decided to look at exactly why PHP wasn’t as ‘good’ as Java.

It’s not Object Oriented

Having done OO for a large part of my programming life I find it hard to use anything that doesn’t support objects. I suspect this is more a failing of the developer than functional programming, however, it’s a moot point as PHP is a fully OO language, I just needed to RTFM.

It’s not got a proper IDE

Around 1 or 2KLoc2 I find I’ve now got more objects than I can remember the interfaces for, which results in lots of bouncing between files to refresh my memory. This can get problematic when it breaks my train of thought. I’ve tried a number of editors and found Sublime Text was OK, but it wasn’t Eclipse. Thankfully I found PHPStorm, a proper IDE for PHP that works on a Mac. It shares a number of features with Eclipse (including being as buggy as hell) and has massively improved life when writing PHP. It costs money, but the investment is well worth it if you’re doing anything more than dabbling in PHP.

You can’t test it easily

Actually, there’s PHPUnit which I now prefer to JUnit. OK, so unit testing the code that actually renders your web pages isn’t so easy, but if you’ve got proper separation of responsibilities there should be minimal code before it hands everything off to your fully tested backend code.

It lacks ‘modern’ features

Such as…
PHP can handle closures so it’s actually more feature rich than Java in some respects. The way PHP handles method overloading is convoluted to say the least, but method overloading isn’t exactly modern and I suspect it stems from the way that PHP handles varargs (something else Java only got recently).

The code is hard to read

Yes, a lot of PHP is hard to read (go look at the WordPress codebase) but I don’t think PHP is to blame here. I spent the longest time trying to bludgeon PHP into looking like Java when I should have been bludgeoning my brain into thinking the PHP way – something I’ve finally done.

I think this last point is key when it comes to the problems with PHP. The barriers to entry with PHP are very low as you can throw together a usable web app with a UI very quickly, even as a novice developer. The result is a lot of bad PHP out there in the wild which lacks the design, testing and layout that us ‘proper’ developers would use with our ‘grownup’ languages. I’ll freely admit that some of that bad PHP belongs to me. Having matured as a PHP developer I’m hoping my next application will see me being a ‘grownup’ PHP developer.

This is a similar conclusion that that nor(DEV): panel came to. The question isn’t “is PHP3 an enterprise language?“, it’s “are your developers enterprise level developers?“.

1My hosting provider, while nice and cheap, are rather limited on what I can run, thus PHP for my personal projects.

2KLoC: Kilo-Lines of Code, or thousand lines of code.

3You can replace PHP here with a number of languages.