Node: Introduction, Next: , Previous: Top, Up: Top



Introduction

What is a Unit Test?

A unit test is a small bit of code designed to exerise a small part of your program to confirm a desirable result. The unit test will expect to be in an environment with some code to invoke, data to use and assertions that will record errors to be reported later, if any.

Unit testing is a part of the Extreme Programming "anti-methodology". Extreme Programming1 (from now on abbreviated as XP in this manual) moves away from the complicated methodologies by reducing the number of rules and processes that developers must adhere to to a core collection of rules (that can be broken.)

Why should we use Unit Tests?

Benefits to Developers

The software developers are the ones burdened with the responsibility of creating new functionality in programs. It's often demanded that new functionality doesn't destroy old functionality. Developers will label releases with keywords to inform users of a subjective opinion of the status of the software. With unit test suites in place, the developers can place an objective label on the software they release.

Some of the benefits of unit testing include:

  1. Improve source code control.

    A single developer may forget what the state of the source tree is in. Multiple developers need methods to reduce the overhead of communication between each other to avoid misunderstandings and ommissions. When all developers follow a protocol of unit testing, bad source code is never checked into the source repository.

  2. Compilation and/or Parse Testing.

    Unit tests provide a way to quickly determine if the source tree even compiles or is parsable by the interpreter. If the unit tests fail to even compile or link, that's a warning to the developers that something is amiss.

  3. Regression testing.

    As software ages, features are added and bugs are fixed. Unit tests provide a safety net for catching unwanted side-effects that sometimes occur during maintenace or addition of features.

  4. "Example code" overhead eliminated.

    New developers will appreciate having example code to read and learn from as they get familiar with a new source tree. Experienced developers usually resent having to write this code and sometimes let it lag behind the true functionality of the system. Developers instead can stop writing "example programs" and instead just write tests- the end result is new developers have working examples that never mislead them because there's never "old code" in the tests.

  5. Release qualification simplified.

    When all tests pass, it's a simple matter of the developers deciding to make a new release when they believe they have enough new functionality.

Benefits to Consumers

  1. Release evaluation simplified.

    Users can run the tests to see if they pass. If users want to know more about how the software is designed, they can have someone read the tests to "audit" them to see if they are covering functionality of the software in a satisfactory way.

  2. Bugs rarely come back.

    When bugs are found, the origninal developers can add new unit tests to the software to confirm when the bugs are fixed, and leave those unit tests there to ensure that they do not return in later releases.

How do you write a Unit Test?

Unit tests are easy to write once you understand that the object of the test is not to "test your program" but to test small parts of your program. I tend to test "accessors" and "gettors" methods in my interactive scripts as I often cut and paste code (a bad habit), and forget to change some identifiers. For this kind of test, I create the data structure I'm working with and then apply the function on it that I want to test. Then I use the "accessor" function to retrieve the data that I put into the data structure, and craft an expression for au_assert() to record an error if there's a problem.

In psuedocode:

     TEST_GENERIC_GET_AND_SET
             create test_data
             test_data->setValue("some value")
             au_assert("get and set",
                       "getValue returns different value than expected",
                       (test_data->getValue() equals "some value")
                      )
             release test_data
     END_TEST
     

Later we will move the "create test_data" and "release test_data" out of the test into setup and teardown functions, reducing code duplication.

How do you organize your Unit Tests?

Running each unit test by hand would quickly become a big headache in any practical project. Each test then can be aggregated into a test case, and each test case itself can be made part of a suite. This suite then runs and reports on the tests for you.

Hand Coded Suites

As of version 0.07, all suites are essentially hand-coded.

Automatically Generated Suites

In the future, I want to create a suite-generator engine that will scan program sources and automatically generate suites to run the tests found in the sources. This same program is not far off from making an "auditing" program that developers and end-users can use to evaluate how well the unit-test coverage is in a program.

How do you run your Unit Tests?

There are two major project building systems that are freely available on the Internet

Within GNU Automake Managed Sources

The invocation of make check should cause the software to compile and run the test suites for the software.

Within Aegis Managed Sources

[to be determined.]

How long should it take to run all my Unit Tests?

Unit tests for a package should not take more than a few seconds to run. To fully understand why, you need to read the next section.

When are Unit Tests run?

As a Developer

Unit tests are run practically continuously. A developer uses the tests to check to see if any changes they made broke any other part of the system. In a project managment system like Aegis, you cannot go for long without running tests to ensure that your source base is on solid ground.

As a Consumer

The consumer may want to download your program, compile it, and check to see if it does all the things you claim it does. They do not want to wait a long time to evaluate the software. Being able to see an OK result nearly instantly saves the consumer time.


Footnotes

  1. A full exposition of Extreme Programming can be found at <http://www.extremeprogramming.org> and will not be discussed at huge length in this manual.