<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Open Source Web Thoughts &#187; test driven development</title>
	<atom:link href="http://blog.dewaldbotha.co.za/tag/test-driven-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.dewaldbotha.co.za</link>
	<description></description>
	<lastBuildDate>Fri, 25 Nov 2011 09:17:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Test drive your PHP code</title>
		<link>http://blog.dewaldbotha.co.za/2009/03/30/test-drive-your-php-code/</link>
		<comments>http://blog.dewaldbotha.co.za/2009/03/30/test-drive-your-php-code/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 14:53:14 +0000</pubDate>
		<dc:creator>dewaldbotha</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[test driven development]]></category>
		<category><![CDATA[unit testing]]></category>
		<category><![CDATA[martin fowler]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[uml]]></category>

		<guid isPermaLink="false">http://blog.dewaldbotha.co.za/2009-03-30/test-drive-your-php-code/</guid>
		<description><![CDATA[Lately I&#8217;ve ventured fully submerged into the world of Test driven development (TDD). This might start out a bit scary, especially if you have only heard about it, but never done it yourself. There is a couple of good reads on the net, so you might want to start out by familiarising yourself with this <a href="http://blog.dewaldbotha.co.za/2009/03/30/test-drive-your-php-code/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve ventured fully submerged into the world of <a href="http://en.wikipedia.org/wiki/Test-driven_development" title="Test Driven Development">Test driven development (TDD)</a>.</p>
<p>This might start out a bit scary, especially if you have only heard about it, but never done  it yourself.  There is a couple of good reads on the net, so you might want to start out by familiarising yourself with this exciting way of doing things.</p>
<p>Have a look at <a href="http://en.wikipedia.org/wiki/Test-driven_development" title="Test Driven Development" target="_blank">http://en.wikipedia.org/wiki/Test-driven_development</a> or <a href="http://lmgtfy.com/?q=test+driven+development" title="Test Driven Development" target="_blank">Google it</a>.</p>
<h3>What is test driven development?</h3>
<p><a href="http://en.wikipedia.org/wiki/Test-driven_development" title="Test Driven Development">Test driven development (TDD)</a> is more a change in coding philosophy than anything else.   Some of us might say: &#8220;&#8230;yip, I&#8217;ve written a couple of unit tests when I had some spare time at the end of my project.&#8221;</p>
<p>To be honest, this is a bit of the wrong way round method of doing things, kind of like building a house by putting on the roof first.   I think <a href="http://martinfowler.com/" title="Martin Fowler" target="_blank">Martin Fowler</a> describes it best when he pointed out these three components.</p>
<ul>
<li>Write a test for the next bit of functionality you want to add.</li>
<li>Write the functional code until the test passes.</li>
<li>Refactor both new and old code to make it well structured.</li>
</ul>
<p><a href="http://en.wikipedia.org/wiki/Test-driven_development" title="Test Driven Development" target="_blank">TDD</a> is a branch of <a href="http://en.wikipedia.org/wiki/Agile_software_development" title="Agile Development" target="_blank">Agile development</a> which was based upon the first stages of <a href="http://en.wikipedia.org/wiki/Extreme_programming" title="Extreme Programming" target="_blank">extreme programming</a>, but has really become a coding methodology that changed the way in which a lot of projects are being done.<br />
<span id="more-17"></span></p>
<h3>What do I need to get started?</h3>
<h4>UML</h4>
<p>It is always good to have a basic <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language" title="Unified Modeling Language" target="_blank">Unified Modeling Language (UML)</a> diagram of how you would like your objects/classes to work and behave, but believe me, after you analyzed it through testing, you would do a fair amount of refactoring.</p>
<p>Here we have some pretty <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language" title="Unified Modeling Language" target="_blank">UML</a> for a very basic Message object which must create and delete messages.  The Message implements a Message_Store object for message storage.</p>
<p><img src="http://farm4.static.flickr.com/3451/3397964953_6165f47f15.jpg" alt="Message UML" /></p>
<h4>PHPUnit</h4>
<p>Now before you even attempt to write a line of code &#8211; go to <a href="http://www.phpunit.de/" title="PHPUnit" target="_blank">http://www.phpunit.de/</a>.</p>
<p>This will become your friend in days/months/years to come and you will learn to love it.  <img src='http://blog.dewaldbotha.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>Background:</strong></p>
<p><a href="http://www.phpunit.de/" title="PHPUnit" target="_blank">PHPUnit</a> was created by a German fellow called <a href="http://sebastian-bergmann.de/" title="Sebastian Bergmann" target="_blank">Sebastian Bergmann</a> and has grown into a full fledge PHP testing framework.  It was based upon <a href="http://en.wikipedia.org/wiki/SUnit" title="SUnit" target="_blank">SUnit</a>, which was developed by the father of <a href="http://en.wikipedia.org/wiki/Extreme_programming" title="Extreme Programming" target="_blank">extreme programming</a>, <a href="http://en.wikipedia.org/wiki/Kent_Beck" title="Kent Beck" target="_blank">Kent Beck</a>,  to accommodate testing in <a href="http://en.wikipedia.org/wiki/Smalltalk" title="Smalltalk" target="_blank">Smalltalk</a>.</p>
<p><strong>Installing:</strong></p>
<p>The easiest way to install <a href="http://www.phpunit.de/" title="PHPUnit" target="_blank">PHPUnit</a> would be via your <a href="http://pear.php.net/" title="Pear" target="_blank">PEAR</a> Installer.</p>
<p>First you must register <a href="http://www.phpunit.de/" title="PHPUnit" target="_blank">PHPUnit</a> <a href="http://pear.php.net/" title="Pear" target="_blank">PEAR</a> channel with your local <a href="http://pear.php.net/" title="Pear" target="_blank">PEAR</a> environment.</p>
<pre lang="php">
pear channel-discover pear.phpunit.de</pre>
<p>Now you can install <a href="http://www.phpunit.de/" title="PHPUnit" target="_blank">PHPUnit</a> to your local <a href="http://pear.php.net/" title="Pear" target="_blank">PEAR</a> packages</p>
<pre lang="php">
pear install phpunit/PHPUnit</pre>
<p>That should be it for now &#8211; <a href="http://www.phpunit.de/" title="PHPUnit" target="_blank">PHPUnit</a> should hopefully be installed on your system.  According to the <a href="http://www.phpunit.de/" title="PHPUnit" target="_blank">PHPUnit</a> website the directory it is located in is /usr/lib/php/PHPUnit, but I instead found it inside /usr/share/php/PHPUnit on my Ubuntu installation.  In all likelyhood it should be located inside the same directory as your <a href="http://pear.php.net/" title="Pear" target="_blank">PEAR</a> installation.</p>
<h3>Let the testing commence.</h3>
<p>&#8220;Whoa, whoa, whoa!&#8221;, most developers would cry.  &#8220;How can you possibly test code you haven&#8217;t written yet?&#8221;, they all sing together.</p>
<p>Here is where the mind shift starts.  You should have a basic understanding of how your code should work/behave after you have done the <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language" title="Unified Modeling Language" target="_blank">UML</a> for your class.   So why not use the way you think your code should behave in your tests.</p>
<h4>Your test class</h4>
<p>First things first.  If you have a look at your <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language" title="Unified Modeling Language" target="_blank">UML</a> diagram you would see that there is a dependency between the Message class and Message_Store class.</p>
<p><img src="http://farm4.static.flickr.com/3451/3397964953_6165f47f15.jpg" alt="Message UML" /></p>
<p>You should now write the test for how your Message object should behave.</p>
<pre lang="php">
//Include the base class for PHPUnit in order for your tests to work
require_once 'PHPUnit/Framework/TestCase.php';

//Include the Message class you are testing
require_once 'Message.php';

//Your Message Test Class
class MessageTest extends PHPUnit_Framework_TestCase
{

//Create a private class variable for re-use
private $oMessage;

/*
The setUp class function is native to PHPUnit and is executed infront of each
test function.  This will help you do things such as create a new object to work with before each new test.
*/
protected function setUp()
{
    $this->oMessage = new Message();
}

/*
The tearDown class function is reverse of the setUp() function and is executed after each test.
This will help you do things such as setting objects to a NULL value for re-use.
*/
protected function tearDown()
{
  $this->oMessage = null;
}

/*
First you test the construction of your Message object.
This isn't really necessary, since you know that a PHP constructor is suppose to work <img src='http://blog.dewaldbotha.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> , but is just done
for completeness sake.
$this->assertType() tests to see if the object you created is of the type 'Message'.
*/
public function testMessageConstructed()
{
    $this->assertType('Message', new Message());
}

/*
Now you start testing all the public methods inside your class.  Since you are going to test the way you want
your code to work in, you will only be allowed to test the public accessible methods.  The tests will still cover any
private methods which is called from the public method tested.
This is kind of a double-barrel test. Since you can prove that the setStore is working if the getStore returns the
correct object.
$this->assertSame() will test if two different variables are of the exact same type
*/
public function testSetAndGetStore()
{
    $oPDO = new PDO('mysql:host=localhost;dbname=localdb', 'username', 'password');
    $oMessageStore = new Message_Store_Pdo($oPDO);
    $this->oMessage->setStore($oMessageStore);
    $this->assertSame($oMessageStore,$this->oMessage->getStore());
}

/*
You will now test if the save function will return a variable of bool type, either true if correctly saved or
false if incorrectly saved
*/
public function testSave()
{
    $oPDO = new PDO('mysql:host=localhost;dbname=localdb', 'username', 'password');
    $oMessageStore = new Message_Store_Pdo($oPDO);
    $this->oMessage->setStore($oMessageStore);
    $this->assertType('boolean',$this->oMessage->save('Hello'));
}

/*
You will now test if the delete function will return a variable of bool type, either true if deleted or
false if not deleted.
*/
public function testDelete()
{
    $oPDO = new PDO('mysql:host=localhost;dbname=localdb', 'username', 'password');
    $oMessageStore = new Message_Store_Pdo($oPDO);
    $this->oMessage->setStore($oMessageStore);
    $this->assertType('boolean',$this->oMessage->delete(1));
}

}</pre>
<h4>What does our test class tell us?</h4>
<p>That&#8217;s it &#8211; we now have a couple of basic tests to cover our Message class.  The important thing about writing tests is that you should cover all public functions used in the class you are testing.  At the moment these tests shouldn&#8217;t run, but it will give you a clear idea of where to start and is great for debugging whilst writing code.</p>
<p>Already there is a bit of a discrepancy of what is happening in the unit tests and <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language" title="Unified Modeling Language" target="_blank">UML</a>.  The way we test our code, is the way we would like our objects to behave.  In the <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language" title="Unified Modeling Language" target="_blank">UML</a> we assumed that the the message store could be part of the message object, but as our tests showed us &#8211; there might be a more elegant way using a storage object, which would allow for more pluggable, <a href="http://en.wikipedia.org/wiki/Loosely_coupled" title="Loosely coupled" target="_blank">loosely-coupled</a> code.</p>
<p>If we passed a storage object into the Message object itself, after a while the message object will become bloated and unusable, since now you have to cater for your different storage objects within the Message object.  For e.g. create a saveToFileSystem function and a saveToDatabase function, where some functions might become redundant when using a specific storage object.</p>
<p>So instead of passing a PDO storage object directly to the message, you could have a Message_Store object which <a href="http://php.net/interfaces" title="PHP Inteface" target="_blank">interfaces</a> to your various storage objects, such as a PDO or filesystem etc.</p>
<p>Thus turning:</p>
<pre lang="php">
$oMessage = new Message();
$oPDO = new PDO('mysql:host=localhost;dbname=localdb', 'username', 'password');
$oMessage->setStore($oPDO);</pre>
<p>Into:</p>
<pre lang="php">
$oMessage = new Message();
$oPDO = new PDO('mysql:host=localhost;dbname=localdb', 'username', 'password');
$oMessageStore = new MessageStore($oPDO);
$oMessage->setStore($oMessageStore);</pre>
<p>By creating a Message_Store class, rather than building extra code onto your Message object, you reverse any dependencies that might occur within the Message object.  All this means is that for you can now create a message object, and pass a <a href="http://php.net/interfaces" title="Interface" target="_blank">interfaced</a> storage object to it, thus allowing your code to become more flexible, without building layers of complexity itself into the Message object.</p>
<h4>Refactor your code.</h4>
<p>Now update your <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language" title="Unified Modeling Language" target="_blank">UML</a> to include an interface to the Message_Store object.</p>
<p><img src="http://farm4.static.flickr.com/3633/3367692592_1f58519ff7.jpg" alt="Message UML" /></p>
<p>Let&#8217;s build our message class according to the tests and updated <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language" title="Unified Modeling Language" target="_blank">UML</a> diagram.</p>
<pre lang="php">
class Message
{

    private $oMessageStore;

    public function __construct($oMessageStore=Null)
    {
        $this->oMessageStore = $oMessageStore;
    }

    public function setStore($oMessageStore)
    {
        $this->oMessageStore = $oMessageStore;
    }

    public function getStore()
    {
        return $this->oMessageStore;
    }

    public function save()
    {
        return $this->oMessageStore->create($this);
    }

    public function delete($sMessageId)
    {
        return $this->oMessageStore->delete($sMessageId);
    }

}</pre>
<p>Now your Message class is starting to look elegant.  Now you can create the interface.</p>
<pre lang="php">
interface Message_Store_Interface
{
public function __construct($oStorage);
public function create($oMessage);
public function delete($sMessageId);
}</pre>
<p>You can now implement the interface in the various Message store objects.</p>
<pre lang="php">
class Message_Store_Pdo implements Message_Store_Interface{

    private $oPdo;

    public function __construct($oPdo)
    {
        $this->oPdo = $oPdo;
    }

    public function create($oMessage)
    {
        $sSql = "insert into message_store (message)
        values (?)";
        $oSql = $this->oPdo->prepare($sSql);
        $oSql->bindParam(1, $oMessage->sMessage);
        $oSql->execute();
        return (bool) $this->oPdo->lastInsertId();
    }

    public function delete($sMessageId)
    {
        $sSql = "DELETE FROM message_store
        WHERE message_id = ?";
        $oSql = $this->oPdo->prepare($sSql);
        $oSql->bindParam(1, $sMessageId);
        $oSql->execute();
        return (bool) $oSql->rowCount();
    }

}</pre>
<h3>The advantages of Test Driven Development and Unit Testing</h3>
<h4>Running the unit tests</h4>
<p>Now the big moment has arrived.  Time to run your test.  Assuming there is no syntax errors the test should execute fine.<br />
Run this by going to your command prompt and enter the following</p>
<pre lang="php">
phpunit tests/MessageTest.php</pre>
<p>If you saved the tests to MessageTest.php in the tests directory, everything should execute fine and the following would be displayed.</p>
<pre lang="php">
dewald@dewald-desktop:/var/www/mobi$ phpunit tests/MessageTest.php
PHPUnit 3.3.14 by Sebastian Bergmann.

....

Time: 0 seconds

OK (4 tests, 4 assertions)
dewald@dewald-desktop:/var/www/mobi$</pre>
<p>You have compiled your tests and ran it succesfully. <img src='http://blog.dewaldbotha.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Whoohoo &#8211; if your tests gave an error, just follow the debug messages and fix your code.  Easy as that.</p>
<p>You can also create reports to see if you have achieved acceptable code coverage by running.</p>
<pre lang="php">
phpunit --coverage-html /tmp/tests/ tests/MessageTest.php</pre>
<p>The reports should can be found in the /tmp/tests/ directory and should look something like this:</p>
<p><img src="http://farm4.static.flickr.com/3636/3398100607_9eab3051fd.jpg" alt="Test Report" /></p>
<h4>In the End</h4>
<p>In the beginning of the article I wrote that <a href="http://martinfowler.com/" title="Martin Fowler" target="_blank">Martin Fowler</a> said the following about <a href="http://en.wikipedia.org/wiki/Test-driven_development" title="Test Driven Development" target="_blank">Test Driven Development</a>:</p>
<p><strong>Write a test for the next bit of functionality you want to add.</strong></p>
<p>We wrote all our test for the functionality of our Message object in the way which we would like our object to behave.  We then test the results of that object.</p>
<p><strong>Write the functional code until the test passes.</strong></p>
<p>We wrote the functional code for the classes to make it work as we determined through our tests.</p>
<p><strong>Refactor both new and old code to make it well structured.</strong></p>
<p>After writing the tests, we realised that our code has some short-comings and dependencies, which we could reverse in-time, since we saw the way it was supposed to work in unit tests meant refactoring our <a href="http://en.wikipedia.org/wiki/Unified_Modeling_Language" title="Unified Modeling Language" target="_blank">UML</a> and inherently we would have needed to refactor our code.</p>
<p><strong>What now?</strong><br />
<a href="http://en.wikipedia.org/wiki/Test-driven_development" title="Test Driven Development" target="_blank">TDD</a> doesn&#8217;t come naturally.  Especially if you were used to years of a different kinds of development techniques.  It comes through practice and experience.</p>
<p>I&#8217;ll suggest you read through the <a href="http://www.phpunit.de/manual/3.3/en/" title="PHPunit manual and examples" target="_blank">PHPUnit manual and examples</a>, as to see how flexible the testing framework can be, also as a start, write some unit tests for your old code, and you might be surprised just how efficient you could have been.  <img src='http://blog.dewaldbotha.co.za/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dewaldbotha.co.za/2009/03/30/test-drive-your-php-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

