FLiFnotes

August 22, 2011

Purely Incremental Development

Filed under: Coding,Projects — Tags: , , , — Deborah Hawkins @ 8:17 am

Usually in incremental development there’s a plan which is subject to change as new features are added on incrementally and users have a chance to respond. For Flif Risc, I’m extending the idea to purely incremental development–a similar idea but without the overall plan. In purely incremental development, everything is subject to change. This may not be a great idea within a company where business justification is always necessary, but for a personal project it’s offers the flexibility needed to keep interest up.

Test-driven development goes hand-in-hand with any type of incremental development. Writing tests to define what you want to achieve in each iteration and then writing the code to pass them is exactly what’s needed to make regular process. As an added benefit, having the tests from previous iterations makes it easy to find out if a new feature’s implementation breaks existing functionality.

For unit testing in PHP, the natural choice in PHPUnit. At first, I had some difficulty getting PHPUnit set up from the installation instructions, but adding a sudo to the beginning of each instruction solved all my problems.

At the very basic level, I want my application to be able to take in a string which is the hex representation of a MIPS machine code instruction and output the instruction in assembly code. I’d like to accomplish this in a class structure, and knowing that the machine code for add $t1, $t2, $t0 is 0×01484820, the first test verifies that this is the result my code gives.

public function testGetAssemblyCodeAdd() {
    $input = '01484820';
    $expected = 'add $t1, $t2, $t0';
    $temp = new MipsInstruction($input);
    $this->assertEquals($expected, $temp->getAssemblyCode());
}

The easiest way to code this to make it work is to hardcode the output:

class MipsInstruction {
    public function __construct($machineCode) {
        // does nothing
    }

    public function getAssemblyCode() {
        return 'add $t1, $t2, $t0';
    }
}

Running phpunit on the one test now results in OK (1 test, 1 assertion), whoo! A commit is in order for this. Unfortunately, the code doesn’t do anything other than pass this one test, so the next step is to add a couple more tests:

public function testGetAssemblyCodeSub() {
    $input = '01484822';
    $expected = 'sub $t1, $t2, $t0';
    $temp = new MipsInstruction($input);
    $this->assertEquals($expected, $temp->getAssemblyCode());
}

public function testGetAssemblyCodeOr() {
    $input = '01484825';
    $expected = 'or $t1, $t2, $t0';
    $temp = new MipsInstruction($input);
    $this->assertEquals($expected, $temp->getAssemblyCode());
}

resulting in:

FAILURES!
Tests: 3, Assertions: 3, Failures: 2

Once again, I’m making these pass the easy way first and can improve the code later once I know it works.

class MipsInstruction {
    private $inst;

    public function __construct($machineCode) {
        $this->inst = substr($machineCode, -1);
    }

    public function getAssemblyCode() {
        switch ($this->inst) {
            case '0':
                return 'add $t1, $t2, $t0';
            case '2':
                return 'sub $t1, $t2, $t0';
            case '5':
                return 'or $t1, $t2, $t0';
        }
    }
}

Now that all tests pass, it’s time to commit and I’m ready to start refactoring.

Powered by WordPress