Chapter 10 – Testing and Debugging. Goals Learn techniques to test your code Learn techniques to test your code Learn to carry out unit tests Learn to.

Slides:



Advertisements
Similar presentations
SOFTWARE TESTING. INTRODUCTION  Software Testing is the process of executing a program or system with the intent of finding errors.  It involves any.
Advertisements

COMPUTER PROGRAMMING I Essential Standard 5.02 Understand Breakpoint, Watch Window, and Try And Catch to Find Errors.
Annoucements  Next labs 9 and 10 are paired for everyone. So don’t miss the lab.  There is a review session for the quiz on Monday, November 4, at 8:00.
Week 5: Loops 1.  Repetition is the ability to do something over and over again  With repetition in the mix, we can solve practically any problem that.
Programming Types of Testing.
FIT FIT1002 Computer Programming Unit 19 Testing and Debugging.
Testing & Debugging CSC 171 FALL 2004 LECTURE 13.
Debugging Techniques1. 2 Introduction Bugs How to debug Using of debugger provided by the IDE Exception Handling Techniques.
Integration testing Satish Mishra
Methods Liang, Chapter 4. What is a method? A method is a way of running an ‘encapsulated’ series of commands. System.out.println(“ Whazzup ”); JOptionPane.showMessageDialog(null,
Loops Repeat after me …. Loops A loop is a control structure in which a statement or set of statements execute repeatedly How many times the statements.
Chapter 8 Testing and Debugging Goals To learn how to carry out unit tests To understand the principles of test case selection and evaluation To learn.
16/27/2015 3:38 AM6/27/2015 3:38 AM6/27/2015 3:38 AMTesting and Debugging Testing The process of verifying the software performs to the specifications.
Software Testing. “Software and Cathedrals are much the same: First we build them, then we pray!!!” -Sam Redwine, Jr.
ECE122 L17: Method Development and Testing April 5, 2007 ECE 122 Engineering Problem Solving with Java Lecture 17 Method Development and Testing.
CS1101: Programming Methodology Aaron Tan.
1 Functional Testing Motivation Example Basic Methods Timing: 30 minutes.
System/Software Testing
Fruitful functions. Return values The built-in functions we have used, such as abs, pow, int, max, and range, have produced results. Calling each of these.
Testing. What is Testing? Definition: exercising a program under controlled conditions and verifying the results Purpose is to detect program defects.
Testing. Definition From the dictionary- the means by which the presence, quality, or genuineness of anything is determined; a means of trial. For software.
Test plans CSCI102 - Systems ITCS905 - Systems MCS Systems.
© The McGraw-Hill Companies, 2006 Chapter 4 Implementing methods.
Testing CSE 140 University of Washington 1. Testing Programming to analyze data is powerful It’s useless if the results are not correct Correctness is.
Week 5 - Wednesday.  What did we talk about last time?  Exam 1!  And before that?  Review!  And before that?  if and switch statements.
1 Principles of Computer Science I Prof. Nadeem Abdul Hamid CSC 120 – Fall 2005 Lecture Unit 10 - Testing.
Chapter 10 Testing and Debugging. Chapter Goals To learn how to carry out unit tests To understand the principles of test case selection and evaluation.
Chapter 10 – Testing and Debugging. Chapter Goals ► Learn techniques to test your code ► Learn to carry out unit tests ► Understand principles of test.
Fall 2006Adapted from Java Concepts Companion Slides1 Testing and Debugging Advanced Programming ICOM 4015 Lecture 9 Reading: Java Concepts Chapter 10.
©2000, John Wiley & Sons, Inc. Horstmann/Java Essentials, 2/e Chapter 8: Testing and Debugging 1 Chapter 8 Testing and Debugging.
Debugging in Java. Common Bugs Compilation or syntactical errors are the first that you will encounter and the easiest to debug They are usually the result.
Dr. Tom WayCSC Testing and Test-Driven Development CSC 4700 Software Engineering Based on Sommerville slides.
Testing and Debugging Version 1.0. All kinds of things can go wrong when you are developing a program. The compiler discovers syntax errors in your code.
Testing Methods Carl Smith National Certificate Year 2 – Unit 4.
Testing. 2 Overview Testing and debugging are important activities in software development. Techniques and tools are introduced. Material borrowed here.
Problem of the Day  Why are manhole covers round?
Introduction to Software Testing. Types of Software Testing Unit Testing Strategies – Equivalence Class Testing – Boundary Value Testing – Output Testing.
1 Intro to Java Week 12 (Slides courtesy of Charatan & Kans, chapter 8)
COMP 121 Week 1: Testing and Debugging. Testing Program testing can be used to show the presence of bugs, but never to show their absence! ~ Edsger Dijkstra.
Chapter 22 Developer testing Peter J. Lane. Testing can be difficult for developers to follow  Testing’s goal runs counter to the goals of the other.
Chapter 10 Testing and Debugging. Chapter Goals ► To learn how to carry out unit tests ► To understand the principles of test case selection and evaluation.
The Software Development Process
Java Basics Hussein Suleman March 2007 UCT Department of Computer Science Computer Science 1015F.
1 Debugging and Syntax Errors in C++. 2 Debugging – a process of finding and fixing bugs (errors or mistakes) in a computer program.
Week 14 Introduction to Computer Science and Object-Oriented Programming COMP 111 George Basham.
Design - programming Cmpe 450 Fall Dynamic Analysis Software quality Design carefully from the start Simple and clean Fewer errors Finding errors.
Scientific Debugging. Errors in Software Errors are unexpected behaviors or outputs in programs As long as software is developed by humans, it will contain.
1 Chapter 8: Testing and Debugging  Chapter Goals To learn how to design test harnesses for testing components of your programs in isolationTo learn how.
Software Construction Lecture 19 Software Testing-2.
Testing CSE 160 University of Washington 1. Testing Programming to analyze data is powerful It’s useless (or worse!) if the results are not correct Correctness.
Software Quality Assurance and Testing Fazal Rehman Shamil.
PROGRAMMING TESTING B MODULE 2: SOFTWARE SYSTEMS 22 NOVEMBER 2013.
CompSci 100E 18.1 Testing and Debugging Robert A Wagner.
Dynamic Testing.
1 The Software Development Process ► Systems analysis ► Systems design ► Implementation ► Testing ► Documentation ► Evaluation ► Maintenance.
Efficiently Solving Computer Programming Problems Doncho Minkov Telerik Corporation Technical Trainer.
SOFTWARE TESTING LECTURE 9. OBSERVATIONS ABOUT TESTING “ Testing is the process of executing a program with the intention of finding errors. ” – Myers.
Debugging and Testing Hussein Suleman March 2007 UCT Department of Computer Science Computer Science 1015F.
MOOR ERROR HANDLING Types of error How to test your code for errors How to detect errors How to recover from errors.
Testing and Debugging UCT Department of Computer Science Computer Science 1015F Hussein Suleman March 2009.
Testing Tutorial 7.
Software Testing.
Testing and Debugging.
Testing UW CSE 160 Winter 2017.
Loop Structures.
Chapter 10 Testing and Debugging
Testing UW CSE 160 Spring 2018.
Chapter 15 Debugging.
Test Case Test case Describes an input Description and an expected output Description. Test case ID Section 1: Before execution Section 2: After execution.
CSE 1020:Software Development
Presentation transcript:

Chapter 10 – Testing and Debugging

Goals Learn techniques to test your code Learn techniques to test your code Learn to carry out unit tests Learn to carry out unit tests Understand principles of test case selection and evaluation Understand principles of test case selection and evaluation Learn to use logging Learn to use logging Become familiar with a debugger Become familiar with a debugger

Unit Testing The single most important testing tool The single most important testing tool Checks a single method or a set of cooperating methods Checks a single method or a set of cooperating methods You don't test the complete program that you are developing; you test the classes in isolation You don't test the complete program that you are developing; you test the classes in isolation

Unit Testing Avoids confusion of interactions Avoids confusion of interactions More startup cost, but less work in the end More startup cost, but less work in the end Analogy: Testing car Analogy: Testing car

Test Harness For each test, you provide a simple class called a test harness For each test, you provide a simple class called a test harness Test harness feeds parameters to the methods being tested Test harness feeds parameters to the methods being tested

Example To compute the square root of a use a common algorithm: To compute the square root of a use a common algorithm: Guess a value x that might be somewhat close to the desired square root (x = a is ok) Guess a value x that might be somewhat close to the desired square root (x = a is ok) Actual square root lies between x and a/x Actual square root lies between x and a/x Take midpoint (x + a/x) / 2 as a better guess Take midpoint (x + a/x) / 2 as a better guess Repeat the procedure. Stop when two successive approximations are very close to each other Repeat the procedure. Stop when two successive approximations are very close to each other

Example Method converges rapidly. Square root of 100: Guess #1: 50.5 Guess #2: Guess #3: Guess #4: Guess #5: Guess #6: Guess #7: Guess #8: 10.0 Method converges rapidly. Square root of 100: Guess #1: 50.5 Guess #2: Guess #3: Guess #4: Guess #5: Guess #6: Guess #7: Guess #8: 10.0

Testing RootApproximator class RootApproximator class getRoot() getRoot() nextGuess() nextGuess() Numeric class Numeric class approxEqual(double, double) approxEqual(double, double)

06:public class RootApproximatorTester 07:{ 08: public static void main(String[] args) 09: { 10: System.out.print("Enter a number: "); 11: Scanner in = new Scanner(System.in); 12: double x = in.nextDouble(); 13: RootApproximator r = new RootApproximator(x); 14: final int MAX_TRIES = 10; 15: for (int tries = 1; tries <= MAX_TRIES; tries++) 16: { 17: double y = r.nextGuess(); 18: System.out.println("Guess #"+tries+ ": " + y); 19:} 20: System.out.println("Square root: " + r.getRoot()); 21: } 22:}

Unit Testing What is needed to make the testing more robust? What is needed to make the testing more robust? More tests More tests Limitation: Hard to replicate tests when bugs are fixed Limitation: Hard to replicate tests when bugs are fixed Solution: Use test harness to repeat values Solution: Use test harness to repeat values

Providing Test Input Solution #1: Hardwire series of tests Solution #1: Hardwire series of tests No need to memorize series of tests, already taken care of. Just run tester class. No need to memorize series of tests, already taken care of. Just run tester class.

public class RootApproximatorHarness1 { public static void main(String[] args) { double[] testInputs = { 100, 4, 2, 1, 0.25, 0.01 }; for (int x = 0; x < testInputs.length; x++) { RootApproximator r = new RootApproximator(testInputs[x]); double y = r.getRoot(); System.out.println("square root of " + testInputs[x] + " = " + y); }}}

Generate Test Cases Automatically Instead of hardcoding array of values Instead of hardcoding array of values 1. Loop through a sample range of values for (int x = MIN; x <= MAX; x += INCREMENT){ RootApproximator r = new RootApproximator(x); double y = r.getRoot(); System.out.println("square root of " + x + " = " + y); }

Generate Test Cases Automatically Instead of hardcoding array of values Instead of hardcoding array of values 2. Use random number generator final int SAMPLES = 100; Random generator = new Random(); for (int i = 0; i < SAMPLES; i++){ double x = 1000 * generator.nextDouble(); RootApproximator r = new RootApproximator(x); double y = r.getRoot(); System.out.println("square root of " + x + " = " + y); }

What to Test for? Good testing requires testing good cases Good testing requires testing good cases Reduces debugging time and ensures better product Reduces debugging time and ensures better product Test all of the features of the method Test all of the features of the method Positive tests – normal behavior of method Positive tests – normal behavior of method Boundary test cases (e.g. x = 0), make sure end conditions are correct Boundary test cases (e.g. x = 0), make sure end conditions are correct Negative cases – program should reject Negative cases – program should reject

Test Case Evaluation How do you know whether the output is correct? How do you know whether the output is correct? Calculate correct values by hand E.g., for a payroll program, compute taxes manually Calculate correct values by hand E.g., for a payroll program, compute taxes manually Supply test inputs for which you know the answer E.g., square root of 4 is 2 and square root of 100 is 10 Supply test inputs for which you know the answer E.g., square root of 4 is 2 and square root of 100 is 10 Verify that the output values fulfill certain properties E.g., square root squared = original value Verify that the output values fulfill certain properties E.g., square root squared = original value

for (int i = 1; i <= SAMPLES; i++) { double x = 1000 * generator.nextDouble(); RootApproximator r = new RootApproximator(x); double y = r.getRoot(); if (Numeric.approxEqual(y * y, x)){ System.out.print("Test passed: "); passcount++; } else { System.out.print("Test failed: "); failcount++;} System.out.println("x = " + x 37: + ", root squared = " + y * y); }

Test Case Evaluation Use an Oracle: a slow but reliable method to compute a result for testing purposes E.g., use Math.pow to slower calculate x 1/2 (equivalent to the square root of x) Use an Oracle: a slow but reliable method to compute a result for testing purposes E.g., use Math.pow to slower calculate x 1/2 (equivalent to the square root of x)

for (int i = 1; i <= SAMPLES; i++) { double x = 1000 * generator.nextDouble(); RootApproximator r = new RootApproximator(x); double y = r.getRoot(); double oracleValue = Math.pow(x, 0.5); if (Numeric.approxEqual(y,oracleValue)){ System.out.print("Test passed: "); passcount++; } else { System.out.print("Test failed: "); failcount++;}}

Regression Testing and Test Coverage Save test cases Save test cases Particularly tests that reveal bugs Particularly tests that reveal bugs Use saved test cases in subsequent versions Use saved test cases in subsequent versions A test suite is a set of tests for repeated testing A test suite is a set of tests for repeated testing

Why keep a test case? Very common for bugs to show up later Very common for bugs to show up later We often think we fixed a bug, but just covered it up We often think we fixed a bug, but just covered it up Cycling = bug that is fixed but reappears in later versions Cycling = bug that is fixed but reappears in later versions Regression testing: repeating previous tests to ensure that known failures of prior versions do not appear in new versions Regression testing: repeating previous tests to ensure that known failures of prior versions do not appear in new versions

Test Coverage Test coverage: measure of how many parts of a program have been tested Test coverage: measure of how many parts of a program have been tested Good testing tests all parts of the program Good testing tests all parts of the program E.g. every line of code is executed in at least one test E.g. every line of code is executed in at least one test Example: Test all possible branches inside of an if statement Example: Test all possible branches inside of an if statement In Tax code program, 6 tests (3 $ brackets * 2 types of status) In Tax code program, 6 tests (3 $ brackets * 2 types of status)

Test Coverage Black-box testing: test functionality without consideration of internal structure of implementation Black-box testing: test functionality without consideration of internal structure of implementation Useful since this is what the user interacts with Useful since this is what the user interacts with White-box testing: take internal structure into account when designing tests White-box testing: take internal structure into account when designing tests Unit testing Unit testing Why? Cannot prove absence of bugs, only presence Why? Cannot prove absence of bugs, only presence

Testing Levels The part of the program that is being tested. The part of the program that is being tested. System System Unit Unit

System Level Testing Test interactions of the various parts of the application. Test interactions of the various parts of the application. Completed after the unit tests pass. Completed after the unit tests pass.

Unit Level Testing Test individual units (classes) in isolation. Test individual units (classes) in isolation. Test features of the unit. Test features of the unit. Multiple test cases for each feature. Multiple test cases for each feature.

Black Box Testing a.k.a. behavioral, functional, closed a.k.a. behavioral, functional, closed against the specification against the specification does not need the program source does not need the program source internal implementation is unknown internal implementation is unknown

Black Box Testing Advantages: Advantages: designed from the specifications designed from the specifications user's point of view user's point of view less biased less biased can discover if part of the specification has not been fulfilled. can discover if part of the specification has not been fulfilled.

Black Box Testing Disadvantages: Disadvantages: may be redundant may be redundant can be difficult to design. can be difficult to design. testing every possible input stream is unrealistic testing every possible input stream is unrealistic

White Box Testing a.k.a. structural, clear box, open a.k.a. structural, clear box, open tests against the implementation tests against the implementation every line of source code is executed at least once. every line of source code is executed at least once. tests exception handling code. tests exception handling code.

White Box Testing Advantages Advantages can discover if any part is faulty can discover if any part is faulty test coverage (test all paths) test coverage (test all paths) Disadvantages Disadvantages will not discover if part is missing will not discover if part is missing only if the programmer knows what the program is supposed to do only if the programmer knows what the program is supposed to do code must also be visible to the tester. code must also be visible to the tester.

"Fully" Tested To fully test a software product, the following are required: To fully test a software product, the following are required: unit testing and system level testing unit testing and system level testing black and white box testing black and white box testing Does this ensure there are no bugs? Does this ensure there are no bugs?

Testing Tips Develop cases to take into account end conditions Develop cases to take into account end conditions Tip: write first test cases before program is written completely → gives insight into what program should do Tip: write first test cases before program is written completely → gives insight into what program should do Build up as program goes along and bugs are found Build up as program goes along and bugs are found

Logging To figure out where your program “goes”, use program trace statements To figure out where your program “goes”, use program trace statements Help determine the “flow” of execution Help determine the “flow” of execution if (status == SINGLE) { System.out.println("status is SINGLE");... }

Problem When done debugging, have to remove all System.out.println trace messages When done debugging, have to remove all System.out.println trace messages What if we find a bug again? What if we find a bug again? Solution: Create a separate class for the purpose of logging Solution: Create a separate class for the purpose of logging

Logging Logging messages can be deactivated when testing is complete Logging messages can be deactivated when testing is complete Use global object Logger.global in place of System.out Use global object Logger.global in place of System.out Log a message Log a message Logger.global.info("status is SINGLE");

Turn off/on How does this class help? How does this class help? Can easily switch logging on and off Can easily switch logging on and off Default: On Default: On To turn off, insert at top of main(): To turn off, insert at top of main():Logger.global.setLevel(Level.OFF);

What to print out Common to need to know enter/exit conditions of methods Common to need to know enter/exit conditions of methods public TaxReturn(double anIncome, int aStatus){ Logger.global.info("Parameters: anIncome = " + anIncome + " aStatus = " + aStatus);... }//Exit public double getTax(){... Logger.global.info("Return value = " + tax); return tax; }

Logging Obviously other output is needed Obviously other output is needed Bug is that certain condition isn’t true when it is supposed to be – track values as you go along Bug is that certain condition isn’t true when it is supposed to be – track values as you go along Logging class has many other options (see API) Logging class has many other options (see API) Disadvantages: Disadvantages: Time consuming Time consuming Too much/little output Too much/little output

Debuggers To avoid logging problems, most professionals use a debugger To avoid logging problems, most professionals use a debugger Programs rarely (never) run perfectly the first time Programs rarely (never) run perfectly the first time Think of perfect first draft to paper Think of perfect first draft to paper The larger your programs, the harder to debug them simply by logging The larger your programs, the harder to debug them simply by logging

Debuggers Most current development environments contain a debugger Most current development environments contain a debugger Debugger - program to run your program and analyze its run-time behavior Debugger - program to run your program and analyze its run-time behavior A debugger lets you stop and restart your program, see contents of variables, and step through it A debugger lets you stop and restart your program, see contents of variables, and step through it

Debuggers Debuggers can be part of your IDE (Eclipse, BlueJ) or separate programs (JSwat) Debuggers can be part of your IDE (Eclipse, BlueJ) or separate programs (JSwat) Three key concepts: Three key concepts: Breakpoints Breakpoints Single-stepping Single-stepping Inspecting variables Inspecting variables

Breakpoint Breakpoint – the debugger doesn’t stop running the program until it hits a defined breakpoint Breakpoint – the debugger doesn’t stop running the program until it hits a defined breakpoint Setup by programmer Setup by programmer Once stopped, you can see the state of all the variables Once stopped, you can see the state of all the variables

Step-through Once a breakpoint is hit, two options Once a breakpoint is hit, two options Step through the next few statements carefully inspecting Step through the next few statements carefully inspecting Slow, but useful in heavy calculations Slow, but useful in heavy calculations Single-step – line by line execution Single-step – line by line execution Step into – doesn’t just skip line to line, but goes into method calls within each line Step into – doesn’t just skip line to line, but goes into method calls within each line Step over – Execute the enter statement and stop Step over – Execute the enter statement and stop Run at full speed until the next breakpoint Run at full speed until the next breakpoint

Example Current line: Current line: String input = in.next(); Word w = new Word(input); int syllables = w.countSyllables(); System.out.println("Syllables in " + input + ": " + syllables);

Step Over Next step: Next step: String input = in.next(); Word w = new Word(input); int syllables = w.countSyllables(); System.out.println("Syllables in " + input + ": " + syllables);

Step Into public int countSyllables() { int count = 0; int end = text.length() - 1;... }

Which to choose If the method is suspect (it may be the cause of a problem) – Step into If the method is suspect (it may be the cause of a problem) – Step into If you are sure the method works correctly – step over If you are sure the method works correctly – step over

What if a test fails? It's time to debug! It's time to debug! We will want (need) a strategy. We will want (need) a strategy. Debugging Strategy Debugging Strategy A systematic way to find and fix bugs. A systematic way to find and fix bugs.

Debug Strategy 1: Trial & Error 1. Write code 2. Run program 3. Fix bugs Advantages Advantages no planning required no planning required Disadvantages Disadvantages Spend more time trying to find and fix bugs than you did writing the program. Spend more time trying to find and fix bugs than you did writing the program.

Debug Strategy 2: Trial & Error with a Debugger 1. Write code 2. Run program 3. Use Debugger program to fix bugs Advantages Advantages no planning required no planning required Disadvantages Disadvantages Spend lots of time in the debugger program trying to find and fix the bugs Spend lots of time in the debugger program trying to find and fix the bugs

Debug Strategy 3: Incremental Development with Testing 1. Write small amount of code with testing and debugging in mind. 2. Document and write tests for each new piece of code. 3. Run tests on new code 4. Fix any bugs before adding new code. Disadvantage: Sometimes you have to debug code that you didn't write. Disadvantage: Sometimes you have to debug code that you didn't write.

Debug Strategy 3: Incremental Development with Testing Disadvantages Disadvantages Takes more time (harder) to design the solution Takes more time (harder) to design the solution Must write more code (tests) Must write more code (tests) Only possible if you're the one who wrote the program Only possible if you're the one who wrote the program Advantages Advantages A small amount of code to review and fix. A small amount of code to review and fix. Bug is fixed before it get hidden by some other bug. Bug is fixed before it get hidden by some other bug. If small parts work, the bigger parts will usually work too. If not, it's only the public interfaces that have to be debugged. If small parts work, the bigger parts will usually work too. If not, it's only the public interfaces that have to be debugged.

Debugging Strategy 4: Test and use a Debugger 1. Identify the bug. Must be repeatable and testable. 2. Write test(s) that fails for the bug. 3. Locate the source of the bug. HOW? 4. Understand the problem before you fix it. 5. Try your fix and run all tests. 6. Repeat until all tests pass.

How do we find the source of the bug? Pick a point to start looking Pick a point to start looking Beginning (main method) Beginning (main method) Divide and conquer Divide and conquer Trace the code. ( Look for variables with unexpected values) Trace the code. ( Look for variables with unexpected values) Manual trace Manual trace Trace messages Trace messages System.out.println(…) System.out.println(…) Java 1.5: Use java.util.logging.Logger class Java 1.5: Use java.util.logging.Logger class Debugger program Debugger program