Saturday, February 18, 2012

A Super Simple PHP class for Unit testing

Since I was introduced to unit testing and test-driven development, I have become a big fan. Since most of my projects to date have been primarily PHP, I prefer PHPUnit as my unit testing framework.

To me the best part of unit testing is that good unit tests are quick, automated confirmation that everything is working as expected. Using test-driven development I can write a test to ensure that given a certain input my future code will return a given output. I often find writing my tests first also helps define what I want my application to do, it is an outline of what the code should do.

Then as I write my code, I can run the test often to ensure that I don't get false positives and it will also point out any syntax errors or typos in my code.

Recently I found myself without my trusty testing tool and without internet at the time to download it. I was about to enter Facebook's HackerCup and needed to be sure my answers were correct before submitting them. So I ended up writing a quick, very simple unit testing base class for my submissions. I call it jphpunit because it is my version of a php unit tester and I based much of how it is used and the output it generates on my experience with PHPUnit.

It only has one class, jphpUnit, and one external method, assertEquals($expected, $actual, $message = NULL).

Here is a quick sample of one of the unit tests I wrote using it for my HackerCup submissions. When working on the problems, I would copy and save the example input and output files to run a basic test on.
<?php /** * alphabet_soup_test.php */ require_once('helpers/alphabet_soup_generator.php'); class alphabet_soup_test extends jphpunit { public function testExample() { $fixture = file_get_contents('data/example_output.txt'); $output = array(); exec('../alphabet_soup.php data/example_input.txt', $output); $this->assertEquals($fixture, implode("\n", $output)); } public function testGenerated() { $gen = new alphabet_soup_generator(); $fixture = $gen->getCorrectAnswer(); $input = $gen->saveFile(); $output = array(); exec('../alphabet_soup.php '. $input, $output); $this->assertEquals($fixture, implode("\n", $output)); } }
As you can see, I wrote a test that would generate other test cases based on the contraints of the problem to ensure my program met all contraints of the problem and not just the ones in the example. I will probably talk about this more in one of my next posts.

No comments: