PHPBuilder - Test Driven Development in PHP Page 6



RSS Twitter
Articles Application Architecture

Test Driven Development in PHP - Page 6

by: Marcus Baker
|
February 3, 2004

Design with Working Tests
Designing by modifying existing code is called "Refactoring". It is an essential step in Test Driven Development as without it we lose the vital design phase altogether. I have deliberately exaggerated the poor design so far just to illustrate the process.
Here is the refactored version...

<?php
class ConfigurationParser {
    function 
parse($lines) {
        
$values = array();
        foreach (
$lines as $line) {
            if (
preg_match('/^(.*?)\s+(.*)$/'$line$matches)) {
                
$values[$matches[1]] = trim($matches[2]);
            }
        }
        return 
$values;
    }
}
?>
I actually got this right on the first go, but I suspect that this was a fluke. More likely I would have had a failure, such as forgetting to trim the trailing carriage return. In this case just do a hack to add it, rerun the tests, and then just focus on only that issue. It is much easier to shuffle the code about with the tests to protect you.
What I have done here is moved in the smallest possible steps. One of the joys of this process is that we can tune the step size as we go. If we get lot's of easy passes, take bigger steps. If you get a failure you don't expect, slow down and do less work each cycle. The cycle is red, green, refactor.
Tests as Documentation
We repeat the cycle until we cannot think of any more sensible tests to add. With five more cycles we get the following test case...

<?php
class ConfigurationTest extends UnitTestCase {
    function 
ConfigurationTest() {
        
$this->UnitTestCase();
    }
    function 
testNoLinesGivesEmptyHash() {
        
$parser = &new ConfigurationParser();
        
$this->assertIdentical($parser->parse(array()), array());
    }
    function 
testKeyValuePair() {
        
$parser = &new ConfigurationParser();
        
$this->assertEqual(
                
$parser->parse(array("a A long message\n")),
                array(
'a' => 'A long message'));
    }
    function 
testMultipleKeyValuePairs() {
        
$parser = &new ConfigurationParser();
        
$this->assertEqual(
                
$parser->parse(array("a A\n""b\tB\n")),
                array(
'a' => 'A''b' => 'B'));
    }
    function 
testBlankLinesAreIgnored() {
        
$parser = &new ConfigurationParser();
        
$this->assertEqual(
                
$parser->parse(array("\n""key value\n")),
                array(
'key' => 'value'));
    }
    function 
testCommentLinesAreIgnored() {
        
$parser = &new ConfigurationParser();
        
$this->assertEqual(
                
$parser->parse(array("# A comment\n""key value\n")),
                array(
'key' => 'value'));
    }
}
?>
Notice how the test case describes the behaviour. Once you are used to reading test cases you can use them as an executable specification of the code. Unlike coments they cannot lie.

« Previous Page
1
|
2
|
3
|
4
|
5
|
6
|
7
Next Page »

Comment and Contribute

Your comment has been submitted and is pending approval.

Author:
Marcus Baker

Comment:



Comment:

(Maximum characters: 1200). You have characters left.