This requires far more than simply showing that the program "works ok" for a few typical input cases.
For all software we want to ensure many things:
This is a very tall order, particularly for large, complex software projects.
There are, however, a number of typical or predictable sources of error in most programs and a number of steps we can take to improve our code quality.
THE GOAL OF TESTING IS TO REVEAL INADEQUACIES IN SOFTWARE
Don't write "cushy" test sets that you're pretty sure your code can pass - a good test is one that reveals a problem.
The test set developed should include, for each test:
When coming up with a test set, there are three major categories to consider:
Black box testing
In glass box testing we are only interested in testing the functionality
of the program: we have the problem description that tells us how a correct
solution is supposed to behave, so we establish test data that we think
is representative of the possible input conditions the program will
ultimately face.
Common black box tests:
For example, if the specifications talk about one aspect of the input having values in the range 0..1950, then include tests that, for that input, use values 0, 1, 1949, and 1950.
As another example, if the specifications talk about handling a list of values (or a sequence of inputs) then include a test that has an empty list, and include a test that has just one element in the list.
Glass box testing
As covered in the black box section, we can derive many test sets
directly from the specifications.
However, it is often useful to also consider the "inside information" we have about the actual structure of the code.
The testing ideas are the same as above, but now there are more data values of interest:
The program is supposed to read two times, each in the format hh:mm:ss, and output the time difference between the two.Then we might propose the following black box testsThe program should verify the correctness of the input, and it is not permissible to omit leading zeros in the hours segment of the time.
For example, if the times 09:59:59 and 10:01:00 are entered then the program should respond with 00:01:01.
A 24-hour clock is assumed, with times running from
00:00:00
to23:59:59
. If the first time is later than the second time then it is assumed the clock has "wrapped around" once.For example, if the times 23:00:01 and 01:24:01 are entered then the program should respond with 02:24:00.
Test rationale | Time 1 | Time 2 | Correct Output |
text in time 1 | hh:mm:ss | 12:00:00 | *ERRMESSAGE |
text in time 2 | 12:00:00 | hh:mm:ss | *ERRMESSAGE |
missing leading zero, hours time 1 | 0:00:00 | 12:00:00 | *ERRMESSAGE |
missing leading zero, minutes time 1 | 00:0:00 | 12:00:00 | *ERRMESSAGE |
missing leading zero, seconds time 1 | 00:00:0 | 12:00:00 | *ERRMESSAGE |
missing leading zero, hours time 2 | 00:00:00 | 2:00:00 | *ERRMESSAGE |
missing leading zero, minutes time 2 | 00:00:00 | 12:0:00 | *ERRMESSAGE |
missing leading zero, seconds time 2 | 00:00:00 | 12:00:0 | *ERRMESSAGE |
time out of bounds, hours time 1 | 24:00:00 | 12:00:00 | *ERRMESSAGE |
time out of bounds, minutes time 1 | 00:60:00 | 12:00:00 | *ERRMESSAGE |
time out of bounds, seconds time 1 | 00:00:60 | 12:00:00 | *ERRMESSAGE |
time out of bounds, hours time 2 | 20:00:00 | 24:00:00 | *ERRMESSAGE |
time out of bounds, minutes time 2 | 00:00:00 | 12:60:00 | *ERRMESSAGE |
time out of bounds, seconds time 2 | 00:00:00 | 12:00:60 | *ERRMESSAGE |
boundary case - all zeros | 00:00:00 | 00:00:00 | *ERRMESSAGE |
boundary case - max time-of-days | 23:59:59 | 23:59:59 | *ERRMESSAGE |
max time difference, no rollover | 00:00:00 | 23:59:59 | 23:59:59 |
max time difference, includes rollover | 12:00:01 | 12:00:00 | 23:59:59 |
min time difference with rollover | 23:59:59 | 00:00:00 | 00:00:01 |
"typical" case, no rollover | 07:24:39 | 11:28:47 | 04:04:08 |
"typical" case, with rollovers | 16:27:55 | 08:12:51 | 15:44:56 |
Now, suppose we implement the program as follows
#include <cstdio> void PromptUser(); void ReadTime(int& hours, int& minutes, int& seconds); void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2); void DisplayTime(int hrs_res, int min_res, int sec_res); int main() { int Hours1, Minutes1, Seconds1; int Hours2, Minutes2, Seconds2; int ResultHours, ResultMinutes, ResultSeconds; PromptUser(); ReadTime(Hours1, Minutes1, Seconds1); ReadTime(Hours2, Minutes2, Seconds2); CalcTimeDifference( ResultHours, ResultMinutes, ResultSeconds, Hours1, Minutes1, Seconds1, Hours2, Minutes2, Seconds2); DisplayTime(ResultHours, ResultMinutes, ResultSeconds); return 0; } void PromptUser() { printf("This program calculates the difference between two times,\n"); printf("assuming the two times are within 24 hours of one another\n"); printf("and are entered in sequential order\n\n"); } void ReadTime(int& hours, int& minutes, int& seconds) { char ColonChar; printf("Please enter a time in the form hh:mm:ss\n"); printf("assuming a 24-hour clock, and leading zeros must be included\n"); printf("(i.e. times go from 00:00:00 to 23:59:59)\n"); scanf("%d", &hours); scanf("%c", &ColonChar); scanf("%d", &minutes); scanf("%c", &ColonChar); scanf("%d", &seconds); } void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2) { sec_res = sec2 - sec1; min_res = min2 - min1; hrs_res = hrs2 - hrs1; if (sec_res < 0) { sec_res = sec_res + 60; min_res = min_res - 1; } if (min_res < 0) { min_res = min_res + 60; hrs_res = hrs_res - 1; } if (hrs_res < 0) { hrs_res = hrs_res + 24; } } void DisplayTime(int hrs_res, int min_res, int sec_res) { if (hrs_res < 10) printf("0"); printf("%d:", hrs_res); if (min_res < 10) printf("0"); printf("%d:", min_res); if (sec_res < 10) printf("0"); printf("%d:", sec_res); }Which additional glass box tests might we propose?
combination | Time 1 | Time 2 |
aaa | 10:10:10 | 09:09:09 |
aab | 10:10:02 | 09:09:11 |
aac | 10:10:22 | 09:09:32 |
aba | 10:02:10 | 09:11:09 |
abb | 10:02:02 | 09:11:11 |
abc | 10:02:22 | 09:11:32 |
aca | 10:22:10 | 09:32:09 |
acb | 10:22:02 | 09:32:11 |
acc | 10:22:22 | 09:32:32 |
aaa | 02:10:10 | 11:09:09 |
aab | 02:10:02 | 11:09:11 |
aac | 02:10:22 | 11:09:32 |
aba | 02:02:10 | 11:11:09 |
abb | 02:02:02 | 11:11:11 |
abc | 02:02:22 | 11:11:32 |
aca | 02:22:10 | 11:32:09 |
acb | 02:22:02 | 11:32:11 |
acc | 02:22:22 | 11:32:32 |
aaa | 22:10:10 | 32:09:09 |
aab | 22:10:02 | 32:09:11 |
aac | 22:10:22 | 32:09:32 |
aba | 22:02:10 | 32:11:09 |
abb | 22:02:02 | 32:11:11 |
abc | 22:02:22 | 32:11:32 |
aca | 22:22:10 | 32:32:09 |
acb | 22:22:02 | 32:32:11 |
acc | 22:22:22 | 32:32:32 |
Exception Handling
Exception handling is the process by which we deal with
any "unusual circumstances" during execution. Typically
this covers things like the entry of incorrect data or
failures in other parts of a system we must use (e.g. suppose
our program interacts with a database program, and for some
reason the database program crashes).
Exception handling on a practical level involves inserting sufficient error checking into our source code to ensure that any possible errors are caught and an appropriate response generated (even if the "response" is just displaying an error message and shutting down the program).
The key to successful exception handling is to assume,
in each and every function, that the other functions are
not necessarily trustworthy - i.e. don't assume
the error checking was adequately done elsewhere.
Example: suppose we have the following function
float divides(float x, float y) { return (x / y); }For the sake of robustness, we should not assume y is never zero - i.e. we should check for it, and generate an appropriate error message.
float divides(float x, float y) { if (y != 0) return (x / y); else { printf("WARNING: DIVIDE BY ZERO\n"); return 0; } }
#include <cstdio> void PromptUser(); int TimeCheck(int hours, int minutes, int seconds); void ReadTime(int& hours, int& minutes, int& seconds); void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2); void DisplayTime(int hrs_res, int min_res, int sec_res); int main() { int Hours1, Minutes1, Seconds1; int Hours2, Minutes2, Seconds2; int ResultHours, ResultMinutes, ResultSeconds; PromptUser(); ReadTime(Hours1, Minutes1, Seconds1); ReadTime(Hours2, Minutes2, Seconds2); CalcTimeDifference( ResultHours, ResultMinutes, ResultSeconds, Hours1, Minutes1, Seconds1, Hours2, Minutes2, Seconds2); printf("\nThe time difference is: "); DisplayTime(ResultHours, ResultMinutes, ResultSeconds); return 0; } void PromptUser() { printf("\nThis program calculates the difference between two times,\n"); printf("assuming the two times are within 24 hours of one another\n"); printf("and are entered in sequential order\n"); } void ReadTime(int& hours, int& minutes, int& seconds) { char ColonChar; printf("\nPlease enter a time in the form hh:mm:ss\n); printf("assuming a 24-hour clock, and leading zeros must be included\n"); printf("(i.e. times go from 00:00:00 to 23:59:59)\n"); scanf("%d", &hours); scanf("%c", &ColonChar); scanf("%d", &minutes); scanf("%c", &ColonChar); scanf("%d", &seconds); if (TimeCheck(hours, minutes, seconds) == 0) { printf("WARNING: invalid time supplied\n"); ReadTime(hours, minutes, seconds); } } int TimeCheck(int hours, int minutes, int seconds) { if ((hours < 0) || (hours > 23)) return 0; if ((minutes < 0) || (minutes > 59)) return 0; if ((seconds < 0) || (seconds > 59)) return 0; return 1; } void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2) { if (TimeCheck(hrs1, min1, sec1) == 0) return; if (TimeCheck(hrs2, min2, sec2) == 0) return; sec_res = sec2 - sec1; min_res = min2 - min1; hrs_res = hrs2 - hrs1; if (sec_res < 0) { sec_res = sec_res + 60; min_res = min_res - 1; } if (min_res < 0) { min_res = min_res + 60; hrs_res = hrs_res - 1; } if (hrs_res < 0) { hrs_res = hrs_res + 24; } } void DisplayTime(int hrs_res, int min_res, int sec_res) { if (TimeCheck(hrs_res, min_res, sec_res) == 0) { printf("Invalid time supplied, hours="); printf("%d, minutes=", hrs_res); printf("%d, seconds=", min_res); printf("%d\n", sec_res); return; } if (hrs_res < 10) printf("0"); printf("%d:", hrs_res); if (min_res < 10) printf("0"); printf("%d:", min_res); if (sec_res < 10) printf("0"); printf("%d\n", sec_res); }
Suppose we were going to approach the development of our "time difference" program in an incremental fashion. The steps I would advise are:
#include <cstdio> void PromptUser(); int TimeCheck(int hours, int minutes, int seconds); void ReadTime(int& hours, int& minutes, int& seconds); void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2); void DisplayTime(int hrs_res, int min_res, int sec_res); int main() { int Hours1, Minutes1, Seconds1; int Hours2, Minutes2, Seconds2; int ResultHours, ResultMinutes, ResultSeconds; PromptUser(); ReadTime(Hours1, Minutes1, Seconds1); ReadTime(Hours2, Minutes2, Seconds2); CalcTimeDifference( ResultHours, ResultMinutes, ResultSeconds, Hours1, Minutes1, Seconds1, Hours2, Minutes2, Seconds2); printf("\nThe time difference is: "); DisplayTime(ResultHours, ResultMinutes, ResultSeconds); return 0; } void PromptUser() { printf("In PromptUser\n"); } void ReadTime(int& hours, int& minutes, int& seconds) { printf("In ReadTime\n"); } int TimeCheck(int hours, int minutes, int seconds) { printf("In TimeCheck\n"); return 1; } void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2) { printf("In CalcTimeDifference\n"); } void DisplayTime(int hrs_res, int min_res, int sec_res) { printf("In DisplayTime\n"); }
#include <cstdio> void PromptUser(); int TimeCheck(int hours, int minutes, int seconds); void ReadTime(int& hours, int& minutes, int& seconds); void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2); void DisplayTime(int hrs_res, int min_res, int sec_res); int main() { int Hours1, Minutes1, Seconds1; int Hours2, Minutes2, Seconds2; int ResultHours, ResultMinutes, ResultSeconds; PromptUser(); ReadTime(Hours1, Minutes1, Seconds1); ReadTime(Hours2, Minutes2, Seconds2); CalcTimeDifference( ResultHours, ResultMinutes, ResultSeconds, Hours1, Minutes1, Seconds1, Hours2, Minutes2, Seconds2); printf("\nThe time difference is: "); ResultHours = 12; ResultMinutes = 12; ResultSeconds = 12; DisplayTime(ResultHours, ResultMinutes, ResultSeconds); return 0; } void PromptUser() { printf("In PromptUser\n"); } void ReadTime(int& hours, int& minutes, int& seconds) { printf("In ReadTime\n"); } int TimeCheck(int hours, int minutes, int seconds) { printf("In TimeCheck\n"); return 1; } void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2) { printf("In CalcTimeDifference\n"); } void DisplayTime(int hrs_res, int min_res, int sec_res) { if (hrs_res < 10) printf("0)"; printf("%d:", hrs_res); if (min_res < 10) printf("0)"; printf("%d:", min_res); if (sec_res < 10) printf("0)"; printf("%d\n", sec_res); }
#include <cstdio> void PromptUser(); int TimeCheck(int hours, int minutes, int seconds); void ReadTime(int& hours, int& minutes, int& seconds); void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2); void DisplayTime(int hrs_res, int min_res, int sec_res); int main() { int Hours1, Minutes1, Seconds1; int Hours2, Minutes2, Seconds2; int ResultHours, ResultMinutes, ResultSeconds; PromptUser(); ReadTime(Hours1, Minutes1, Seconds1); ReadTime(Hours2, Minutes2, Seconds2); CalcTimeDifference( ResultHours, ResultMinutes, ResultSeconds, Hours1, Minutes1, Seconds1, Hours2, Minutes2, Seconds2); printf("\nThe time difference is: "); ResultHours = 12; ResultMinutes = 12; ResultSeconds = 12; DisplayTime(ResultHours, ResultMinutes, ResultSeconds); return 0; } void PromptUser() { printf("\nThis program calculates the difference between two times,\n"); printf("assuming the two times are within 24 hours of one another"\n"); printf("and are entered in sequential order\n"); } void ReadTime(int& hours, int& minutes, int& seconds) { printf("In ReadTime\n"); } int TimeCheck(int hours, int minutes, int seconds) { printf("In TimeCheck\n"); return 1; } void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2) { printf("In CalcTimeDifference\n"); } void DisplayTime(int hrs_res, int min_res, int sec_res) { if (hrs_res < 10) printf("0"); printf("%d:", hrs_res); if (min_res < 10) printf("0"); printf("%d:", min_res); if (sec_res < 10) printf("0"); printf("%d\n", sec_res); }
#include <cstdio> void PromptUser(); int TimeCheck(int hours, int minutes, int seconds); void ReadTime(int& hours, int& minutes, int& seconds); void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2); void DisplayTime(int hrs_res, int min_res, int sec_res); int main() { int Hours1, Minutes1, Seconds1; int Hours2, Minutes2, Seconds2; int ResultHours, ResultMinutes, ResultSeconds; PromptUser(); ReadTime(Hours1, Minutes1, Seconds1); ReadTime(Hours2, Minutes2, Seconds2); CalcTimeDifference( ResultHours, ResultMinutes, ResultSeconds, Hours1, Minutes1, Seconds1, Hours2, Minutes2, Seconds2); // editing for testing, just echo hours read in ResultHours = Hours1; ResultMinutes = Minutes1; ResultSeconds = Seconds1; printf("\nThe time difference is: "); DisplayTime(ResultHours, ResultMinutes, ResultSeconds); return 0; } void PromptUser() { printf("\nThis program calculates the difference between two times,\n"); printf("assuming the two times are within 24 hours of one another\n"); printf("and are entered in sequential order\n"); } void ReadTime(int& hours, int& minutes, int& seconds) { char ColonChar; printf("\nPlease enter a time in the form hh:mm:ss\n"); printf("assuming a 24-hour clock, and leading zeros must be included\n"); printf("(i.e. times go from 00:00:00 to 23:59:59)\n"); scanf("%d", &hours); scanf("%c", &ColonChar); scanf("%d", &minutes); scanf("%c", &ColonChar); scanf("%d", &seconds); } int TimeCheck(int hours, int minutes, int seconds) { printf("In TimeCheck\n"); return 1; } void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2) { printf("In CalcTimeDifference\n"); } void DisplayTime(int hrs_res, int min_res, int sec_res) { if (hrs_res < 10) printf("0"); printf("%d:", hrs_res); if (min_res < 10) printf("0"); printf("%d:", min_res); if (sec_res < 10) printf("0"); printf("%d\n", sec_res); }
#include <cstdio> void PromptUser(); int TimeCheck(int hours, int minutes, int seconds); void ReadTime(int& hours, int& minutes, int& seconds); void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2); void DisplayTime(int hrs_res, int min_res, int sec_res); int main() { int Hours1, Minutes1, Seconds1; int Hours2, Minutes2, Seconds2; int ResultHours, ResultMinutes, ResultSeconds; PromptUser(); ReadTime(Hours1, Minutes1, Seconds1); ReadTime(Hours2, Minutes2, Seconds2); CalcTimeDifference( ResultHours, ResultMinutes, ResultSeconds, Hours1, Minutes1, Seconds1, Hours2, Minutes2, Seconds2); // Again, adjusted just for checking I/O, // still not really calculating time differences printf("\nThe time difference is: "); DisplayTime(Hours1, Minutes1, Seconds1); DisplayTime(Hours2, Minutes2, Seconds2); return 0; } void PromptUser() { printf("This program calculates the difference between two times,\n"); printf("assuming the two times are within 24 hours of one another\n"); printf("and are entered in sequential order\n"); } void ReadTime(int& hours, int& minutes, int& seconds) { char ColonChar; printf("Please enter a time in the form hh:mm:ss\n"); printf("assuming a 24-hour clock, and leading zeros must be included\n"); printf("(i.e. times go from 00:00:00 to 23:59:59)\n"); scanf("%d", &hours); scanf("%c", &ColonChar); scanf("%d", &minutes); scanf("%c", &ColonChar); scanf("%d", &seconds); if (TimeCheck(hours, minutes, seconds) == 0) { printf("WARNING: invalid time supplied"\n"); ReadTime(hours, minutes, seconds); } } int TimeCheck(int hours, int minutes, int seconds) { if ((hours < 0) || (hours > 23)) return 0; if ((minutes < 0) || (minutes > 59)) return 0; if ((seconds < 0) || (seconds > 59)) return 0; return 1; } void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2) { printf("In CalcTimeDifference\n"); } void DisplayTime(int hrs_res, int min_res, int sec_res) { if (TimeCheck(hrs_res, min_res, sec_res) == 0) { printf("Invalid time supplied, hours="); printf("%d, minutes=", hrs_res); printf("%d, seconds=", min_res); printf("%d\n", sec_res); return; } if (hrs_res < 10) printf("0"); printf("%d:", hrs_res); if (min_res < 10) printf("0"); printf("%d:", min_res); if (sec_res < 10) printf("0"); printf("%d\n", sec_res); }
#include <cstdio> void PromptUser(); int TimeCheck(int hours, int minutes, int seconds); void ReadTime(int& hours, int& minutes, int& seconds); void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2); void DisplayTime(int hrs_res, int min_res, int sec_res); int main() { int Hours1, Minutes1, Seconds1; int Hours2, Minutes2, Seconds2; int ResultHours, ResultMinutes, ResultSeconds; PromptUser(); ReadTime(Hours1, Minutes1, Seconds1); ReadTime(Hours2, Minutes2, Seconds2); CalcTimeDifference( ResultHours, ResultMinutes, ResultSeconds, Hours1, Minutes1, Seconds1, Hours2, Minutes2, Seconds2); printf("\nThe time difference is: "); DisplayTime(ResultHours, ResultMinutes, ResultSeconds); return 0; } void PromptUser() { printf("This program calculates the difference between two times,\n"); printf("assuming the two times are within 24 hours of one another\n"); printf("and are entered in sequential order\n"); } void ReadTime(int& hours, int& minutes, int& seconds) { char ColonChar; printf("\nPlease enter a time in the form hh:mm:ss\n"); printf("assuming a 24-hour clock, and leading zeros must be included\n"); printf("(i.e. times go from 00:00:00 to 23:59:59)\n"); scanf("%d", &hours); scanf("%c", &ColonChar); scanf("%d", &minutes); scanf("%c", &ColonChar); scanf("%d", &seconds); if (TimeCheck(hours, minutes, seconds) == 0) { printf("WARNING: invalid time supplied\n"); ReadTime(hours, minutes, seconds); } } int TimeCheck(int hours, int minutes, int seconds) { if ((hours < 0) || (hours > 23)) return 0; if ((minutes < 0) || (minutes > 59)) return 0; if ((seconds < 0) || (seconds > 59)) return 0; return 1; } void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2) { sec_res = sec2 - sec1; min_res = min2 - min1; hrs_res = hrs2 - hrs1; if (sec_res < 0) { sec_res = sec_res + 60; min_res = min_res - 1; } if (min_res < 0) { min_res = min_res + 60; hrs_res = hrs_res - 1; } if (hrs_res < 0) { hrs_res = hrs_res + 24; } } void DisplayTime(int hrs_res, int min_res, int sec_res) { if (TimeCheck(hrs_res, min_res, sec_res) == 0) { printf("Invalid time supplied, hours="); printf("%d, minutes=", hrs_res); printf("%d, seconds=", min_res); printf("%d\n=", sec_res); return; } if (hrs_res < 10) printf("0"); printf("%d:", hrs_res); if (min_res < 10) printf("0"); printf("%d:", min_res); if (sec_res < 10) printf("0"); printf("%d\n", sec_res); }
#include <cstdio> void PromptUser(); int TimeCheck(int hours, int minutes, int seconds); void ReadTime(int& hours, int& minutes, int& seconds); void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2); void DisplayTime(int hrs_res, int min_res, int sec_res); int main() { int Hours1, Minutes1, Seconds1; int Hours2, Minutes2, Seconds2; int ResultHours, ResultMinutes, ResultSeconds; PromptUser(); ReadTime(Hours1, Minutes1, Seconds1); ReadTime(Hours2, Minutes2, Seconds2); CalcTimeDifference( ResultHours, ResultMinutes, ResultSeconds, Hours1, Minutes1, Seconds1, Hours2, Minutes2, Seconds2); printf("\nThe time difference is: "); DisplayTime(ResultHours, ResultMinutes, ResultSeconds); return 0; } void PromptUser() { printf("This program calculates the difference between two times,\n"); printf("assuming the two times are within 24 hours of one another\n"); printf("and are entered in sequential order\n"); } void ReadTime(int& hours, int& minutes, int& seconds) { char ColonChar; printf("Please enter a time in the form hh:mm:ss\n"); printf("assuming a 24-hour clock, and leading zeros must be included\n"); printf("(i.e. times go from 00:00:00 to 23:59:59)\n"); scanf("%d", &hours); scanf("%c", &ColonChar); scanf("%d", &minutes); scanf("%c", &ColonChar); scanf("%d", &seconds); if (TimeCheck(hours, minutes, seconds) == 0) { printf("WARNING: invalid time supplied\n"); ReadTime(hours, minutes, seconds); } } int TimeCheck(int hours, int minutes, int seconds) { if ((hours < 0) || (hours > 23)) return 0; if ((minutes < 0) || (minutes > 59)) return 0; if ((seconds < 0) || (seconds > 59)) return 0; return 1; } void CalcTimeDifference( int& hrs_res, int& min_res, int& sec_res, int hrs1, int min1, int sec1, int hrs2, int min2, int sec2) { if (TimeCheck(hrs1, min1, sec1) == 0) return; if (TimeCheck(hrs2, min2, sec2) == 0) return; sec_res = sec2 - sec1; min_res = min2 - min1; hrs_res = hrs2 - hrs1; if (sec_res < 0) { sec_res = sec_res + 60; min_res = min_res - 1; } if (min_res < 0) { min_res = min_res + 60; hrs_res = hrs_res - 1; } if (hrs_res < 0) { hrs_res = hrs_res + 24; } } void DisplayTime(int hrs_res, int min_res, int sec_res) { if (TimeCheck(hrs_res, min_res, sec_res) == 0) { printf("Invalid time supplied, hours="); printf("%d, minutes=", hrs_res); printf("%d, seconds=", min_res); printf("%d\n", sec_res); return; } if (hrs_res < 10) printf("0"); printf("%d:", hrs_res); if (min_res < 10) printf("0"); printf("%d:", min_res); if (sec_res < 10) printf("0"); printf("%d\n", sec_res); }
If you have thought out your test plan as per the discussion above, and you're building your software in an incremental fashion, then you already have an excellent start on debugging: you have a focus on which segment of the source code is (most likely) the source of any current problems, and you have a rationale for each test set that gives you a basis for investigating further.
One of the key goals in debugging is to constantly narrow the sources of your current error - visual inspection of the code may not be sufficient. Try to identify new test values you can use to precisely determine when and why your program crashes, hangs, or simply gives incorrect data.
Debugging software is helpful, but often is not enough to track down the cause of a problem unless you also make careful (and sometimes creative) deductions about what your program is doing and why.
In addition to fuse
, we also have available a debugger
named gdb
that can be run from a terminal window.
To invoke this debugger, follow the steps below
(example is shown assuming pex2.C
is the source code file):
g++ -g pex2.C -o pex2 gdb pex2The debugger will come back with a prompt that looks like
(gdb)You can now execute a variety of commands that allow you to
h
when you see
the (gdb)
prompt.