Monday, November 20, 2006

Error testing in your software


When you write methods, you should:

  • throw an exception with public method when preconditions or postconditions of the exposed contract fail

  • use assertions to verify nonpublic method's preconditions and postconditions. For example:
    /* Set coordinates of image i in layout */
    void setImageLayout(const Image& i, const int point[]) {
    /* Preconditions: image already loaded and displayed
    * and coordinates are within bounds */
    assert(i.isLoaded() && i.inLayout());
    assert(point[0] >= 0 && point[0] <= Window::WindowLimit);
    assert(point[1] >= 0 && point[1] <= Window::WindowLimit);

    /* Set layout */
    layout_->setImage(i,point);

    /* Postconditions: image layout updated */
    assert(i.isUpdated());
    }
    Assertions are usually implemented so that they can be enabled or disabled. If assertions are disabled, assertion failures are ignored. When the program is released, they are often disabled (while exceptions of public methods continue their checking work...)

  • use unit test to validate that a particular module of source code is working properly from each modification to the next.
    Extreme Programming states "Code the Unit Test First": in development cycle you'll write tests, code, tests, code, tests, code, ...
    You can use many tools like JUnit, TestNG, CUnit or CPPUnit.

Remember this is important rule: A test is not a unit test if:
  • It talks to the database (try a look for DbUnit)
  • It communicates across the network
  • It touches the file system
  • It can't run at the same time as any of your other
    unit tests
  • You have to do special things to your environment
    (such as editing config files) to run it
  • You are not testing a class in isolation from other
    concrete classes: constructs such as mock objects can assist in separating unit tests (with tools like EasyMock and mockpp)

No comments: