Grouping tests
Next up we will fill in some blanks and create a test suite.
Another test
Adding another test can be as simple as adding another method to a test case...
class TestOfLogging extends UnitTestCase {
function testCreatingNewFile() {
@unlink('../temp/test.log');
$log = new Log('../temp/test.log');
$this->assertFalse(file_exists('../temp/test.log'), 'Created before message');
$log->message('Should write this to a file');
$this->assertTrue(file_exists('../temp/test.log'), 'File created');
@unlink('../temp/test.log');
}
function testSecondMessageIsAppended() {
@unlink('../temp/test.log');
$log = new Log('../temp/test.log');
$log->message('Test line 1');
$messages = file('../temp/test.log');
$this->assertPattern('/Test line 1/', $messages[0]);
$log->message('Test line 2');
$messages = file('../temp/test.log');
$this->assertPattern('/Test line 2/', $messages[1]);
@unlink('../temp/test.log');
}
}
The assertPattern()
test case method uses Perl style regular expressions for
matching.
All we are doing in this new test method is writing a line to a file and reading it back twice over. We simply want to confirm that the logger appends the text rather than writing over the old file.
In fact this unit test actually passes straight away...
Log class test
With outrageous plagarism from JUnit,
SimpleTest has setUp() and
tearDown() methods
which are run before and after every test respectively.
File deletion is common to all the test methods so we
should move that operation there.
Our tests are green so we can refactor...
class TestOfLogging extends UnitTestCase {
function setUp() {
@unlink('../temp/test.log');
}
function tearDown() {
@unlink('../temp/test.log');
}
function testCreatingNewFile() {
$log = new Log('../temp/test.log');
$this->assertFalse(file_exists('../temp/test.log'), 'Created before message');
$log->message('Should write this to a file');
$this->assertTrue(file_exists('../temp/test.log'), 'File created');
}
function testSecondMessageIsAppended() {
$log = new Log('../temp/test.log');
$log->message('Test line 1');
$messages = file('../temp/test.log');
$this->assertPattern('/Test line 1/', $messages[0]);
$log->message('Test line 2');
$messages = file('../temp/test.log');
$this->assertPattern('/Test line 2/', $messages[1]);
}
}
The test stays green. We can add non-test methods to the test case as long as the method name does not start with the string "test". Only the methods that start "test" are run. This allows further optional refactoring...
class TestOfLogging extends UnitTestCase {
function setUp() {
@unlink('../temp/test.log');
}
function tearDown() {
@unlink('../temp/test.log');
}
function getFileLine($filename, $index) {
$messages = file($filename);
return $messages[$index];
}
function testCreatingNewFile() {
$log = new Log('../temp/test.log');
$this->assertFalse(file_exists('../temp/test.log'), 'Created before message');
$log->message('Should write this to a file');
$this->assertTrue(file_exists('../temp/test.log'), 'File created');
}
function testSecondMessageIsAppended() {
$log = new Log('../temp/test.log');
$log->message('Test line 1');
$this->assertPattern('/Test line 1/', $this->getFileLine('../temp/test.log', 0));
$log->message('Test line 2');
$this->assertPattern('/Test line 2/', $this->getFileLine('../temp/test.log', 1));
}
}
It is a matter of taste whether you prefer this version to the previous one. There is a little more code, but the logic of the test is clearer.
A test suite
A test case does not function alone for very long. When coding for real we usually want to run as many tests as quickly and as often as we can. This means grouping them together into test suites that could easily include every test in the application.
Firstly we create a test suite called all_tests.php in the tests folder...
<?php
require_once(dirname(__FILE__) . '/simpletest/autorun.php');
require_once('log_test.php');
class AllTests extends TestSuite {
function __construct() {
parent::__construct();
$this->add(new TestOfLogging());
}
}
?>
We hardly notice the difference when things work...
All tests
In the next page we will add these more quickly.




