<?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>VG Tech &#187; Unit testing</title>
	<atom:link href="http://tech.vg.no/category/qa/unit-testing/feed/" rel="self" type="application/rss+xml" />
	<link>http://tech.vg.no</link>
	<description>VGTech is a blog where the developers and devops of Norways most visited website share code and tricks of the trade...</description>
	<lastBuildDate>Fri, 16 Mar 2012 11:45:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Running multiple versions of PHPUnit</title>
		<link>http://tech.vg.no/2011/11/29/running-multiple-versions-of-phpunit/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=running-multiple-versions-of-phpunit</link>
		<comments>http://tech.vg.no/2011/11/29/running-multiple-versions-of-phpunit/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 11:43:51 +0000</pubDate>
		<dc:creator>Christer Edvartsen</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Unit testing]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpunit]]></category>

		<guid isPermaLink="false">http://tech.vg.no/?p=266</guid>
		<description><![CDATA[The latest version of PHPUnit (3.6.4 at the time of this writing) does not play well with the Zend Framework extensions (Zend_Test_PHPUnit). After asking Matthew Weier O&#8217;Phinney about this he answered that they had standardized on PHPUnit-3.4 for ZF1. Having just upgraded to the latest version of PHPUnit on our servers we were no longer [...]]]></description>
			<content:encoded><![CDATA[<p>The latest version of <a href="https://github.com/sebastianbergmann/phpunit/">PHPUnit</a> (3.6.4 at the time of this writing) does not play well with the <a href="http://framework.zend.com">Zend Framework</a> extensions (<a href="http://framework.zend.com/manual/en/zend.test.phpunit.html">Zend_Test_PHPUnit</a>). After asking <a href="http://mwop.net/blog">Matthew Weier O&#8217;Phinney</a> about this he answered that they had <a href="https://twitter.com/#!/weierophinney/status/141141184411209729">standardized on PHPUnit-3.4 for ZF1</a>.</p>
<p>Having just upgraded to the latest version of PHPUnit on our servers we were no longer able to test our Zend Framework applications. One option was to downgrade PHPUnit, but since we were already using some of the new features this was not going to happen.</p>
<p>One solution to this problem is to run multiple versions of PHPUnit and use specific versions for specific test suites. Not optimal, but at least it gets the job done.<span id="more-266"></span></p>
<p>Installing multiple versions can be accomplished by using the <code>--installroot</code> option to the <code>pear</code> command:</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: bash">sudo pear config-set auto_discover 1
sudo pear install --installroot /some/path/phpunit34 pear.phpunit.de/PHPUnit-3.4.15</pre></div>
<p>This will install PHPUnit-3.4.15 to <code>/some/path/phpunit34</code>.</p>
<p>You will need to make a small change to one of the installed files to fix the <code>include_path</code>. If you installed the package to <code>/some/path/phpunit34</code> the file you want to change is <code>/some/path/phpunit34/usr/bin/phpunit</code>. Before the first <code>require_once</code> statement in that file, enter the following code:</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: php">
// Ubuntu / Debian
set_include_path(implode(PATH_SEPARATOR, array(
    dirname(__FILE__) . '/../share/php',
    get_include_path()
)));

// CentOS
set_include_path(implode(PATH_SEPARATOR, array(
    dirname(__FILE__) . '/../share/pear',
    get_include_path()
)));

</pre></div>
<p>The path you need to prepend to PHP&#8217;s <code>include_path</code> is different from distro to distro. To see the path your system uses run the following command:</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: bash">pear config-show|grep php_dir</pre></div>
<p>or simply look around in the directory where you installed the specific version of PHPUnit.</p>
<p>The last part of the puzzle is to place a symlink to the file you just edited in /usr/bin. This can be done by running the following command:</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: bash">sudo ln -s /some/path/phpunit34/usr/bin/phpunit /usr/bin/phpunit34</pre></div>
<p>To verify that everything works you can run these commands:</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: bash">christere@spongebob:~$ phpunit --version
PHPUnit 3.6.4 by Sebastian Bergmann.

christere@spongebob:~$ phpunit34 --version
PHPUnit 3.4.15 by Sebastian Bergmann.
</pre></div>
<p>Feel free to leave a comment if you see any possible problems with this solution.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.vg.no/2011/11/29/running-multiple-versions-of-phpunit/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Unit testing with streams in PHP</title>
		<link>http://tech.vg.no/2011/06/27/unit-testing-with-streams-in-php/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=unit-testing-with-streams-in-php</link>
		<comments>http://tech.vg.no/2011/06/27/unit-testing-with-streams-in-php/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 20:22:21 +0000</pubDate>
		<dc:creator>André Roaldseth</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Unit testing]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[streams]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://tech.vg.no/?p=110</guid>
		<description><![CDATA[Using the memory/temporary stream provided by php:// stream wrapper you  can create a stream with read and write access directly to RAM or to a temporary file. This gives you the possibilty to write unit tests that does not rely on a specific file, resource or stream, but rather on data provided by the test [...]]]></description>
			<content:encoded><![CDATA[<p>Using the memory/temporary stream provided by <a title="php:// — Accessing various I/O streams" href="http://no2.php.net/manual/en/wrappers.php.php">php:// stream wrapper</a> you  can create a stream with read and write access directly to RAM or to a temporary file.</p>
<p>This gives you the possibilty to write unit tests that does not rely on a specific file, resource or stream, but rather on data provided by the test itself.</p>
<p>Creating a memory stream is easy; <code>$fp = fopen('php://memory', 'r+');</code>. Now you have a <a title="PHP: Resources - Manual" href="http://no2.php.net/manual/en/language.types.resource.php">resource </a>that can be <a title="PHP: Streams - Manual" href="http://no.php.net/manual/en/book.stream.php">used and manipulated</a> just like any other stream or file.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.vg.no/2011/06/27/unit-testing-with-streams-in-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mocking the file system using PHPUnit and vfsStream</title>
		<link>http://tech.vg.no/2011/03/09/mocking-the-file-system-using-phpunit-and-vfsstream/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mocking-the-file-system-using-phpunit-and-vfsstream</link>
		<comments>http://tech.vg.no/2011/03/09/mocking-the-file-system-using-phpunit-and-vfsstream/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 14:47:07 +0000</pubDate>
		<dc:creator>Christer Edvartsen</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Unit testing]]></category>

		<guid isPermaLink="false">http://tech.vg.no/?p=9</guid>
		<description><![CDATA[This article is about how to mock the file system when writing unit tests, and it will be rather code-heavy. If you are not familiar with the concept of unit testing this article might not be the best place to start. There will be other articles regarding unit testing on this blog, so keep coming [...]]]></description>
			<content:encoded><![CDATA[<p>This article is about how to mock the file system when writing unit tests, and it will be rather code-heavy. If you are not familiar with the concept of unit testing this article might not be the best place to start. There will be other articles regarding unit testing on this blog, so keep coming back for more.<span id="more-9"></span></p>
<p>Those of you still reading are hopefully familiar with unit testing. <a href="http://phpunit.de" target="_blank">PHPUnit</a> is the de-facto standard for unit testing in PHP projects, and this is what we will be using together with <a href="http://code.google.com/p/bovigo/wiki/vfsStream" target="_blank">vfsStream</a> in this article.</p>
<p>vfsStream is a <a href="http://no2.php.net/streams" target="_blank">custom stream wrapper</a> for PHP that works as a virtual file system that PHP&#8217;s built in filesystem functions can use. Some functions that work with vfsStream are:</p>
<ul>
<li><a href="http://no2.php.net/file_exists" target="_blank">file_exists</a></li>
<li><a href="http://no2.php.net/copy" target="_blank">copy</a></li>
<li><a href="http://no2.php.net/mkdir" target="_blank">mkdir</a></li>
<li><a href="http://no2.php.net/unlink" target="_blank">unlink</a></li>
<li><a href="http://no2.php.net/is_file" target="_blank">is_file</a></li>
<li><a href="http://no2.php.net/is_dir" target="_blank">is_dir</a></li>
</ul>
<p>There are some known limitations when using custom stream wrappers. Some functions that does not work with vfsStream:</p>
<ul>
<li><a href="http://no2.php.net/realpath" target="_blank">realpath</a></li>
<li><a href="http://no2.php.net/chmod" target="_blank">chmod</a></li>
<li><a href="http://no2.php.net/chown" target="_blank">chown</a></li>
<li><a href="http://no2.php.net/chgrp" target="_blank">chgrp</a></li>
<li><a href="http://no2.php.net/touch" target="_blank">touch</a></li>
<li><a href="http://no2.php.net/move_uploaded_file" target="_blank">move_uploaded_file</a></li>
</ul>
<p>vfsStreams&#8217; known limitations are <a href="http://code.google.com/p/bovigo/wiki/vfsStreamDocsKnownIssues" target="_blank">listed on its wiki</a>. Now, on to the code!</p>
<p>The following simplified class is the class we will be testing using PHPUnit and the vfsStream stream wrapper:</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: php">class VGF_Storage_Driver_Filesystem {
    /**
     * Root directory
     *
     * @var string
     */
    public $rootDir = null;

    /**
     * Store a file
     *
     * @param string $originalPath Path to the original local file
     * @param string $hash Hash that will be used to identify the new file
     * @return boolean Returns true on success or false on failure
     */
    public function store($originalPath, $hash) {
        return copy($originalPath, $this-&gt;rootDir . '/' . $hash);
    }

    /**
     * Delete a file
     *
     * @param string $hash Hash identifying the file we want to delete
     * @return boolean Returns true on success or false on failure
     */
    public function delete($hash) {
        return unlink($this-&gt;rootDir . '/' . $hash);
    }

    /**
     * Fetch a file
     *
     * @param string $hash Hash identifying the file we want to fetch
     * @return string Returns the content of the file
     */
    public function get($hash) {
        return file_get_contents($this-&gt;rootDir . '/' . $hash);
    }
}</pre></div>
<p><strong>PS!</strong> The class is very simplified and does not include error handling at all. It should only be used for instructional purposes.</p>
<p>As you can see the class uses regular file system functions such as <code>copy</code>, <code>unlink</code>, and <code>file_get_contents</code>. To be able to get full code coverage on this class all these functions need to work their magic.</p>
<p>A typical way to solve this when writing tests is to create files/folders in PHPUnit&#8217;s <code>setUp()</code> method and remove them again in the <code>tearDown()</code> method. This works, but if your tests somehow dies (fatal error for instance) during a test run you are left with files/folders on disk that was never cleaned up. vfsStream does not touch the file system at all, but keeps virtual files and folders in memory, so if your test suite dies there is nothing on disk that was not there before you started the tests. Also, if you manage to sneak in a bug that deletes more files than it should it&#8217;s safer to work on a virtual file system than an actual one.</p>
<p>Now, lets take a look at the basics of vfsStream. First you will need to install it. This can be done easily using <a href="http://pear.php.net/" target="_blank">PEAR</a>:</p>
<pre>$ pear channel-discover pear.php-tools.net
$ pear install pat/vfsStream-beta</pre>
<p>After installation make sure the vfsStream directory is in your include path. If you have a sane PEAR environment you are most likely good to go.</p>
<p>The following snippet will show you the basics of vfsStream:</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: php">&lt;?php
require_once 'vfsStream/vfsStream.php';

vfsStreamWrapper::register();
$root = vfsStream::newDirectory('someDir');
vfsStreamWrapper::setRoot($root);

var_dump(is_dir(vfsStream::url('someDir'))); // true
var_dump(is_file(vfsStream::url('someDir'))); // false
var_dump(is_dir(vfsStream::url('someOtherDir'))); // false

$file = vfsStream::newFile('someFile');
$root-&gt;addChild($file);

var_dump(is_file(vfsStream::url('someDir/someFile'))); // true
var_dump(file_exists(vfsStream::url('someDir/someFile'))); // true
var_dump(is_file(vfsStream::url('dir/someOtherFile'))); // false

unlink(vfsStream::url('someDir/someFile'));
var_dump(file_exists(vfsStream::url('someDir/someFile'))); // false</pre></div>
<p>First we simply require the main <code>vfsStream</code> class (that in turn will require other components as well). The next three lines registers the stream wrapper (which defaults to <strong>vfs://</strong>) and creates the root directory which <code>vfsStream</code> will use as a container for other virtual files and directories. These three lines can be replaced by:</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: php">$root = vfsStream::setup('someDir');</pre></div>
<p>which is a convenience method that will be used in the unit tests later on.</p>
<p>The <code>vfsStream::url</code> method that is used in the code snippet above creates the path that the file system functions must use. It will simply prepend the schema to the file/directory name.</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: php">var_dump(vfsStream::url('someDir')); // "vfs://someDir"</pre></div>
<p>The next few lines in the code snippet just illustrates how the regular file system functions work with <code>vfsStream</code>.</p>
<p>To add a file we first create a new <code>vfsStreamFile</code> object by calling <code>vfsStream::newFile()</code> which simply takes a filename as argument. We attach it to the root directory by using the root object&#8217;s <code>addFile</code> method. After this we do some file system checks for the file, remove it, and check again. As you can see all this is pretty similar to working with regular files.</p>
<p>Now that we have the basic usage of vfsStream out of the way, let&#8217;s move on to how to incorporate this into our tests. The below code snippet is the test class without any actual tests as we&#8217;ll add them later on.</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: php">&lt;?php
require_once 'vfsStream/vfsStream.php';

class VGF_Storage_Driver_FilesystemTest extends PHPUnit_Framework_TestCase {
    /**
     * Driver instance
     *
     * @var VGF_Storage_Driver_Filesystem
     */
    protected $driver = null;

    /**
     * Setup method
     *
     * This method will register the vfsStream stream wrapper and create a new instance of the driver
     */
    public function setUp() {
        vfsStream::setup('someDir');
        $this-&gt;driver = new VGF_Storage_Driver_Filesystem();
        $this-&gt;driver-&gt;rootDir = vfsStream::url('someDir');
    }

    /**
     * Tear down method
     *
     * This method will destroy the instance of the driver
     */
    public function tearDown() {
        $this-&gt;driver = null;
    }
}</pre></div>
<p>As you can see from the code snippet we use the <code>vfsStream::setup</code> method to create a root dir, and set that dir as the <code>rootDir</code> in the driver. No action is needed in the <code>tearDown()</code> method regarding <code>vfsStream</code>. The first test we will write shall test the <code>store</code> method.</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: php">/**
 * Test the store method in the driver
 */
public function testStore() {
    $hash = md5(microtime());
    $root = vfsStreamWrapper::getRoot();

    $this-&gt;assertFalse($root-&gt;hasChild($hash));
    $this-&gt;assertTrue($this-&gt;driver-&gt;store(__FILE__, $hash));
    $this-&gt;assertTrue($root-&gt;hasChild($hash));
}</pre></div>
<p>First we create a random hash value that will be used to identify the file internally in our driver. Then we make sure the file does not exist prior to running the <code>store</code> method. After storing the file we assert that it now exists. The <code>vfsStreamWrapper::getRoot()</code> method returns the root <code>vfsStreamDirectory</code> object, on which we call the <code>hasChild()</code> method to see if it has a child with a given name.</p>
<p>Next up is the <code>delete</code> method:</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: php">/**
 * Test the delete method in the driver
 */
public function testDelete() {
    $hash = md5(microtime());
    $root = vfsStreamWrapper::getRoot();
    $root-&gt;addChild(vfsStream::newFile($hash));

    $this-&gt;assertTrue($root-&gt;hasChild($hash));
    $this-&gt;assertTrue($this-&gt;driver-&gt;delete($hash));
    $this-&gt;assertFalse($root-&gt;hasChild($hash));
}</pre></div>
<p>This is pretty much the same as the previous test method except that we register a virtual file before calling <code>delete()</code>. After deleting we assert that the file is actually gone. Now for the last test:</p>
<div class="code_wrap"><a href="#" class="code_opener">Show code</a><pre class="brush: php">/**
 * Test the get method in the driver
 */
public function testGet() {
    $hash = md5(microtime());
    $content = 'some content';
    $file = vfsStream::newFile($hash);
    $file-&gt;setContent($content);
    vfsStreamWrapper::getRoot()-&gt;addChild($file);

    $this-&gt;assertSame($content, $this-&gt;driver-&gt;get($hash));
}</pre></div>
<p>In this last test method we create a virtual file with content by using the <code>setContent()</code> method on the <code>vfsStreamFile</code> object. After adding the virtual file we assert that we get the same content when fetching the file identified by <code>$hash</code>.</p>
<p>And that&#8217;s that! If anyone has used vfsStream differently or has related questions, don&#8217;t hesitate to leave a comment. Happy testing!</p>
<p>Related links:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Unit_testing" target="_blank">Unit testing</a></li>
<li><a href="http://phpunit.de" target="_blank">PHPUnit</a></li>
<li><a href="http://code.google.com/p/bovigo/wiki/vfsStream" target="_blank">vfsStream</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://tech.vg.no/2011/03/09/mocking-the-file-system-using-phpunit-and-vfsstream/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

