6.0.0-git
2024-03-28
Last Modified 2012-11-13 by Michael Slusarz

Anatomy of Horde Unit Tests

Filesystem structure of a test suite

The following tree shows a hypothetical arrangement of all element types that you might find in a Horde package:

horde/framework/Xyz/
`-- test
    `-- Horde
        `-- Xyz
            |-- AllTests.php
            |-- Autoload.php
            |-- bootstrap.php
            |-- fixtures
            |   `-- data.xml
            |-- Integration
            |   `-- IntegrationTest.php
            |-- phpunit.xml
            |-- Server
            |   |-- conf.php
            |   |-- conf.php.dist
            |   `-- ServerTest.php
            |-- SomeTest.php
            |-- Stub
            |   `-- Object.php
            |-- TestCase.php
            `-- Unit
                `-- UnitTest.php

We will go through the different elements below but lets first look at the hierarchy from the top level directory to the level of the AllTests.php file.

The top level directory horde represents the horde-git repository that everyone should be familiar with.

The majority of the test suites can be found in the framework area but several applications have their own test suites as well. Whether a framework package or an application: In both cases the test directory in the top-level directory of the component will contain the tests.

Below the test directory the code hierarchy of the component will usually be mirrored.

For a hypothetical framework package with name Horde_Xyz this means that where will be a directory Horde with a subdirectory Xyz. The latter one contains the tests. This matches the hierarchy in the lib directory where you will also find a Horde directory that usually contains a Xyz subdirectory. If not there will at least be an Xyz.php file.

For an application named xyz the test directory will only contain a directory Xyz.

This directory structure below test is just a convention and no functional requirement for the tests. At least at the moment. At some point the idea was that you would be able to unpack all PEAR package archives into one location without the file paths in the components conflicting with each other. But when we rely on PEAR for the installation now then the different test suites of package Horde_One and Horde_Two end up in tests/Horde_One and tests/Horde_Two respectively. So there is no chance for a conflict anyway. This might change at some point though. So we stick to the convention and ask anyone writing new test suites to do it as well.

AllTests.php

This file is a mandatory requirement for a Horde test suite. In almost every case you should use the boilerplate template found at framework/Test/doc/Horde/Test/template/packagetest/AllTests.php.

bootstrap.php

This file is a mandatory requirement for a Horde test suite. In almost every case you should use the boilerplate template found at framework/Test/doc/Horde/Test/template/packagetest/bootstrap.php. This file contains the code necessary to integrate the tests with the rest of the Horde suite (i.e. it sets up autoloading).

phpunit.xml

This file is a mandatory requirement for a Horde test suite. In almost every case you should use the boilerplate template found at framework/Test/doc/Horde/Test/template/packagetest/phpunit.xml.

Autoload.php

This file is not required . It's purpose is to setup additional PHP autoloading so that all tests in the test suite automatically have access to all the classes required for executing the tests. The default Horde_Test_AllTests already loads a basic autoloading definition that works for most framework components; this file should only be used if additinal autoloading is needed.

This file will be needed if you desire to autoload any helper class contained in the Test framework, since the default autoloader does not account for these files.

The content of Autoload.php

If you derive your test cases from a central test case definition you should load this one in Autoload.php as well:

/** Load the basic test definition */
require_once dirname(__FILE__) . '/TestCase.php';

Sometimes it makes sense to pull in the definition of test helpers that may be used throughout the test suite. They are usually not available via autoloading and need to be pulled in explicitely:

/** Load stub definitions */
require_once dirname(__FILE__) . '/Stub/ListQuery.php';
require_once dirname(__FILE__) . '/Stub/DataQuery.php';

Autoload mappings for applications

In case you test a horde application that may have special class name mappings when autoloading, you can define this via the {Horde_Test_Autoload::addPrefix()} call:

Horde_Test_Autoload::addPrefix('IMP', dirname(__FILE__) . '/../../lib/');

The class IMP_Imap would be loaded from dirname(FILE) . '/../../lib/Imap.php' in the example above.

Running the test suite

The default method for running the test suite of a Horde component is to run php AllTests.php on the command line.

You can also run individual tests by navigating to the base of the tests directory (the level of the directory containing AllTests.php), and running:

phpunit [SubDirectory1/SubDirectory2/]UnitTest.php