PHP in Action

Many test methods versus custom assertions

dagfinn | 16 September, 2008 13:27

This is something I posted to the Sitepoint PHP Application Design Forum with a little bit of added background.

The background is the idea that unit test methods, for the sake of readability, should test only one single behavior. This may mean several tests for one method under test, since one method may have several behaviors. One version of this is the notion of one assertion per test.

Web tests are not quite the same thing as unit test. On the Sitepoint forum, in a discussion on web testing, I said:

It's also very slow to have too many separate test methods. So instead, to make it readable, I tend to use custom assertions.

Marcus Baker asked me for examples. I tried to illustrate the principle with an example that may be a something of a caricature.

If performance and speed were not an issue, I might do something like this, keeping each test method short and sweet: PHP Code:

class ArticleListTest extends WebTestCase {
 
    function setUp() {
        // Some code to log in and go to the article list page
        //....
    }
 
    function testHttpStatusOk() {
        //...
    }
 
    function testHasCorrectTitle() {
        //...
    }
 
    function testHasNoDebugInfoAccidentallyLeftBehind() {
        //...
    }
} 
 

Unfortunately, it would be nauseatingly slow, since you have to traverse some web pages for every single test method. Instead, I can try to get similar small chunking by using custom assertions: PHP Code:

class VariousPageTests extends WebTestCase {
 
    function testLoginAndArticleList() {
        // Some code to log in
        //....
 
        $this->assertStartPage();
 
        // Some code to go to article list page
        //....
 
        $this->assertArticleListPage();
    }
 
    function assertArticleListPage() {
        $this->assertHttpStatusOk();
        $this->assertHasCorrectTitle();
        $this->assertHasNoDebugInfoAccidentallyLeftBehind();
    }
 
    function assertStartPage() {
        //
    }
} 
 

This way, the code has names for approximately the same details as in the first example.

Type hints are more useful for scalars than objects

dagfinn | 06 September, 2008 23:46

Max Horvath has implemented a library for type hinting scalars. That interests me, since I find that type hinting for objects has limited usefulness.

I tried using type hints extensively from an early beta version of PHP 5. I mostly gave up on them for three reasons:

  1. They make refactoring harder since you get lots of dependecies on a particular class name.
  2. Making sure an object is the right class has limited usefulness. If you pass an object of the wrong class to a method without type hinting, you're still alerted to the error the moment you try to call a non-existent method (one belonging to the class it was supposed to be as opposed to the class it actually is). This typically happens early.
  3. My experience is I hardly ever see actual bugs in practice that would have been caught earlier if there had been a type hint. I (nearly) always have good unit test coverage. It may be different if you don't, but that's not an advisable way to live.

I admit that these jugdments are hard to make. I could be wrong, more or less. Type hints are probably useful when code becomes stable enough and at the boundaries between modules. But I still tend to avoid using them until I get an actual bug that might have been prevented by a type hint. Their usefulness is and has to be an empirical question. The purpose of using them has to be catching errors earlier, so if they don't have that effect, there's no point.

For the purposes of this blog post, reason 2 is the important one. The idea is that type hints are more useful for arrays and scalars than for objects. Why? Because they have the potential to catch errors that would otherwise be hard to find or escape unnoticesd. As I said, if you pass an object of the wrong class, you will usually get a "non-existent method" error quickly. The same thing happens if you try to pass an array or scalar instead of an object. But if you try to pass an object instead of an array, an array instead of a scalar or vice versa, you can keep using the passed array or scalar for some time before it blows up. The problem becomes harder to track down. I've used type hints for arrays, and found them more meaningful and less troublesome than object type hints.

One case I've seen in which scalar type hinting would be useful is a simple homegrown date and time object that is initialized by passing a Unix timestamp as an argument to the constructor. A couple of times I've made the mistake of passing an object instead. The ensuing error can be hard to figure out. If I could type hint to make sure it's an integer, that would be helpful.

Performance optimism

dagfinn | 01 September, 2008 14:02

I like weird ideas. There should be more of them. And the idea that we need to make programs efficient to save energy is weird enough to interest me.

David Peterson tells his version of Rasmus Lerdorfs views on it:

He continues on by stating that PHP developers really need to think about performance for not only scalability reasons but for green reasons. If programs were more efficient it would cut the number of data centres and would reduce energy needs as a result. In our newly emerging age of energy awareness this does become an important aspect and I am glad that he is raising awareness.

Well, theoretically, using less of anything makes good environmental sense. But you have to consider which actions have a big impact and which are marginal. For example, Norwegian politicians have considered banning incandescent light bulbs. But the idea makes a lot less sense here than in some other countries, since it's hardly ever dark and warm at the same time this far north. Therefore, the heat generated by indoor lighting contributes to heating that would be needed anyway and is usually electric already.

"Premature optimization is the root of all evil." It occurs to me that energy saving is a kind of optimization and subject to similar considerations. It needs to be focused so it's applied where it matters most and where you can get the most out of the least effort.

How much traffic does a web app need to have to make optimization worthwhile? Does the green angle add anything to that assessment?

Theoretically, it might if the cost of energy does not cover the cost of its environmental consequences. But it's a question that requires analysis. If cutting data center energy consumption is important, it makes sense to know and apply the strategies that are most cost-effective. Putting the waste heat to use? Using more of the hardware and techniques that are used to make laptops energy-efficient? I don't know, I'm not an expert on these things. What I do know is the idea of green optimization needs that kind of thinking to put it in context.

 
Accessible and Valid XHTML 1.0 Strict and CSS
Powered by LifeType - Design by BalearWeb