<?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>Web Mozarts &#187; Development</title>
	<atom:link href="http://webmozarts.com/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://webmozarts.com</link>
	<description>On The Art Of Web Development</description>
	<lastBuildDate>Tue, 07 Sep 2010 08:02:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Easy Unit Testing</title>
		<link>http://webmozarts.com/2009/06/30/easy-unit-testing/</link>
		<comments>http://webmozarts.com/2009/06/30/easy-unit-testing/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 09:06:41 +0000</pubDate>
		<dc:creator>Bernhard</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://webmozarts.com/?p=334</guid>
		<description><![CDATA[Unit testing is a very important task of professional, scalable software development. Many tools exist to support unit testing in one or another way. All tools come with advantages and drawbacks. One of the best known test frameworks in the PHP world is PHPUnit. With the release of symfony, Fabien Potencier released another new testing [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>Unit testing is a very important task of professional, scalable software development. Many tools exist to support unit testing in one or another way. All tools come with advantages and drawbacks. One of the best known test frameworks in the PHP world is <a href="http://www.phpunit.de" title="Website of the test framework PHPUnit" target="_blank" class="liexternal">PHPUnit</a>. With the release of <a href="http://www.symfony-project.org" title="Official website of the web PHP framework &quot;symfony&quot;" target="_blank" class="liexternal">symfony</a>, <a href="http://fabien.potencier.org" title="Fabien Potencier's blog" target="_blank" class="liexternal">Fabien Potencier</a> released another new testing framework for PHP: <a href="http://trac.symfony-project.org/browser/tools/lime/trunk/lib/lime.php" title="Source code of the test framework &quot;lime&quot;" target="_blank" class="liexternal">lime</a>. The biggest advantage of <em>lime</em> over <em>PHPUnit</em> surely is the conciseness of the written test code. There are several disadvantages as well, which include bad test encapsulation due to the lack of support for fixture setup and teardown, and missing support for mock object generation.</p>
<p>Today I will briefly speak about the advantages of both frameworks, and how they can be combined to result in a slicker, powerful testing framework. I will show you how easy testing really can be! And you will be able to try it out, because all the required code has already been released in  <a href="http://www.symfony-project.org/plugins/sfLimeExtraPlugin" title="The symfony plugin sfLimeExtraPlugin" target="_blank" class="liexternal">sfLimeExtraPlugin</a>.</p>
<p><span id="more-334"></span></p>
<h3>Introduction</h3>
<p>In the following sections, I will refer to a set of example classes that I will briefly describe here for your better understanding:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> User
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000088;">$storage</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> User<span style="color: #009900;">&#40;</span>SessionStorageInterface <span style="color: #000088;">$storage</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>storage <span style="color: #339933;">=</span> <span style="color: #000088;">$storage</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setAttribute<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>storage<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>write<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getAttribute<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>storage<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>read<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The <strong>user</strong> class offers methods to store data of a user in a <strong>session storage</strong> that you need to pass to its constructor.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">interface</span> SessionStorageInterface
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> write<span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> read<span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Let&#8217;s assume that <code>SessionStorageInterface</code> specifies how session storages have to look like. They need methods to write values into the underlying layer, be it the file system or database, and methods to read values.</p>
<p>We will be writing unit tests for the <code>User</code> class. We don&#8217;t want to use a real session storage class though, because we don&#8217;t want the test to rely on the file system or a database. Thus we will create a <em>fake implementation</em> of <code>SessionStorageInterface</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> StubSessionStorage implements SessionStorageInterface
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> write<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>name <span style="color: #339933;">=</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>value <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> read<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$name</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>name ? <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>value <span style="color: #339933;">:</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p class="note">Fake implementations like this are called &#8220;Stubs&#8221;. Obviously, they would never make sense in a production environment. Their sole purpose is to help us testing, as in our case, the <code>User</code> class.</p>
<h3>PHPUnit and the xUnit Family</h3>
<p>Back in 1999, <a href="http://www.threeriversinstitute.org/Kent%20Beck.htm" title="Kent Beck's page at the Three Rivers Institute" target="_blank" class="liexternal">Kent Beck</a> wrote &#8220;the mother of all unit          testing frameworks&#8221;; it was called &#8220;SUnit&#8221; and supported unit testing for <a href="http://en.wikipedia.org/wiki/Smalltalk" title="Smalltalk at Wikipedia" target="_blank" rel="nofollow" class="liwikipedia">Smalltalk</a>[1]. <a href="http://sunit.sourceforge.net" title="Unit testing framework for Smalltalk" target="_blank" class="liexternal">SUnit</a> lead to a further testing framework, that Beck wrote in cooperation with Erich Gamma: <a href="http://www.junit.org" title="Unit testing framework for Java" target="_blank" class="liexternal">jUnit</a>, for Java. Today, <em>jUnit</em> is the most popular and widely-used unit testing framework for Java and hence it was ported to many other languages: <em>CppUnit</em> for C++, <em>NUnit</em> for C# or <em>PHPUnit</em> for PHP. All those frameworks together are often referred to as the<strong> xUnit family</strong>[2].</p>
<p><a href="http://www.phpunit.de/" title="Website of the test framework PHPUnit" target="_blank" class="liexternal">PHPUnit</a> is a high-quality port of <em>jUnit</em> to PHP written by <a href="http://sebastian-bergmann.de" title="Sebastian Bergmann's personal website" target="_blank" class="liexternal">Sebastian Bergmann</a>, currently available in stable version 3.3. A typical test case with <em>PHPUnit</em> looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> UserTest <span style="color: #000000; font-weight: bold;">extends</span> PHPUnit_Framework_TestCase
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$sessionStorage</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$user</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>sessionStorage <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> StubSessionStorage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>user <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> User<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>sessionStorage<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testAttributesAreReadFromTheSession<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// fixture setup</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>sessionStorage<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>write<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Foo'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Bar'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// execute test</span>
    <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>user<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getAttribute<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// verify results</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>assertEquals<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Bar'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'The value was read from the session'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> testAttributesAreWrittenToTheSession<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// ...</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>What does this code do? First of all, we see that the test code is organized within a <em>test class</em>. This means that you can use all the power of object-orientation for testing, but it also implies that a certain amount of code overhead is required for defining the class&#8217;s structure.</p>
<p>All methods prefixed with &#8220;test&#8221; are <em>test methods</em>. These methods test that a certain requirement is successfully fulfilled by the tested class. Because most of the test methods need a common set of objects (the &#8220;fixture&#8221;), these objects are created in the method <code>setUp()</code>, which is executed once before every test method. As a result, each test method works with fresh objects; influences of the previously executed test methods are largely prevented.</p>
<p>We also notice that test methods have descriptive names (which, to be honest, tend to look very weird). The purpose is to allow the reader to quickly scan the method names of a test class to receive an impression of the tested class&#8217;s abilities.</p>
<p>In our single, exemplary test method, we first set up the fixture; we tell the fake session storage, which has been instantiated in <code>setUp()</code>, to return the value &#8220;Bar&#8221; when the method <code>read("Foo")</code> is called. Then we call <code>getAttribute("Foo")</code> on the user, which we expect to read from the session. In the last line of code, we assert that the returned value has indeed been read from the session.</p>
<h3>Lime</h3>
<p><em>Lime</em> is a testing framework created by <a href="http://fabien.potencier.org/" title="Fabien Potencier's blog" target="_blank" class="liexternal">Fabien Potencier</a> for testing the source code of the web framework <a href="http://www.symfony-project.org/" title="Official website of the web PHP framework &quot;symfony&quot;" target="_blank" class="liexternal">symfony</a>. It is based on the <em>Test::More</em> Perl library and aims for a very concise and readable test code. The above test in <em>lime</em> looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$t</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> lime_test<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$t</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>comment<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Attributes are read from the session'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// fixture</span>
  <span style="color: #000088;">$s</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> StubSessionStorage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$u</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> User<span style="color: #009900;">&#40;</span><span style="color: #000088;">$s</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$s</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>write<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Foo'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Bar'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">// test</span>
  <span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$u</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getAttribute<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">// assertions</span>
  <span style="color: #000088;">$t</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>is<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Bar'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'The value was read from the session'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$t</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>comment<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Attributes are written to the session'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// ...</span></pre></div></div>

<p>Contrary to <em>PHPUnit</em>, <em>lime</em> tests are written in a procedural way. Thus the code is more concise, because you don&#8217;t need to write down structural information of the code.</p>
<p>Initially a <code>lime_test</code> object is created, which tracks the number of expected, successful and failing tests and offers several methods to make testing easier. Each test case is, by convention, introduced by a comment that explains the tests purpose. Therefore the method <code>comment()</code> is called, which does also print the comment on the console when executing the test.</p>
<p>The test fixture has to be created manually for each test case. This is very prone to errors, because you can easily forget to reassign a variable once in a while. Then you&#8217;ll suddenly deal with an object left over from a previous test, which may lead to strange and unexpected test results.</p>
<h3>Pro and Contra</h3>
<p>Let us roughly sum up the advantages and disadvantages of both frameworks:</p>
<p><strong>PHPUnit&#8230;</strong></p>
<ul>
<li>&#8230; is verbose</li>
<li>&#8230; offers magic methods like <code>setUp()</code>, which initiates your test fixture before every test</li>
<li>&#8230; offers other convenient tools not covered in this blog post, like mocking support</li>
</ul>
<p><strong>lime&#8230;</strong></p>
<ul>
<li>&#8230; is concise and readable</li>
<li>&#8230; requires code repetition</li>
<li>&#8230; requires you to initiate your fixture manually</li>
</ul>
<p>sfLimeExtraPlugin extends <em>lime</em> and tries to introduce concepts of the xUnit family without making tests more verbose. Quite the opposite, because sfLimeExtraPlugin supports <em>annotations</em>, the written tests are even more concise than without this plugin.</p>
<h3>Annotation-Driven Tests</h3>
<p>The above test case, written with support of sfLimeExtraPlugin, looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$t</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> lime_test_simple<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// @Before</span>
<span style="color: #000088;">$s</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> StubSessionStorage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$u</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> User<span style="color: #009900;">&#40;</span><span style="color: #000088;">$s</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// @Test: Attributes are read from the session</span>
<span style="color: #666666; font-style: italic;">// fixture</span>
<span style="color: #000088;">$s</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>write<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Foo'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Bar'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// test</span>
<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$u</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getAttribute<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// assertions</span>
<span style="color: #000088;">$t</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>is<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Bar'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'The value was read from the session'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// @Test: Attributes are written to the session</span>
<span style="color: #666666; font-style: italic;">// ...</span></pre></div></div>

<p class="info">This test leads to <em>exactly the same</em> test results and console output as the test written with plain <em>lime</em> earlier in this post.</p>
<p>sfLimeExtraPlugin introduces the new class <code>lime_test_simple</code>. When you use that test class, you can mark sections of your code with so-called <a href="http://en.wikipedia.org/wiki/Java_annotation" title="Java annotations at Wikipedia" target="_blank" rel="nofollow" class="liwikipedia">annotations</a>. The test class knows, for example, that code annotated with <code>@Before</code> must be executed before every test case.</p>
<p>Single test cases are annotated with <code>@Test</code>. You can also add a comment about the purpose of the test. Note that the comment now really is a <em>PHP comment</em>, which is usually highlighted in a different color by code editors and thus disturbs the eye much less than the call to the method <code>comment()</code>.</p>
<p>Several other annotations are available. I&#8217;ll shortly list all of them:</p>
<dl>
<dt>@Test</dt>
<dd>A test case</dd>
<dt>@Before</dt>
<dd>Executed before each test case</dd>
<dt>@After</dt>
<dd>Executed after each test case</dd>
<dt>@BeforeAll</dt>
<dd>Executed once before all test cases</dd>
<dt>@AfterAll</dt>
<dd>Executed once after all test cases</dd>
</dl>
<p>With these annotations, you can easily structure your test code and avoid code duplication while making your tests easier to read.</p>
<h3>Testing for Exceptions</h3>
<p>Contrary to plain <code>lime_test</code>, <code>lime_test_simple</code> allows you to automatically test whether exceptions are thrown. With plain <code>lime_test</code>, such a test would look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$t</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>comment<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'setAttribute() throws an exception if the data contains &amp;lt;script&amp;gt; tags'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// fixture</span>
  <span style="color: #000088;">$u</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> User<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> StubSessionStorage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">// test</span>
  try
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$u</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>setAttribute<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&amp;lt;script&amp;gt;alert(&quot;Evil!&quot;)&amp;lt;/script&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$t</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>fail<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'setAttribute() throws an &quot;InvalidArgumentException&quot;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  catch <span style="color: #009900;">&#40;</span>InvalidArgumentException <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$t</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>pass<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'setAttribute() throws an &quot;InvalidArgumentException&quot;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>In this test, we try to catch the expected exception. If the exception is caught, we mark  the test as passed, otherwise as failed.</p>
<p>With <code>lime_test_simple</code>, this is much easier:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// @Before</span>
<span style="color: #000088;">$u</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> User<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> StubSessionStorage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// @Test: setAttribute() throws an exception if the data contains &amp;lt;script&amp;gt; tags</span>
<span style="color: #666666; font-style: italic;">// fixture</span>
<span style="color: #000088;">$t</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>expect<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'InvalidArgumentException'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// test</span>
<span style="color: #000088;">$u</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>setAttribute<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&amp;lt;script&amp;gt;alert(&quot;Evil!&quot;)&amp;lt;/script&amp;gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Mock and Stub Objects</h3>
<p>Like <em>PHPUnit</em>, sfLimeExtraPlugin allows you to automatically generate fake objects, which are referred to as &#8220;Mocks&#8221; and &#8220;Stubs&#8221;. So far, we had to write our fake <code>StubSessionStorage</code> class by hand. With sfLimeExtraPlugin this is not needed anymore. The component <code>lime_mock</code> will generate such a class automatically:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// @Before</span>
<span style="color: #000088;">$s</span> <span style="color: #339933;">=</span> lime_mock<span style="color: #339933;">::</span><span style="color: #004000;">create</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SessionStorageInterface'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$u</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> User<span style="color: #009900;">&#40;</span><span style="color: #000088;">$s</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// @Test: Attributes are read from the session</span>
<span style="color: #666666; font-style: italic;">// fixture</span>
<span style="color: #000088;">$s</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>read<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>returns<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Bar'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$s</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>replay<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// test</span>
<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$u</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getAttribute<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// assertions</span>
<span style="color: #000088;">$t</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>is<span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Bar'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'The value was read from the session'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Before the execution of each test case, we tell <code>lime_mock</code> to generate a new fake instance of <code>SessionStorageInterface</code>. In the test itself, we teach the fake object which methods can be called with what parameters and which value should be returned. We can also specify other constraints, such as how often a method may be called or which exception it should throw.</p>
<p>Then we switch the fake object into &#8220;replay&#8221; mode. In this mode, the fake object will behave just the way that we configured it before.</p>
<p class="note">You can create stubs for interfaces, classes or abstract classes. You can even create stubs for non-existing classes, which is very convenient if you develop test-driven.</p>
<p>Because this topic deserves a whole blog post of its own, I won&#8217;t go into more detail here. For more information about Mocks and Stubs in general and their usage in sfLimeExtraPlugin in specific can be found on the <a href="http://www.symfony-project.org/plugins/sfLimeExtraPlugin/0_2_0?tab=plugin_readme" title="Readme page of sfLimeExtraPlugin" target="_blank" class="liexternal">readme page</a> of sfLimeExtraPlugin.</p>
<h3>Final Words</h3>
<p>I personally think that tests can be written in a much more concise and readable way with sfLimeExtraPlugin. Because it also introduces other powerful features of the xUnit-family, the plugin aims to be an essential tool of every symfony developer who wants to seriously unit test his or her application.</p>
<p>Currently the plugin is available in version 0.2.0alpha. That means that the API may change before the final release (though this is unlikely) and that the code is not being considered 100% stable. I recommend you to try it out nevertheless and give me feedback about its usefulness or shortcomings, report bugs etc.</p>
<p>What do you think about sfLimeExtraPlugin? Do you think you may ever use it?</p>
<h3>References</h3>
<p>[1] Kent Beck, Donald G. Firesmith: <em>Kent Beck&#8217;s Guide to Better Smalltalk</em>. Cambridge University Press, 1998. Page 408</p>
<p>[2] Gerard Meszaros: <em>xUnit Test Patterns. Refactoring Test Code</em>. Addison-Wesley, 2007. Page 75</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://webmozarts.com/2009/06/30/easy-unit-testing/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>

