A good automated testing strategy is crucial to keeping our applications maintainable.
The framework provides a testing structure suite to get you on the right track
setting up tests. Test files are stored under the
The framework refers to two different groups of tests. Unit Tests for our models,
and Functional Tests for our controller and views. As you create stubs for your
models and controllers using
script/generate, the framework will
automatically create corresponding test stubs.
Our testing framework is built on PHPUnit and
this must be installed on your system. To check if PHPUnit is installed properly,
phpunit --version command:
$> phpunit --version PHPUnit 3.2.0beta9 by Sebastian Bergmann.
If the output does not look similar to the above and indicate version 3.2 or greater, please see the installation instructions in the PHPUnit Manual.
Running a Single Test¶
You can run any single test file in the
$> cd /your-application/test/unit $> phpunit DocumentTest
The above will run only the tests that have been written for the Document model. It may take a few seconds and should display output that is similar to:
PHPUnit 3.2.0beta9 by Sebastian Bergmann. .......... Time: 16.990113019943 OK (10 Tests) $>
Each dot represents a passed test. If there are any Failures or errors, they will
be represented by
E respectively with a message describing what went wrong:
PHPUnit 3.2.0beta9 by Sebastian Bergmann. F......... Time: 11.186962842941 There was 1 failure: 1) testFindByPk(DocumentTest) expected <1234> but was: <0> ../your-application/test/unit/DocumentTest.php:47 ../vender/Mad/Test/Unit.php:125 FAILURES!!! Tests run: 10, Failures: 1, Errors: 0, Incomplete Tests: 0. $>
We are given a wealth of information to fix what went wrong including the name of the test that failed, the value we expected in our test assertion, and the backtrace of the error.
Running All Tests¶
All of the tests for your application are located in the
under you application’s root directory. To run all of the tests, change to the
test/ directory and run
$> cd /your-application/test $> phpunit AllTests.php
Running a Test Group¶
Tests are organized into two groups: unit tests and functional tests.
When you run
AllTests.php as shown above, it will run all tests
in both groups.
It is often convenient to run all of the tests of a particular
group, e.g. just the unit tests or just the functional tests. You
can do this with the
--group switch for PHPUnit:
$> cd /your-application/test $> phpunit --group unit AllTests
Populating the Database¶
A fixture is the system’s state before the test is performed. We set this up by loading sample data into the database for the test to perform. This sample data is loaded before the test and then cleared out at the end of the test. This ensures that no test will have an effect on the operation of a different test.
YAML (Rhymes with “camel”) is our preferred method
for loading test data. The YAML fixture files can be found in
and should end with a
YAML is great because it is very readable. YAML is formatted using a few simple guidelines. Note that spacing is important (2 space indents, no tabs).
# a comment in YAML format
A Mapping is a key associated with a value:
String: Any string of characters Int: 12 Boolean: true Null: NULL Float: 3.43
A Sequence is a list of items:
- item 1 - item 2 - item 3
An Inline Sequence is a shortcut for writing a sequence when your values consist of only one word:
[item1, item2, item3]
A Mapping of a Sequence:
teardown: - do this first - do this second - do this third
A Mapping of an Inline Sequence:
requires: [folders, documents]
A Mapping of a Mapping:
public: id: 1 parent_id: 0 name: Documents path: ./Documents
Our fixtures are by convention named after the table in which they are inserted. So in
the simplest form, inserting two records into the folders table would look like the
following and would be in
public: id: 1 parent_id: 0 name: Documents path: ./Documents private: id: 2 parent_id: 1 name: Private path: ./Documents/Private
This fixture would load two records into the database, but also make the yml records accessible within the test itself by their respective names (public/private). It is important to name each record with a unique name.