.. _mapscript_tests:

*****************************************************************************
 MapScript Unit Testing
*****************************************************************************

:Date: 2005/11/20
:Author: Sean Gillies

Test Driven Development
------------------------------------------------------------------------------

In 2003, I began to commit to test driven development of the mapscript module.
TDD simply means development through repetition of two activities:

  1) add a test, cause failure, and write code to pass the test
  
  2) remove duplication

Test Driven Development is also a book by Kent Beck.

New features that I develop for MapServer begin as test expressions. There are
a bazillion good reasons for working this way. The most obvious are

  1) accumulation of automated unit tests

  2) accumulation of excellent usage examples

  3) that i'm prevented from starting work on flaky ideas that can't be tested

About the tests
------------------------------------------------------------------------------

Tests are committed to the MapServer CVS under mapscript/python/tests. They
are written in Python using the JUnit inspired unittest module. A good
introduction to unit testing with Python is found at
http://diveintopython.org/unit_testing/index.html.

The test framework imports mapscript from python/tests/cases/testing.py.  This
allows us to test the module before installation

::

    [sean@lenny python]$ python setup.py build
    [sean@lenny python]$ python tests/runtests.py -v

Test cases are implemented as Python classes, and individual tests as class
methods named beginning with test*. The special setUp() and tearDown() methods
are for test fixtures and are called before and after every individual test.

Since version 4.2, MapServer includes a very lightweight testing dataset under
mapserver/tests. The set consists of symbols, fonts, three single-feature
shapefiles, and a test.map mapfile. This is the only data used by the unit
tests.

Many tests that require a mapObj derive from testing.MapTestCase::

    class MapTestCase(MapPrimitivesTestCase):
        """Base class for testing with a map fixture"""
        def setUp(self):
            self.map = mapscript.mapObj(TESTMAPFILE)
        def tearDown(self):
            self.map = None

One example is the MapSymbolSetTestCase, the test case I used for development
of the expanded symbolset functionality present in the 4.2 release::

    class MapSymbolSetTestCase(MapTestCase):
        def testGetNumSymbols(self):
            """expect getNumSymbols == 2 from test fixture test.map"""
            num = self.map.getNumSymbols()
            assert num == 2, num
        
        ...


Status
------------------------------------------------------------------------------

This unit testing framework only covers functionality that is exposed to the
Python mapscript module. It can help to check on pieces of the core MapServer
code, but is no guarantor of the :ref:`mapserv` program or of the :ref:`PHP
MapScript <php>` module. As of this writing, there are 159 tests in the suite.
These are tests of features added since mid-2003. Much of MapServer's older
stuff remains untested and it is doubtful that we'll make the time to go back
and fill in.