Debugging and Testing Lab

CS 117, 10/2/96

Compiler errors

Let's start with dataProc.p, a version of your first homework assignment.
  1. Save the program in your account.
  2. Compile and run the program to convince yourself it works. You can use data.txt as test data.
  3. Collect as many different error messages as you can, by deliberately sabotaging a working program and observing the resulting compiler error messages. You might want to keep a file of error messages with a description of what caused the error in question.

    In the list below, I have given you a few suggestions of errors you can introduce into dataProc.p. For each of them, make the indicated change to the program, try to compile the resulting program, and take a look at the resulting error message(s). Does the message have any apparent relationship to the actual error? Is there terminology you don't recognize? Does the compiler correctly identify the line number where the trouble is?

    Don't forget to put the program back to its original state before moving on to the next bit of sabotage.

Run-time errors

Run-time errors are errors that occur after the program successfully compiles, while the program is running. Let's look at a few such errors.
  1. Write a program with an infinite loop. How does the program behave when you run it?

Testing

Once you get a program to compile, there is still work to be done to determine whether the program is correct. We will, later in term, spend a day or two discussing how to use mathematical proof techniques to prove the correctness of a program. Such techniques can be very powerful, but they are also limited in practical scope (sometimes correctness proofs are just too hard to construct for a large program).

An important phase a program development, whether or not you have used correctness proofs, is testing. You need to run your program through its paces. This exercise will give you a small taste of the scope of testing.

Get and save the program dataProc2.p, another solution of the first programming assignment. This program uses a slightly different strategy for computing maxima and minima than the first program did. Here are some questions:

  1. Does dataProc2.p give the same results for data.txt as dataProc.p?
  2. Have we tested all the important combinations of score1, score2, and score3? What cases, if any, are missing?
  3. Can you find three numbers for which ComputeMax will fail to give the right answer?
  4. Construct a complete set of test data that will try all significant combinations of score1, score2, and score3? Don't forget about some or all of score1, score2, and score3 being equal.
  5. Are there some test cases that make ComputeMax fail, but for which ComputeMin works? How about vice versa?
  6. What needs to be done to dataProc2.p to fix it?
  7. Does dataProc.p work for all of your test data?

Tracking the progress of a program

Here's a very short exercise on a very important debugging technique.

Go back to the original copy of dataProc2.p. To try to understand why it is failing in some cases, you can build a small test data file (containing only the data that cause trouble). Then, insert writeln's judiciously into the code. For example, make ComputeMax look like this:


if (a > b) and (a > c) then
begin
	writeln( 'a is big: ', a, b, c );
	ComputeMax := a
end

else if (b > a) and (b > c) then
begin
	writeln( 'b is big: ', a, b, c );
	ComputeMax := b
end

else
begin
	writeln( 'c is big: ', a, b, c );
	ComputeMax := c
end
Using this code, run the new dataProc2.p on the small data set, and you can see where ComputeMax decides to go. Is ComputeMax making the right decisions? Why not?