This page used to convey wrong information, below is the new version, which explains how Cake tests are run: there is a test suite in the Cake SVN trunk that is used for testing.
Excuse us while we rewrite this text.
(This tutorial is in a very early stage. Please contribute if you know something in this area!)
Testing Cake applications
In this tutorial we will show you how to test a Cake application. We will set up the software necessary for testing, and then do a simple unit test (aka programmer test). Read the upcoming functional_testing_cake_apps for more on functional testing (aka user testing).
Let’s start with the configuration.
Configuration
Install Cake's Test Suites
- Check out the test-cases from
trunk/test_suites/0.10.x.x/, using your favourite Subversion client. - Or download it from: http://cakeforge.org/frs/?group_id=62
Install Simpletest (http://www.lastcraft.com/simple_test.php)
- How to install simpletest: Unpack simpletest in the vendors directory of your CakePHP installation.
- For just the files: Sourceforge project page for SimpleTest
Configure your app's test suites
- Move all the test_suites items in
appto your application, and place the files in the folders where they belong to. If you use a non-standard cake installation, i.e. you have editedapp/webroot/index.php, you have to editapp/webroot/test/index.php, too. - Visiting the now installed
/tests/sub-application of your Cake install gives you the Cake testing interface. (So,testsis both a sub-application, and a controller in your application.)
Configure your database for testing
If you want to use a special database configuration for testing purposes, you have to add the following code snippet to your app/config/database.php:
function __construct () { if (strstr($_SERVER['REQUEST_URI'], '/tests')) { $this->default = $this->test; } }
Naming conventions
All test cases should have the file suffix .test.php.
Example: controller.test.php
All group tests should have the file suffix .group.php.
Example: controller.group.php
First test!
So, let’s start with a _simple_ test-case. We are going to test the Inflector::singularize library method, with a word we know how to singularize. The method’s in /cake/libs/inflector.php, but we just need to know that it returns a string with the given word in singular.
To write a test for this method, we start by subclassing the SimpleTest class UnitTestCase:
<?php class SingularizeTestCase extends UnitTestCase { } ?>
Now, we include the code we want to test:
<?php uses("inflector"); // Include external code to test. //(This could be a normal require(), but this is a library, so we use uses() class SingularizeTestCase extends UnitTestCase { } ?>
Finally, we write a method on this testcase that asserts some state:
<?php uses("inflector"); // Include external code to test. class SingularizeTestCase extends UnitTestCase { /** * Tests whether "monkey" is returned from singularizing "monkeys". */ function testSingularizingMonkey() { $a = Inflector::singularize("monkeys"); $this->assertEqual( "monkey", $a ); } } ?>
Execute your test
You can execute your tests in two ways: on the one hand you can run them inside of the Cake framework with /yourapp/tests, or, on the other hand, you can run them outside of the Cake framework with /yourapp/tests/index.php.
NOTES:
Olle: Since I am running my Cake app in a subfolder, I had to edit some absolute paths in the application tests, to get the CSS and the graphics from my application. When that was done I could add a test case at /tests/app/controllers/products_controller.test.php, which I was able to run. All the paths for the links I also edited.
Other asserts
Refer to the API docs for SimpleTest to see the long list of asserts we can perform in the test methods. SimpleTest API documentation. More specifically, we want to look at the Unit tester tutorial part of the API docs.
| 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 |
| assertCopy($x, $y) | Fail if $x and $y are the same variable |
| assertWantedPattern($p, $x) | Fail unless the regex $p matches $x |
| assertNoUnwantedPattern($p, $x) | Fail if the regex $p matches $x |
| assertNoErrors() | Fail if any PHP error occurred |
| assertError($x) | Fail if no PHP error or incorrect message/expectation |
| assertExpectation($e) | Fail on failed expectation object |
Resources
Article by SimpleTest’s author: Coding a login box shouldn't hurt