====== 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]]