next up previous index
Next: Unit Tests that Use Up: Programming in Opus and Previous: Creating Your Own Opus   Index


Unit Tests

This section describes how Opus developers write unit tests for Opus code. One of the goals of the Opus project is to practice test-driven development, wherein we write tests before we write any code. This practice is becoming increasingly common, since it has many advantages including dramatically increasing the ability to change code without breaking code.

In general, each Opus module includes just two classes: a class defining the functionality of this module, e.g. MyClass, and a test class containing unit tests of MyClass. The contents of this module are structured like this:

#
# UrbanSim software. Copyright (C) 1998-2007 University of Washington
#
# You can redistribute this program and/or modify it under the terms of the
# GNU General Public License as published by the Free Software Foundation
# (http://www.gnu.org/copyleft/gpl.html).
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE.html for copyright
# and licensing information, and the file ACKNOWLEDGMENTS.html for funding and
# other acknowledgments.
#

... imports ...

class MyClass:
    .... methods for this class ...

from opus_core.tests import opus_unittest
class MyClassTests(opus_unittest.OpusTestCase):
    ... test methods ...

if __name__ == '__main__':
    opus_unittest.main()

The file starts with the required GPL header. Then some imports. Then the MyClass class, followed by the test class whose name is the name of the primary class followed by ``Tests''. Finally, the last two lines will cause the unit tests to be run if this module is invoked directly by Python.

Test classes should derive from opus_unittest.OpusTestCase in order to ensure that the test runs in a "clean" environment. In particular, OpusTestCase removes all singletons before and after each test, so that a singleton created by one test will not accidentally be used by another test.

OpusTestCase also provides the following helper methods:

assertDictsEqual(first, second, *args, **kwargs)
This is like the normal assertEqual, except that it also works for Python dictionaries that may contain numpy data.
assertDictsNotEqual(first, second, *args, **kwargs)
This is like the normal assertNotEqual, except that it also works for Python dictionaries that may contain numpy data.

Tests that are defined in this manner will be automatically found and run by the all_tests module when it is executed. Please ensure that the test case class (e.g. MyClassTests) is found outside of the if __name__ == '__main__': check, otherwise the tests will not be found.

For more examples, check out the files in the opus_core package.



Subsections
next up previous index
Next: Unit Tests that Use Up: Programming in Opus and Previous: Creating Your Own Opus   Index
info (at) urbansim.org