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.
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.
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; } } ?>
This section describes specific features developped in CartoWeb for running tests, and infrastructure classes for more simple test case writing.
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.
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:
- 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.
-
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.
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.
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
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.