unit tests

You are currently browsing articles tagged unit tests.

I was trying to figure out the best way to test the myfputcsv() function I posted yesterday. Reading the data from disc before comparing it seemed like a step where errors could creep in, but there was no obvious way round that, as the purpose of the function is to write to disc.

Then I realised I could use PHP’s (fairly) new IO streams to dump the function’s output to a temporary buffer, and read it back in for comparison. Not perfect, but it removes concerns about file mutexes, permissions, unique filenames, etc. and speeds up the tests, as they never touch disc.

It wasn’t worth building on top of PHPUnit for this… checking failure conditions can wait for another day. I just wrote a quick script that compares the output of fputcsv() and myfputcsv(). (And it worked - I’ve already fixed two errors in yesterday’s post).

This is the first time I’ve reached for php://memory. It’s obviously useful for testing code that writes to disc, but I’m now wondering where else it might come in handy.

<?php
 
require_once 'myfputcsv.php';
 
function write( $function, $array )
{
    $fp = fopen( 'php://memory', 'w+' );
    $function( $fp, $array );
    rewind( $fp );
    return fread( $fp, 1024 );
}
 
function test( $array )
{
    $fputcsv = write( 'fputcsv', $array );
    $myfputcsv = write( 'myfputcsv', $array );
    if ( assert( '$fputcsv === $myfputcsv' ) )
    {
        echo "OK" . PHP_EOL;
    }
}
 
test( array() );
test( array( "Hello", "World" ) );
test( array( "He\nllo", "World" ) );
test( array( "He\\"llo", "World" ) );
test( array( "He llo", "World" ) );
test( array( "He\tllo", "World" ) );
test( array( "He\"\"llo", "World" ) );
test( array( "He,llo", "World" ) );

PHP Singleton

I recently had a bad deer-in-the-headlights moment over a simple Singleton pattern. In an effort to turn a negative into a positive, and to burn something new (it never occurred to me that it was necessary to implement the __clone() magic method) into my feeble memory, here’s an implementation of Singleton in PHP, along with a couple of unit tests.

Of course, Singleton is still just another name for global variable.

 
/**
 * EmptySingleton
 *
 * Does nothing, but only one of it can exist at a time
 *
 * @version $Id$
 */
class EmptySingleton
{
    private static $_self = null;
 
    /**
     * EmptySingleton::init()
     *
     * Create an instance of EmptySingleton if necessary, and return it
     *
     * @access public
     * @return EmptySingleton
     */
    public static function init()
    {
        if ( self::$_self == null )
        {
            self::$_self = new EmptySingleton();
        }
 
        return self::$_self;
    }
 
    /**
     * EmptySingleton::__construct()
     *
     * The only place this can be called from is EmptySingleton::init()
     *
     * @access private
     */
    private function __construct()
    {
    }
 
    /**
     * EmptySingleton::__clone()
     *
     * If this somehow manages to get itself called, it throws an error
     *
     * @access private
     * @throws Exception
     */
    /** @codeCoverageIgnoreStart */
    private function __clone()
    {
        throw new Exception();
    }
    /** @codeCoverageIgnoreEnd */
}
 
class EmptySingletonTest extends PHPUnit_Framework_TestCase
{
    public function testCanInit()
    {
        $this->_obj = EmptySingleton::init();
        $this->assertTrue( $this->_obj instanceof EmptySingleton );
    }
 
    public function testOnlyOneInstance()
    {
        $instance_one = EmptySingleton::init();
        $instance_two = EmptySingleton::init();
 
        $instance_one->temp = 42;
 
        $this->assertEquals( $instance_one->temp, $instance_two->temp );
    }
}
 
$suite = new PHPUnit_Framework_TestSuite( 'EmptySingletonTest' );
PHPUnit_TextUI_TestRunner::run( $suite );

Update: Poking around online, I came across this interesting singleton implementation. He’s using class variables rather than instance variables, meaning that every instance of the class shares the same state. As thread safety isn’t really an issue in PHP it will work, but I think forcing class users to avoid the constructor offers a useful hint that something unusual’s going on with that class.

I was just leafing through my old copy of The Mythical Man Month. If you allow for memory size pretty much being a solved problem, it’s amazingly relevant after three decades:

Build plenty of scaffolding. By scaffolding I mean all programs and data built for debugging purposes but never intended to be in the final product. It is not unreasonable for there to be half as much code in scaffolding as there is in product.

One form of scaffolding is the dummy component, which consists only of interfaces and perhaps some faked data or some small test cases. For example, a system may include a sort program which isn’t finished yet. Its neighbors can be tested by using a dummy program that merely reads and tests the format of input data, and spews out a set of well-formatted meaningless but ordered data.

Heh. Eat your heart out, unit testers. It’s all been done before.

I’m taking some time to tidy things up around here, so I’m coalescing a bunch of one-liners into a single post:

  • Smashing Magazine generates linkdump posts faster than I can digest them. This one from April 2008 on creative web form design is one of their best. Lots of inspiration there.
  • O’Reilly Radar’s Marc Hedlund on Code Review Software.
  • . If you’re concerned with database scaling and used to thinking in terms of ACID, there’s a lot to mull over here.
  • Design Principles and Design Patterns is the clearest description of object composition I’ve ever read. Rather than the standard, 15-year-old “Fido’s a Dog, Dogs are Mammals, Mammals are Animals” object hierarchies you get in Introductory OO texts, it’s a short, readable explanation of how to design objects that are maintainable, extensible and loosely coupled. Really really good stuff.
  • A Neat Approach to Narrow Windows. Concept 64’s clever way to deal with varying page widths is firmly grounded in usability. If the page width is >800 pixels, the navigation links style themselves as a left-hand navigation menu. As the page width drops below 800 pixels the navigation links restyle themselves as tabs. Easy to do in Javascript by swapping CSS rules around, but a lot of thought has obviously gone into the design here. [It looks like the site's been taken down (wayback link, no javascript). I'm keeping the link because I hope it comes back at some point.]
  • Peterbe’s experiences at the 2006 Google London Automation Test Conference. And… wow, I’m back to 2006 already. I sure don’t post much. Anyway, unit testing is one of those things that I desperately want to use in commercial projects, but when you say to management “I want to spend two weeks writing code that won’t make it into the final application” they get a funny look in their eye. Much the same thing happens when I start talking about user stories. Or the separation of presentation and business logic. Not that I’m bitter, or anything.