< Code Convention

Code Documentation >

7. Unit Tests

7.1. Introduction

Unit tests are an important componant in the CartoWeb development environment. The framework used for unit testing is based on PHPUnit2, a PEAR package. For more informations abouth PHPUnit2, see http://pear.php.net/reference/PHPUnit2-2.0.3/

PHPUnit2 is included in the libraries shipped with CartoWeb. Thus, no installation is needed to run and write new tests.

7.2. Writing Tests

Information about writing tests for CartoWeb can be separated into two parts. First part about writing Unit tests in general, useful for people new to PhpUnit. Then a part more specific about the infrastructure which is available in CartoWeb for writing tests.

7.2.1. General Information About Writing Tests

Test cases are located in directory tests for testing the core of CartoWeb and in the directories <project>/tests for for tests specific to project <project>. Inside these tests directories, path hierarchy mirrors the existing hierarchy they are testing. For instance, the tests hierarchy for the core CartoWeb testing is the following:

client
    CartoclientTest.php
    CartoserverServiceTest.php
    AllTests.php
common
    BasicTypesTest.php
    AllTests.php
coreplugins
    AllTests.php
    ...
plugins
    AllTests.php
    ...

For the test_main project, the hierarchy is the following:

coreplugins
    AllTests.php
    ...
plugins
    AllTests.php
    ...
misc
    AllTests.php
    < misc tests >
    ...
...

Each directory including tests root directory has a file named AllTests.php. This is called a test suite. It is used to run all tests of a specific directory (ie "package").

Warning

All test case and test suite classes must have the name of their file relative path without extension, with '/' replaced by '_'. For instance, class client_CartoclientTest file name must be <cartoweb3_root>/tests/client/CartoclientTest.php.

The following example shows a test in common/BasicTypeTest.php file:

Example 7.1. Simple test case (BasicTypesTests.php)

<?php
require_once 'PHPUnit2/Framework/TestCase.php';
require_once(CARTOWEB_HOME . 'common/basic_types.php');

class common_BasicTypesTest extends PHPUnit2_Framework_TestCase {

        public function testBboxFrom2Points() {

                $bbox = new Bbox();
                $point1 = new Point(12, 34);
                $point2 = new Point(56, 78);
                $bbox->SetFrom2Points($point1, $point2);

                $this->assertEquals(12, $bbox->minx);
                $this->assertEquals(34, $bbox->miny);
                $this->assertEquals(56, $bbox->maxx);
                $this->assertEquals(78, $bbox->maxy);
        }
}
?>

Each function with name starting with 'test' will be considered as a test case by the automated test runner. You may also want to use functions setUp() and tearDown() to initialize and clean a test environment.

Method assertEquals tests if two values have the same values. If not, the test will be added to the final report as failure.

As stated previously, all test classes have to belong to a test suite. The next example shows how such a test suite is built, by grouping all tests together in the suite() method.

Example 7.2.  Test suite (AllTests.php)

<?php

require_once 'PHPUnit2/Framework/TestSuite.php';
require_once 'CartoclientTest.php';
require_once 'CartoserverServiceTest.php';

class client_AllTests {

        public static function suite() {

                $suite = new PHPUnit2_Framework_TestSuite;

                $suite->addTestSuite('client_CartoclientTest');
                $suite->addTestSuite('client_CartoserverServiceTest');

                return $suite;
        }
}
?>

All test suites are then grouped together into the root test suite. It is shown there for information.

Example 7.3.  Root directory's AllTests.php:

<?php

require_once 'PHPUnit2/Framework/TestSuite.php';
require_once 'client/AllTests.php';
require_once 'common/AllTests.php';

class AllTests {

        public static function suite() {

                $suite = new PHPUnit2_Framework_TestSuite;

                $suite->addTest(client_AllTests::suite());
                $suite->addTest(common_AllTests::suite());

                return $suite;
        }
}
?>

7.2.2. Specific Information for Tests

This section describes specific features developped in CartoWeb for running tests, and infrastructure classes for more simple test case writing.

7.2.2.1. HttpUnit Based Tests

To test features of the cartoclient, the HttpUnit software is used. It is written in Java, and there is no Php port. The http unit tests are run if you have a JVM in you path.

For more information about running HttpUnit tests, see the tests/client/httpunit/README file in the CartoWeb distribution.

7.2.2.2. Testing CartoWeb Plugins

Plugins are a main component in CartoWeb architecture. That's why there is support to maintain common code used for testing plugins. As described in Section 7.2.1, “General Information About Writing Tests” the tests for plugins have to mirror the file hierarchy of the base application. That's why there are coreplugins and plugins directories where test for core plugins and plugins are stored respectively.

Note

Tests are also available for projects. So, to test a plugin in a project, the path of the test will be <cartoweb3>/<projectname>/tests/plugin/<pluginname>

Testing plugins is separated into two tasks:

  1. Locally testing client, common or server classes. For plugin client classes, it requires a CartoClient environment available, and identically a CartoServer environment for testing server classes.
  2. Remote plugin tests, throught the webservice API. This kind of tests are related to the server plugins, that's why we chose to put them in the server folder of plugins.

For the first point mentionned above, general Unit tests rules apply, as described in Section 7.2.1, “General Information About Writing Tests”.

For the second point stated, a help class named client_CartoserverServiceTest can be extended by the testing classes. In turn, client_CartoserverServiceTest extends other classes which offer additional helpful methods. For the complete list of available methods, please have a look at the generate API docs (as more may be added in future). The main useful methods are createRequest() for initializing a new request, getMap() for lanching the request.

Tip

Having a look at an existing plugin test case is the best starting point for writing new tests.

7.2.2.3. Tests for projects

Each CartoWeb project can have its set of tests directly inside the project, in a directory tests. Inside this directory, you have to use the same hierarchy as in the main tests directory.

Inside these tests directories, the same mechanism is used for testing as the main tests directory. The best way to get started is to have a look at the test_main project for a starting point.

7.2.2.3.1. Invoking tests for a specific project

For now, only the command line can be used for invoking tests for a specific project. An environment variable CARTOWEB_TEST_PROJECT can be used to define which test to launch. Under a Unix like shell enviroment, the command line to use is:

CARTOWEB_TEST_PROJECT=<myproject> <php-bin> phpunit.php projects_AllTests projects/AllTests.php

7.3. Running Tests

Unit tests are runned using the command line interface (CLI). To run a test case or a test suite, type the following command in directory <cartoweb3_root>/tests:

<php-bin> phpunit.php <test-class> <php-file>

Where <php-bin> is the PHP binary, <test-class> is the name of the test class (AllTests, client_AllTests, client_CartoclientTest, etc.) and <php-file> is the name of the PHP file containing the test case (client/CartoclientTest.php).

Result should look like this:

PHPUnit 2.0.3 by Sebastian Bergmann.

.......F.....

Time: 0.0410950183868
There was 1 failure:
1) testpointtobbox
expected same: <113> was not: <123>
/home/yves/cartoweb3-proto2/tests/common/BasicTypesTest.php:59
/home/yves/cartoweb3-proto2/tests/phpunit.php:24

FAILURES!!!
Tests run: 12, Failures: 1, Errors: 0, Incomplete Tests: 0.
Content-type: text/html
X-Powered-By: PHP/5.0.1

In this case, 12 tests were run with one failure.

valid xhtml 1.0 valid css