====== Introducing AkUnitTest ======
===== The Small Picture =====
===== Hello World =====
Akelos uses the unit testing framework [[http://www.lastcraft.com/simple_test.php|simpletest]] for running unit tests. You don't need to download simpletest apart, as it is integrated into your Akelos installation.
By using the command **./script/test path/to/your/test**, you can run your tests easily.
Let’s show you a really basic test, and then we’ll step through it and explain some details.
In the file ./test/hello_test.php
assertTrue( true );
}
}
?>
Quite possibly the simplest and least useful test ever invented, but it shows you the bare bones of writing a test case.
Simply run **./script/test hello_test.php** from your application directory and you will see the following:
HelloTestCase
OK
Test cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 0
/Volumes/Files/Sites/blog/test/hello_test.php
Congratulations, your first test. Reach behind you and pat yourself….. (no, not there, on your back).
===== What Does It All Mean? =====
By looking at the output of a test, you will be able to tell if the tests pass or not. In our example, not surprisingly, we’ve passed. The summary shows **Test cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 0**.
So, let’s break our test source code down.
The classes and functionality to write and run unit tests is provided automatically by **./script/test**
First, we have a class **HelloTestCase** which derives from **AkUnitTest**.
class HelloTestCase extends AkUnitTest{
//...
}
All of the tests that you create will directly subclass **AkUnitTest**. By convention test case classes should end in TestCase for the **./script/test** to run it automatically.
Finally, we have a method called **test_hello**.
function test_hello(){
// ...
}
All tests must follow this naming convention: **their names start with the first 4 characters test**, as in test_hello, testme, and testarosa. If you create a method that doesn’t start with test, the testing framework won’t recognize it as a test, hence, won’t run it automatically, hence it is a normal PHP method.
Inside our **test_hello** method, we have an assertion.
$this->assertTrue( true );
Assertions are where the real work gets done. There are a whole army of different types of assertions that you’ll use to make sure your code is doing the right thing.
===== The Big Picture =====
Grab a cup of coffee and dunk your head in some ice water, because here’s some more theory.
There are 4 major players in the testing game.
===== 1. Assertions =====
An **Assertion** is 1 line of code that evaluates an object (or expression) for expected results.
For example, is this value = that value? is this object null? does this line of code throw an exception? is the user’s password greater than 5 characters?
Akelos assertions are the same as those available in [[http://simpletest.org/en/unit_test_documentation.html|simpletest]]
* assertTrue($x) Fail if $x is false
* assertFalse($x) Fail if $x is true
* assertNull($x) Fail if $x is set
* assertNotNull($x) Fail if $x not set
* assertIsA($x, $t) Fail if $x is not the class or type $t
* assertNotA($x, $t) Fail if $x is of the class or type $t
* assertEqual($x, $y) Fail if $x == $y is false
* assertNotEqual($x, $y) Fail if $x == $y is true
* assertWithinMargin($x, $y, $m) Fail if abs($x - $y) < $m is false
* assertOutsideMargin($x, $y, $m) Fail if abs($x - $y) < $m is true
* assertIdentical($x, $y) Fail if $x == $y is false or a type mismatch
* assertNotIdentical($x, $y) Fail if $x == $y is true and types match
* assertReference($x, $y) Fail unless $x and $y are the same variable
* assertClone($x, $y) Fail unless $x and $y are identical copies
* assertPattern($p, $x) Fail unless the regex $p matches $x
* assertNoPattern($p, $x) Fail if the regex $p matches $x
* expectError($x) Swallows any upcoming matching error
* assert($e) Fail on failed expectation object $e
===== 2. The Test =====
A **Test** is method that contains assertions which represent a particular testing scenario.
For example, we may have a test method called test_valid_password. In order for this test to pass, we might need to check a few things:
* password is 4 or more characters
* password isn’t the word ‘password’
* password isn’t all spaces
If all of these assertions are successful, the test will pass.
===== 3. The Test Case =====
A **Test Case** is a class inherited from **AkUnitTest** containing a testing “strategy” comprised of contextually related tests.
For example, I may have a test case called UserTestCase which has a bunch of tests that check that:
* the password is valid (test_password)
* the username doesn’t have any forbidden words (test_username_cussin)
* a user is under the age of 150 (test_shriveled_raisin)
===== 4. The Test Suite =====
A **Test Suite** is a collection of test cases. When you run a test suite, it will, in turn, execute each test that belongs to it.
For example, instead of running each test unit individually, you can run them all by creating a suite and including them. This is good for stuff like continuous-build integration.
We won’t get into test suites in this article.
===== The Hierarchy =====
The relationship of these objects to one-another looks like this:
* a test suite
* has many test cases
* which have many tests
* which have many assertions
[[123-testing|previous]], [[hello-world-on-steroids|next]]