72 Intermediate C Programming
• It is possible to test a program and demonstrate that the program is incorrect.
• It is almost impossible to test a program and demonstrate that the program is correct.
• If a test fails (assuming the test is valid), then we know that the program is wrong.
• If a program passes a test, what do we know about the program? Not much.
This may seem puzzling. If a program passes many tests, then the program must be
correct, right? In a way, this is like the theory of “black swans”. If we observe a thousand
white swans, we do not know whether black swans exist or not. Similarly, passing a thousand
tests does not tell us whether a program is correct. In contrast, if we see one black swan,
we know it exists. If a program fails one test, the program has a problem.
The truth is that testing is extremely hard (and important). Passing many tests gives
you some confidence, but no guarantee. A non-trivial program can have many possible test
cases. It is impossible to test so many cases. Even though testing is imperfect, testing is still
useful in developing programs. The following explains how to develop a strategy for testing.
5.2.1 Generating Test Cases
To test a program, we need test cases. To test areDistinct, we need different test cases:
• len is zero or not.
• arr either contains distinct elements or not.
At least three test cases are needed:
1. an empty file making len zero
2. a file with distinct numbers
3. a file with duplicate numbers
Creating the first test case is easy: Make an empty file. The touch command in Linux
can create an empty file. The second and the third test cases can be created by hand.
Alternatively, test cases can be developed using an on-line random number generator, saving
the results to a file. In this case, how do we know whether the numbers are distinct? The
sort and uniq commands in Linux can be used for this. The first command orders the
numbers and the second command tells whether the sorted numbers are unique or not. If
we add -d after uniq, the command displays which numbers duplicate. We chain the two
commands together using a pipe. The pipe takes the output of the sort command, and
makes it the input to the uniq command. In a Linux Terminal:
$ sort filename | uniq -d
filename is the name of the file that stores the random numbers. If the numbers in this file
are distinct, nothing appears. If some numbers duplicate, then the duplicate numbers are
shown on the screen.
5.2.2 Redirecting Output
Section 1.2 explained how to redirect a program’s output. Instead of printing “The
elements are distinct.” or “The elements are not distinct.” on the computer screen, the
output can be saved to a file. The following command redirects the output to the file whose
name is outputs/output0:
$ ./prog inputs/input0 > outputs/output0
Please check that the directory outputs exists before running this command. If it does not
exist, then use this command to create the directory:
$ mkdir outputs