Testing and debugging refer to the tasks of detecting and removing errors in a program, so that the program produces the desired result on all occasions. Every programmer should be aware of the fact that rarely does a program run perfectly the first time. No matter how thoroughly the design is carried out, and no matter how much care is taken in coding, one can never say that the program would be 100 per cent error-free. It is therefore necessary to make efforts do detect, isolate, and correct any errors that are likely to be present in the program.
Types of Errors
There might be other errors, some obvious and others not so obvious. All the4se errors can be classified under four types, namely, syntax errors, run-time errors, logical errors, and latent errors.
Syntax error: Any violation of rules of the language results in syntax errors. The compiler can detect and isolate such errors. When syntax errors are present, the compilation fails and is terminated after listing the errors and the line numbers in the source program, where the errors have occurred. Remember, in some cases, the line number may not exactly indicate the place of the error. in other cases, on syntax error may result in a long list of errors. Correction of one or two errors at the beginning of the program may eliminate the entire list.
Run-time errors: Errors such as a mismatch of date types or referencing an out-of -range array element go undetected by the compiler. A program with these mistakes will run, but produce erroneous results and therefore, the name run-time errors is given to such errors. Isolating a run-time error is usually a difficult task.
Logical errors: As the name implies, these errors are related to the logic of the program execution. Such actions as taking a wrong path, failure to consider a particular condition, and incorrect order of evaluation, of statements belong to this category. Logical errors do not show up as compile-generated error messages. Rather, they cause incorrect results. These errors are primarily due to a poor understanding of the problem, incorrect translation. of the algorithm into the program.
Latent errors: It is a ‘hidden’ error that shows up only when a particular set of data is used. For example, consider the following statement
An error occurs only when ‘p’ and ‘q’ are equal. An error of this kind can be detected only by using all possible combination of test data.
Testing is the process of reviewing and executing a program with the intent of detecting errors, which may be belong to any of the four kinds discussed above. We know that while the compiler can detect syntactic and semantic errors, it cannot detect run-time and logical errors that show up during the execution of the program. Testing, therefore, should include necessary steps to detect all possible errors in the program. It is, however, important to remember that it is impractical to find all errors. Testing process may include the following two stages:
1. Human testing
2. Computer-based testing
Human testing: It is an effective error-detection process and is done before the computer-based testing begins. Human resting methods include code inspection by the programmer, code inspection by a test group, and a review by a peer group. The test is carried out statement by statement and is analyzed with respect to a checklist of common programming errors. In addition to finding the errors, the programming style and choice of algorithm are also reviewed.
Computer-based testing: This involves two stages, namely compiler testing and run-time testing. Compiler testing is the simplest of the two and detects yet undiscovered syntax errors. The program executes when the compiler detects no more errors. Should it mean that the program is correct? Will it produce the expected results? The answer is negative. The program may still contain run-time and logic errors.
Run-time errors may produce run-time error messages such as “null pointer assignment” and “stack overflow”. When the program is free from all such errors, it produces output which might or might not be correct. Now comes the crucial test, the test for the expected output. The goal is to ensure that the program produces expected results under all conditions of input data.
Test for correct output is done using test data with known results for the purpose of comparison. The most important consideration here is the design or invention of effective test data. A useful criteria for test data is that all the various conditions and path that the processing may take during execution must be tested.
Program testing can be done either at module (function) level or at program level. Module level test, often known as unit test, is conducted on each of the modules to uncover errors within the boundary of the module. Unit testing becomes simple when a module is designed to perform only one function.