580 likes | 596 Views
Learn simple design principles, good coding practices, and testing strategies to develop reliable programs that meet user requirements. Explore input data validation and the importance of testing in program development.
E N D
Fundamental Programming Testing Fundamental Programming 310201
Review • our goal : we aim to develop simple designs that work, and that do what users want • programmers spend 75% of the time maintaining existing programs • in lectures, we’ve mentioned a number of principles and practices that can help us to achieve this goal… Fundamental Programming 310201
Design Principles • design principles introduced in lectures: • keep it simple • take care when selecting variable names • use comments to describe your designs • use sub-programs to simplify a design • test logic using tracing and walkthroughs • produce test cases while developing designs • validate user input Fundamental Programming 310201
Good Coding Practices • some good coding practices introduced: • declare each variable on a new line • initialise variables • indent if-blocks, else-blocks and while-blocks • align braces • use comments to explain logic • use test cases to verify the program’s logic • using tracing and walkthroughs to find bugs Fundamental Programming 310201
Testing • in this class, we look at strategies and techniquesfor testing programs - we cover: • the why and when of testing • testing pseudocode designs • testing programs • we test programs using different sets of input data – test cases • in the previous lecture we saw an example of validating user input • a few more things on input data validation… Fundamental Programming 310201
InputData Validation • the program that follows continues looping until the user enters a valid exam mark – between 0 and the number of marks in the exam… Fundamental Programming 310201
Input Data Validation Example write “Number of marks in exam ==> “ read NbrMarks setStudentMarkto-1 whileStudentMark < 0 orStudentMark > NbrMarks write “Student’s mark ==> “ readStudentMark ifStudentMark < 0 orStudentMark > NbrMarksthen write“ERROR: Enter a value between 0 and ” writeNbrMarks writeNewLine : Fundamental Programming 310201
A C++Implementation #include <iostream.h> void main (void) { int NbrMarks = 0; float StudentMark = 0; cout << "Number of marks in exam ==> "; cin >> NbrMarks; StudentMark = -1; while ((StudentMark < 0) || (StudentMark > NbrMarks)) { cout << "Student’s mark ==> "; cin >> StudentMark; if ((StudentMark < 0) || (StudentMark > NbrMarks)) { cout << " ERROR: Enter a value between 0 and "; cout << NbrMarks; cout << endl; } } } Fundamental Programming 310201
InputData Validation • a dialog to test the logic looks like this… Number of marks in exam ==> 20 Student’s mark ==> -8 ERROR: Enter a value between 0 and 20 Student’s mark ==> 28 ERROR: Enter a value between 0 and 20 Student’s mark ==> 18 Fundamental Programming 310201
InputData Validation • but what if the user enters a value with the wrong data type? • depending on the compiler, you may find that: • in the first case, the program will not accept any further input • in the second case, the program goes into a endless loop displaying “ERROR: Enter a mark…” messages Number of marks in exam ==> 23.5 ...? Number of marks in exam ==> a ...? Fundamental Programming 310201
InputData Validation • it is possible to add code to guard against the user entering the wrong data type • this is a technical issue that is of no interest in this course • in this course, we will always assume that the user enters a value of the required type • do not waste time trying to develop code that will handle incorrect data types • all of the testing performed in this course will involve values of the correct type Fundamental Programming 310201
Why Test Designs? • on some systems (collections of inter-related programs), up to 50% of the development costs are spent on testing the system - why? • the reliability of some systems can be a matter of life-and-death - examples: space systems, military systems, medical systems • reliability of commercial and administrative systems can be costly in terms of: direct loss (incorrect invoicing), development costs, system acceptance, legal fees, damaged reputation…etc Fundamental Programming 310201
When To Test Designs? • it is a mistake to leave testing to last • testing is a cultural thing - one needs to be committed to building reliable programs • we can: • test design specifications • test pseudocode designs • test programs • test documentation • in this course, we are mainly concerned with testing pseudocode designs and programs Fundamental Programming 310201
Testing Pseudocode Designs • we test that a design can deal with the full range of cases it is expected to handle • a test case consists of a set of data inputs • test cases most likely to expose errors in the design tend to lie at the edge of the range of possible input values Fundamental Programming 310201
Tracing For Logic Errors • in the handout for this lecture you will find a pseudocode design for a program to to obtain the lowest & highestmark in a set of marks • this design has logic errors - one is reasonable easy to find - one is more subtle • trace the logic in the design – see if you can find the logic errors in five minutes Fundamental Programming 310201
Activity Break Fundamental Programming 310201
Using Test Cases To Find Errors • if you have not found the errors, consider the following test case: • what output would you expect in this case? • what output will the programproduce in this case? Number of marks in Exam ==> 20 Student Mark ==> 15 Another Mark ? [Y/N] ==> N Fundamental Programming 310201
Using Test Cases To Find Errors Number of marks in Exam ==> 20 Student Mark ==> 15 Another Mark ? [Y/N] ==> N • for this case, the expected output is: • however, the program will produce: Highest student mark: 15 Lowest student mark: 15 Highest student mark: 20 Lowest student mark: 0 Fundamental Programming 310201
Using Test Cases To Find Errors • you may have found that the design has initialisation errors: • LowestStudentMark is initially set to 0 • HighestStudentMark is initially set to the maximum number of marks in the test • having fixed these errors, the design still has another logic error • what is the expected outputs, and actual outputs, for the following test cases… Fundamental Programming 310201
Using Test Cases To Find Errors Number of marks in Exam ==> 10 Student Mark ==> 9 Another Mark ? [Y/N] ==> Y Student Mark ==> 6 Another Mark ? [Y/N] ==> N Number of marks in Exam ==> 10 Student Mark ==> 3 Another Mark ? [Y/N] ==> Y Student Mark ==> 7 Another Mark ? [Y/N] ==> N Fundamental Programming 310201
Activity Break Fundamental Programming 310201
Subtle Logic Error! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • this logic works fine for the following case: • maximum marks in test: 10 • marks: 9, 6 Fundamental Programming 310201
Tracing A Test Case... : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects before entering loop: HighestStudentMark: 0 LowestStudentMark : 10 StudentMark : ? (undefined) Fundamental Programming 310201
First Loop! : ==> ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 0 LowestStudentMark : 10 StudentMark : 9 Fundamental Programming 310201
First Loop! : ( if required, update highest or lowest mark… ) ==> ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 0 LowestStudentMark : 10 StudentMark : 9 Fundamental Programming 310201
First Loop! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then ==> setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 0 LowestStudentMark : 10 StudentMark : 9 Fundamental Programming 310201
First Loop! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark ==> : • value of data objects: HighestStudentMark: 9 LowestStudentMark : 10 StudentMark : 9 Fundamental Programming 310201
Second Loop! : ==> ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 9 LowestStudentMark : 10 StudentMark : 6 Fundamental Programming 310201
Second Loop! : ( if required, update highest or lowest mark… ) ==> ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 9 LowestStudentMark : 10 StudentMark : 6 Fundamental Programming 310201
Second Loop! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark ==> else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 9 LowestStudentMark : 10 StudentMark : 6 Fundamental Programming 310201
Second Loop! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then ==> setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 9 LowestStudentMark : 10 StudentMark : 6 Fundamental Programming 310201
Second Loop! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark ==> : • value of data objects: HighestStudentMark: 9 LowestStudentMark : 6 StudentMark : 6 Fundamental Programming 310201
Subtle Logic Error! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • this logic does not work for the second case: • maximum marks in test: 10 • marks: 3, 7 Fundamental Programming 310201
Tracing A Test Case... : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects before entering loop: HighestStudentMark: 0 LowestStudentMark : 10 StudentMark : ? (undefined) Fundamental Programming 310201
First Loop! : ==> ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 0 LowestStudentMark : 10 StudentMark : 3 Fundamental Programming 310201
First Loop! : ( if required, update highest or lowest mark… ) ==> ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 0 LowestStudentMark : 10 StudentMark : 3 Fundamental Programming 310201
First Loop! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then ==> setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 0 LowestStudentMark : 10 StudentMark : 3 Fundamental Programming 310201
First Loop! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark ==> : • value of data objects: HighestStudentMark: 3 LowestStudentMark : 10 StudentMark : 3 Fundamental Programming 310201
Second Loop! : ==> ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 3 LowestStudentMark : 10 StudentMark : 7 Fundamental Programming 310201
Second Loop! : ( if required, update highest or lowest mark… ) ==> ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 3 LowestStudentMark : 10 StudentMark : 7 Fundamental Programming 310201
First Loop! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then ==> setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : • value of data objects: HighestStudentMark: 3 LowestStudentMark : 10 StudentMark : 7 Fundamental Programming 310201
Second Loop! : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark ==> : • value of data objects: HighestStudentMark: 7 LowestStudentMark : 10 StudentMark : 7 Fundamental Programming 310201
Subtle Logic Error! • if time, take another coupleof minutes to fix the problem… Fundamental Programming 310201
Activity Break Fundamental Programming 310201
Possible Solution • a simple solutions is to remove the “else” • instead of: : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark else if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : Fundamental Programming 310201
Possible Solution • it’s: : ( if required, update highest or lowest mark… ) ifStudentMark > HighestStudentMark then setHighestStudentMarkto StudentMark if StudentMark < LowestStudentMark then setLowestStudentMarkto StudentMark : Fundamental Programming 310201
Testing Pseudocode Designs • to test a pseudocode design, we check that the logic can deal with the full range of cases it is expected to handle • two approaches can we taken when developing test cases: • block-box testing: simply concentrate on the range of data inputs the design must handle • white-box testing: look at loops and branches in logic; formulate test cases to fully exercise the design - eg, a test case to exercise all branches; others to exercise only some branches Fundamental Programming 310201
Documenting A Test Case • it’s not enough for testing to be done, it must be seen to be done: • to reduce professional liability risk • to document tests to perform on program(s) • to document tests to perform on future versions of the program • the Study Guide describes a table that can be used to document a test case • the basic idea is shown on the next slide (see Study Guide Book 1 for details) Fundamental Programming 310201
Label Prompt P1Maximum number of marks in test: P2Student mark: P3Another mark? [Y/N]: Prompt Input P1 10 P2 9 P3 Y P2 6 P3 N Output Highest student mark: 9 Lowest student mark: 6 Fundamental Programming 310201
Testing Pseudocode Designs • there’s an even simpler, cost-effective way to test a design - a walk-through • a walk-through is similar to a trace, but it is a less-formal way of following a design’s logic • a walk-through of the logic is presented to a group of peers (fellow-developers/students): • very effective ! • highly recommended ! Fundamental Programming 310201