1030: General Testing Tips

Tim Brecht

Relevant for Assignment 1 and all assignments

Remember that when it comes to testing three things should
come to mind and should be explained to the reader of the tests:
   0) How can I perform an intelligent test with the least amount of
      output possible?
   1) What is the expected output?
   2) What is the observed output?
   3) Is the observed output the same as the expected output?
      Why and/or why not?
Here are some general rules of thumb that you should consider when
designing, implementing and running your tests (e.g. tester.dem).

0)  Think. 
   Think about how to automate as many test procedures as possible.
   Ideally you should be able to write test programs that only 
   produce one line of output - either stating that the test succeeded
   or that it failed and where it failed.

   One way of doing this is to make extensive use of the Turing assert
   statement.  Recall that an assert statement in OOT automatically
   stops the program with useful information as to which statement
   failed and the cause of the failure.

   You must reason about the state of the testing program and the
   state of underlying modules being tested.  Assuming that the
   modules being tested are functioning correctly, what statements must
   be must be true at key points in the testing program and in the underlying
   modules. Add assert statements at these points in these programs
   to test these assumptions. The goal is
   to insert enough useful assert statements so that if all the
   assertions pass, then we have strong evidence that the program
   is correct. Note that we can never be sure that we have not missed a
   bug.

1) Someone should be able to spend about 1 minute looking at the output of
   each test program to determine whether all of the tests in the program
   failed or succeeded.

   If the reader of the program is required to trace through pages and
   pages of output then the test is essentially useless.

2) Consider to whom you are trying to demonstrate your program (i.e.,
   think about the marker).  What type of and how much information will
   they want to see in your testing?

   For example, pretend that you are the project leader working in a large
   company. Once a month there is a large meeting of technical staff in
   which each of the project leaders has 10 minutes to give a status report
   on their project. This means that you have 10 minutes to demonstrate
   using the output of your testing what parts of your project do and
   do not work correctly.  (Remember showing what does NOT work is just as
   important as showing what does work - perhaps more so).

3) Be smart about your testing. If the program you write which performs
   your tests (your test program) is more than 3 or 4 pages long it is
   likely too long. If the output produced from running the test program is
   more than 2 or 3 pages your test program is probably
   not designed very well. Think about the number of different things
   that need to be tested and how much time it will take to look at the
   output. A good test program should demonstrate simply and easily
   that the program does or does not work using minimal output.

4) Even though the test program is written only for the purpose of
   testing the implementation of other modules, classes or programs, it
   still needs to be clear, concise, and documented. In particular, the
   test program should specify what values you expect it to return
   (this can be done using comments where needed).

5) The test program should be bug free. Take some time when writing the
   test program to ensure that it is correct. Too often people waste a
   bunch of time trying to fix the modules they are working on when in fact
   the modules are fine but there is a bug in the test program (or they
   misunderstand how the test works or the return values that are
   expected).

6) Use multiple test programs to test different aspects of your system.
   (In assignment 1 these different tests are performed during the 
   different task. For example, your interactive tests performed with
   driver.dem should differ from the tests you perform using tester.dem.)

7) Test special cases. Ideally a production quality program should be
   completely bullet proof (not that many really are :-).  No user, even
   malicious ones, should be able to crash the program.

8) Check the return values of function calls. That is check that the call
   has completed successfully - if it has not, handle the error
   intelligently.


Updated for 1030: January 2, 1998