Test-driven development
Outlast Framework fully supports and encourages test-driven development (TDD). This is especially important if you are developing on the plugin- or system-level as here any change could break several dependent applications or plugins.
OFW tests are based on the super-small Enhance unit testing framework, so its API is identical to it. In addition it is integrated fully into the framework as follows…
Basic steps of creating a test
- Create a folder
/app/test/
- Add a file named
example.test.php
and use the following contents. The class name can be anything, but needs to be unique project-wide:<?php /** * A standard unit test example. **/ class ExampleTest extends zajTest { public function example_that_will_pass(){ $a_variable = true; zajTestAssert::isTrue($a_variable); } public function example_that_will_fail(){ $a_variable = false; zajTestAssert::isTrue($a_variable); } }
- Once the file is saved, the test can be run by going to
http://example.com/update/test/
The update menu will run all of the tests for the entire project.
Setting up, tearing down
You can set up and the break down testing data using the special setUp()
and tearDown()
methods.
You can explicitly return false
from your setUp()
method which will skip the tests. Note that the tearDown()
method will still be called (only logical, given that setUp()
was also called).
Assertions
The assertions api is identical to that of the Enhance framework. We chose this framework because it’s a stand-alone, single-file, really simple implementation that covers all of the basics. Of course, you can create a plugin to use any other testing framework if you prefer.
So let’s see the assertions detail:
- Type assertions are available:
isArray
,isNotArray
,isBool
,isNotBool
,isFloat
,isNotFloat
,isInt
,isNotInt
,isNumeric
,isNotNumeric
,isObject
,isNotObject
,isScalar
,isNotScalar
,isString
,isNotString
areIdentical($expected, $actual)
– passes if type and value is sameareNotIdentical($expected, $actual)
– passes if type or value are differentisTrue($actual)
– passes if boolean trueisFalse($actual)
– passes if boolean falsecontains($expected, $actual)
– passes the actual string contains the expected stringnotContains($expected, $actual)
– passes the actual string does not contain the expected stringisNull($actual)
– passes if actual value is nullisNotNull($actual)
– passes if actual value is not nullisInstanceOfType($expected, $actual)
– passes if actual value is an object of type expectedisNotInstanceOfType($expected, $actual)
– passes if actual value is not an object of type expectedisNotInstanceOfType($expected, $actual)
– passes if actual value is not an object of type expected
You can also test logic:
fail()
– will fail every time, you could use this after some custom logic to fail a testinconclusive()
– This call will fail every time – it indicates that a test should fail or has not yet been implementedthrows($someClass, 'MethodName')
– this expects a thrown exception, so it fail if an exception is not thrown by the targetthrows($someClass, 'MethodName', array(2, 'Arg2', 5))
– same as above but passing arguments
Throwing notices
In addition to failing outright, your tests can also throw notices. This is useful to notify the developer of deprecated functionality or other non-essential recommendations.
You can throw notices within any of your testing methods by calling the test library’s notice method:
$this->zajlib->test->notice("Something is not right in your code because it calls this and that. You should fix it!");
Keep in mind that notices are displayed outside of their context and do not refer back to either the test name or the line number. You need to add this information in your notice message (if it is needed).
Catching errors during test
You can test OFW errors ($this->zajlib->error()) by temporarily disabling them. You can use surpress_errors_during_test
to turn error surpression on or off and get_last
to get the text of the last error.
Take the following function:
function an_error_occurs(){ return $this->zajlib->error("An error!"); }
During your test, you can surpress errors and then get the last error message to verify if you got that message during the execution:
function a_test(){ // Surpress errors $this->zajlib->error->surpress_errors_during_test(true); // Run a test an_error_occurs(); // Check the last error, this test will pass! $last_error = $this->zajlib->error->get_last('error'); zajTestAssert::areIdentical("An error!", $last_error); }
Important! Any surpression will only apply to the current test – even if you do not turn off surpression it will be turned off at the end of your current test function.
Examples
For real-world examples, take a look at the tests found in the system folder under /system/app/test/*.test.php
.