How I Learned to Stop Worrying & Love the Bug

Slides:



Advertisements
Similar presentations
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.
Advertisements

CMSC 345, Version 11/07 SD Vick from S. Mitchell Software Testing.
Integration testing Satish Mishra
Illinois Institute of Technology
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.
Testing an individual module
CSC 395 – Software Engineering Lecture 9: Testing -or- How I Stopped Worrying and Learned to Love the Bug.
1 These courseware materials are to be used in conjunction with Software Engineering: A Practitioner’s Approach, 5/e and are provided with permission by.
Chapter 13 & 14 Software Testing Strategies and Techniques
Unit Testing & Defensive Programming. F-22 Raptor Fighter.
P51UST: Unix and Software Tools Unix and Software Tools (P51UST) Compilers, Interpreters and Debuggers Ruibin Bai (Room AB326) Division of Computer Science.
Testing. What is Testing? Definition: exercising a program under controlled conditions and verifying the results Purpose is to detect program defects.
1 Debugging and Testing Overview Defensive Programming The goal is to prevent failures Debugging The goal is to find cause of failures and fix it Testing.
Testing -- Part II. Testing The role of testing is to: w Locate errors that can then be fixed to produce a more reliable product w Design tests that systematically.
Question of the Day  On a game show you’re given the choice of three doors: Behind one door is a car; behind the others, goats. After you pick a door,
Testing. 2 Overview Testing and debugging are important activities in software development. Techniques and tools are introduced. Material borrowed here.
Unit Testing 101 Black Box v. White Box. Definition of V&V Verification - is the product correct Validation - is it the correct product.
CSC 395 – Software Engineering Lecture 10: Execution-based Testing –or– We can make it better than it was. Better...faster...agiler.
What is Testing? Testing is the process of finding errors in the system implementation. –The intent of testing is to find problems with the system.
Software Engineering 2004 Jyrki Nummenmaa 1 BACKGROUND There is no way to generally test programs exhaustively (that is, going through all execution.
CSC 213 – Large Scale Programming. Today’s Goal  Understand why testing code is important  Result of poor or no testing & embarrassment caused  Learn.
CSC 395 – Software Engineering Lecture 27: White-Box Testing.
SWE 434 SOFTWARE TESTING AND VALIDATION LAB2 – INTRODUCTION TO JUNIT 1 SWE 434 Lab.
Chapter 17 Software Testing Techniques
Lecture 5: Test-Driven Development Basics
Software Testing.
Unit Testing.
14 Compilers, Interpreters and Debuggers
User-Written Functions
Programming Logic and Design Seventh Edition
CHAPTER 4 REPETITION CONTROL STRUCTURE / LOOPING
Rekayasa Perangkat Lunak Part-13
John D. McGregor Session 9 Testing Vocabulary
Testing and Debugging.
Loop Structures.
Chapter 13 & 14 Software Testing Strategies and Techniques
John D. McGregor Session 9 Testing Vocabulary
Java Programming: Guided Learning with Early Objects
Lecture 07 More Repetition Richard Gesick.
Software Engineering 1, CS 355 Unit Testing with JUnit
Lecture 4B More Repetition Richard Gesick
Unit testing C# classes
Testing UW CSE 160 Spring 2018.
UNIT-4 BLACKBOX AND WHITEBOX TESTING
John D. McGregor Session 9 Testing Vocabulary
Topics Introduction to File Input and Output
Lecture 09:Software Testing
Arrays in Java What, why and how Copyright Curt Hill.
Coding Concepts (Basics)
Coding Concepts (Standards and Testing)
Algorithm Discovery and Design
If selection construct
CSE 303 Concepts and Tools for Software Development
Chapter 10 – Software Testing
Automation of Testing in the Distributed Common Ground System (Army)
Automation of Testing in the Distributed Common Ground System (Army)
Test Case Test case Describes an input Description and an expected output Description. Test case ID Section 1: Before execution Section 2: After execution.
Control Structure Testing
CS 240 – Advanced Programming Concepts
Test Driven Lasse Koskela Chapter 9: Acceptance TDD Explained
An Introduction to Debugging
CMSC 345 Programming.
CSE 143 Lecture 5 More ArrayIntList:
Review of Previous Lesson
CHAPTER 6 Testing and Debugging.
UNIT-4 BLACKBOX AND WHITEBOX TESTING
Chapter 1: Creating a Program.
Software Testing.
Chapter 13 & 14 Software Testing Strategies and Techniques 1 Software Engineering: A Practitioner’s Approach, 6th edition by Roger S. Pressman.
Presentation transcript:

How I Learned to Stop Worrying & Love the Bug Picture Courtesy of: Prof. Sarah Ford, M.A. (a.k.a. Mrs. Matthew Hertz) How I Learned to Stop Worrying & Love the Bug

Secret of Good Code Good Code Works

Good Code Works

Can They Offer Any Proof? Questions For Testing What is correct? Who gets to decide? How do they know? Can They Offer Any Proof? Apologize if this gets a bit philosophical

Can They Offer Any Proof? Questions For Testing What is correct? Can They Offer Any Proof? Apologize if this gets a bit philosophical

Can They Offer Any Proof? Questions For Testing What is correct? Can They Offer Any Proof? Can check code against design (“verification”), but that is useful only if the design was correct (“validation”). Analysis was an agreement about what program should do and so everything will need to tie back to that document.

Who Gets to Decide? Deadline-focused Ego-driven Knows artifact correct Original Author Testing Team Member Deadline-focused Ego-driven Knows artifact correct Rewarded for writing good artifact quickly Quality-focused Ego-driven Doubts correctness Rewarded for finding every possible bug Given this, think about what tests would actually look like…

Tests the Authors Write

Tests Testers Write

Write Code For Testing Quality of product decided by testing Testing properties targeted when writing code

Write Code For Testing Quality of product decided by testing Testing properties targeted when writing code Ultimately, you have a very simple choice

Write Code For Testing Quality of product decided by testing or Testing properties targeted when writing code Ultimately, you have a very simple choice or

Test-Driven Development (TDD) Very popular technique developing software

Test-Driven Development (TDD) Very popular technique developing software Greatly increases programmer productivity Happier programmers also found when using TDD Requires very different approach to coding Write tests BEFORE begin implementation process Write stubs (but no code) for class & methods Knowing correct outputs, write tests to check Implement methods to pass your tests (& check often)

Common Objection To TDD But… How could I write tests before I know what the method does?

Smart Programmer Responds… How could you write the code before you know what the method must do?

TDD Objections Feels weird to start with tests when you first try… .. but objections reflect poor habits checking code Know method’s outcomes when starting to write… … but you may not know how it will be done

Thought Experiment Have new engine uses 100x less gas New power generation method provides this boost Of the following which test do you want: Belts and axels moved identically with new engine New engine still uses same carburetor & pistons

NOT method's process, checked in test cases Primary Concept of TDD Method's effects, NOT method's process, checked in test cases

Why TDD Helps Many benefits when test cases created first Clarify what method does so coding becomes easier Since written for tests, methods become easier to fix Know when code done by checking if tests pass Studies have found that TDD simplifies debugging Know when bug created by running tests regularly Tests start to fail after writing 1 line: bug on that line Bugs… somewhere(?) when hours pass before testing

Unit Testing Library Nearly all Java uses JUnit for unit testing Tests written in Java so can run anywhere Strong support that make writing tests very easy JUnit support in most IDEs (e.g., Eclipse, IntelliJ, BlueJ) Not limited to Java – xUnit exists for many languages Automation important to allow frequent testing Testing easy – just select “Run As…” “JUnit test” Green means good – checking results also very easy Easy to see problems – see red when tests fail

JUnit Test Cases Format Most often write test class for each class Identical to other classes; usually named ____Test As a Java class, can use inheritance & have fields Inheritance & fields not required like any Java class Since ver. 4.0, JUnit’s annotations identify tests Extra information added to show method is test case Annotation added immediately before method

JUnit Test Cases Format Most often write test class for each class Identical to other classes; usually named ____Test As a Java class, can use inheritance & have fields Inheritance & fields not required like any Java class Since ver. 4.0, JUnit’s annotations identify tests Extra information added to show method is test case Annotation added immediately before method No code or comments between annotation & method

Statements Performing Checks assertEquals(X expected, X actual) assertEquals(float exp, float act, float tol) assertEquals(double exp, double act,double tol) assertTrue(boolean test) assertFalse(boolean test) assertNull(Object objTest) assertNotNull(Object objTest) fail()

JUnit Annotations Loop until all test cases in class are executed JUnit executes all methods marked @Before Optional methods initialize any data before each test Run exactly 1 method labeled @Test executed Pass if no crashes & no incorrect asserts occur during test Fails & stops running when assert____ does not pass Executes all methods marked @After Also optional, cleans mess made by @Before

Statements Performing Checks assertEquals(X expected, X actual) assertEquals(float exp, float act, float tol) assertEquals(double exp, double act,double tol) assertTrue(boolean test) assertFalse(boolean test) assertNull(Object objTest) assertNotNull(Object objTest) fail() @Test method should have 1 or more assert* statement. Requires testing assertion for method to fail.

Writing Test Methods Test methods MUST have @Test annotation Non-static, void methods only for JUnit to work By same logic, test methods cannot have parameters Use normal Java code to write these test methods Just normal methods; can contain any legal Java code Conditionals and loop statements occasionally included Can instantiate objects and call methods on objects Other methods can use assert___ & be called by tests

Class To Be Tested public class Operational { private int a, b; public Operational(int fst, int snd) { a = fst; b = snd; } public String multiply() { int product = a * b; return “Product is ”+product; } public String sum() { return “Sum is ”+a+b; } }

Class To Be Tested public class Operational { private int a, b; public Operational(int fst, int snd) { a = fst; b = snd; } public String multiply() { int product = a * b; return “Product is ”+product; } public String sum() { return “Sum is ”+a+b; } } This concatenates a & b (like Strings) rather than adding them. So 3 + 2 will be 32 and not 5. Our tests need to find this!

Starting to Write Test Cases Traditionally, test class adds “Test” to class name Each case is method having @Test annotation Should have at least 1 call to assertion method public class OperationalTest { @Test public void testMult0() { Operational xByZero = new Operational(3, 0); Operational zeroByX = new Operational(0, 17); assertEquals(“Product is 0”, xByZero.multiply()); assertEquals(“Product is 0”, zeroByX.multiply()); }

Bad Tests to Write Only get to know test failed with assertTrue() @Test public void yuckyButLegal() { Operational xByOne = new Operational(-2, 1); Operational oneByX = new Operational(1, 4); assertTrue(xByOne.multiply() .equals(“Product is -2”)); assertFalse(!“Product is 4”.equals( oneByX.multiply()); }

More Test Gotchas Must be certain assert___ checking code to test @Test public void whatAmITesting() { Operational xByOne = new Operational(-2, 1); assertEquals(“Product is -2”, “Product is ” + (-2 * 1)); } @Test public void passingIsNotFailing() { Operational xByOne = new Operational(-2, 1); xByOne.sum(); }

Hardcode Your Checks Hardcode answer in assert___ whenever possible @Test public void shouldNotPassButDoesPass() { Operational xByOne = new Operational(-2, 1); assertEquals(“Sum is ” + -2 + 1, xByOne.sum()); }

Hardcode Your Checks Hardcode answer in assert___ whenever possible @Test public void shouldNotPassButDoesPass() { Operational xByOne = new Operational(-2, 1); assertEquals(“Sum is ” + -2 + 1, xByOne.sum()); }

Hardcode Your Checks Hardcode answer in assert___ whenever possible @Test public void shouldNotPassButDoesPass() { Operational xByOne = new Operational(-2, 1); assertEquals(“Sum is ” + -2 + 1, xByOne.sum()); }

Hardcode Your Checks Hardcode answer in assert___ whenever possible @Test public void canNowFindBug() { Operational xByOne = new Operational(-2, 1); assertEquals(“Sum is -1”, xByOne.sum()); }

What Test Cases Do Declare variable(s), create objects, & prep inputs Call the method being tested Use specification to verify returned value correct Check fields for changes matching requirements Should also verify other fields did not change Assert array & object arguments are correct

How Do They Know? Avoid wasting time fixing the wrong thing Check artifacts from simplest to most complex JUnit always follow order test cases appear in file Write tests checking the easiest methods first Methods calling those are next to get tested Finally, test the most complex methods last Which card should this guy grab?

How Do They Know? Avoid wasting time fixing the wrong thing Check artifacts from simplest to most complex JUnit always follow order test cases appear in file Write tests checking the easiest methods first Methods calling those are next to get tested Finally, test the most complex methods last Which card should this guy grab?

Evaluating Test Efforts Develop tests with detailed look at the algorithm Test coverage discussed often by people, but… … coverage can be measured many ways Statement coverage Run each statement at least once Branch coverage Run each branch at least once Path coverage Run each possible branch combination at least once Detail Increases

Coverage Measures All Statements: All Branches: All Paths: 2 4 1 3 5 All Statements: 1, 2, 3, 4, 5 All Branches: 1, 2, 3, 4, 5 1, 3, 5 All Paths: 1, 2, 3, 4, 5 1, 2, 3, 5 1, 3, 4, 5 1, 3, 5 Point out that all paths is just not really possible… State that we can check for all statements testing (e.g., the minimum acceptable level) in Eclipse directly!

How To Write Tests Cannot prove there are no bugs Can only show no bugs exist on those tests Picture is of Edsgar Dijkstra of Dijkstra’s algorithm (and just about everything else not done by Knuth) fame.

Testing shows the presence, not the absence of bugs How To Write Tests Cannot prove there are no bugs Can only show no bugs exist on those tests Testing shows the presence, not the absence of bugs Picture is of Edsgar Dijkstra of Dijkstra’s algorithm (and just about everything else not done by Knuth) fame.

What To Test & Why 20% of code has 80% of bugs Limited budgets require focused, not full, testing Add some tests for typical cases/paths, but this is probably well thoughtout & planned Developers & Alpha testers will find all the obvious issues when they run the program Focus on the alternate paths & odd branches – this is what your customers will do (Animation 1) More complex areas have more places for things to hide and harder to produce perfectly accurately (Animation 2) Join points can create unexpected problems – bridge in Laufenburg Germany/Switz. which went bad because the two countries account for Sea Level differently (Animation 3) They actually meant lap desks – the problem was really that terminology has changed! (Animation 4) I _always_ advertise price increases

What To Test & Why 20% of code has 80% of bugs versus Modules that are most complex, intricate, or detailed versus Limited budgets require focused, not full, testing Add some tests for typical cases/paths, but this is probably well thoughtout & planned Developers & Alpha testers will find all the obvious issues when they run the program Focus on the alternate paths & odd branches – this is what your customers will do (Animation 1) More complex areas have more places for things to hide and harder to produce perfectly accurately (Animation 2) Join points can create unexpected problems – bridge in Laufenburg Germany/Switz. which went bad because the two countries account for Sea Level differently (Animation 3) They actually meant lap desks – the problem was really that terminology has changed! (Animation 4) I _always_ advertise price increases

What To Test & Why 20% of code has 80% of bugs versus Modules that are most complex, intricate, or detailed Locations where expectations of data might differ versus Limited budgets require focused, not full, testing Add some tests for typical cases/paths, but this is probably well thoughtout & planned Developers & Alpha testers will find all the obvious issues when they run the program Focus on the alternate paths & odd branches – this is what your customers will do (Animation 1) More complex areas have more places for things to hide and harder to produce perfectly accurately (Animation 2) Join points can create unexpected problems – bridge in Laufenburg Germany/Switz. which went bad because the two countries account for Sea Level differently (Animation 3) They actually meant lap desks – the problem was really that terminology has changed! (Animation 4) I _always_ advertise price increases

What To Test & Why 20% of code has 80% of bugs Modules that are most complex, intricate, or detailed Locations where expectations of data might differ Code in transition: frequently changed modules Limited budgets require focused, not full, testing Add some tests for typical cases/paths, but this is probably well thoughtout & planned Developers & Alpha testers will find all the obvious issues when they run the program Focus on the alternate paths & odd branches – this is what your customers will do (Animation 1) More complex areas have more places for things to hide and harder to produce perfectly accurately (Animation 2) Join points can create unexpected problems – bridge in Laufenburg Germany/Switz. which went bad because the two countries account for Sea Level differently (Animation 3) They actually meant lap desks – the problem was really that terminology has changed! (Animation 4) I _always_ advertise price increases

What To Test & Why 20% of code has 80% of bugs Modules that are most complex, intricate, or detailed Locations where expectations of data might differ Code in transition: frequently changed modules Any place where program requires user input Limited budgets require focused, not full, testing Add some tests for typical cases/paths, but this is probably well thoughtout & planned Developers & Alpha testers will find all the obvious issues when they run the program Focus on the alternate paths & odd branches – this is what your customers will do (Animation 1) More complex areas have more places for things to hide and harder to produce perfectly accurately (Animation 2) Join points can create unexpected problems – bridge in Laufenburg Germany/Switz. which went bad because the two countries account for Sea Level differently (Animation 3) They actually meant lap desks – the problem was really that terminology has changed! (Animation 4) I _always_ advertise price increases

Input Tests Two tests to consider when input is Object Provide null as input since that often leads to crashes null probably unlikely, so also check with real instance Strings & Lists need more, since size matters Important to test case when size is 0 (empty list or “”) Testing on size of 1 provides easy debugging chance Simplify longer examples with test with input size of 2 Test using larger size since that is the common case

Input Tests Also have many common test cases for numbers Input equal to 0 since it is special (especially division) Simplify any debugging by using small input (1 or 2) Test a negative number since easy to overlook Assume bugs exist and check non-obvious case (like 11) Use non-whole numbers for float or double inputs Also should check on “magic numbers” for method Numbers included in description (or, later, in the code) Could also think to test values 1 higher & 1 lower, too

Input Tests

Types of Loops Simple Loop Concatenated Nested Loops Loops Unstructured Loops Nested Loops Concatenated Loops Simple Loop

Types of Loops Simple Loop Concatenated Nested Loops Loops Unstructured Loops Nested Loops Concatenated Loops Simple Loop

Simple Loop For all simple loops, try inputs that: Skip loop entirely Make 1 pass through the loop Make 2 passes through the loop Make m passes through the loop, where (m > 2) If loop executed at most n times, try inputs that: Make n-1 & n passes through the loop

Types of Loops Simple Loop Concatenated Nested Loops Loops Unstructured Loops Nested Loops Concatenated Loops Simple Loop

Nested Loops First test set runs all outer loops exactly once Inner loop runs (min+1), average, (max-1) & max times Then run all but two innermost loops exactly once Inner loops run (min+1), average, (max-1) & max times Tests should continue growing loop-by-loop

Types of Loops Simple Loop Concatenated Nested Loops Loops Unstructured Loops Nested Loops Concatenated Loops Simple Loop

Concatenated Loops If loops are entirely independent No conditions, variables, or values in common Woo-hoo! Just perform single loop tests on each Otherwise treat as nested loops & make life easier Work as if the first loop is the outermost loops

Types of Loops

Unstructured Loops Figure out the process leading to this decision Burn the artifacts creating this abomination Anyone involved should terminated immediately (Animate on terminate joke)

Unstructured Loops Figure out the process leading to this decision Burn the artifacts creating this abomination Anyone involved should terminated immediately (Animate on terminate joke)

Unstructured Loops Figure out the process leading to this decision Burn the artifacts creating this abomination Anyone involved should terminated immediately Rewrite “missing” documents, starting from scratch (Animate on terminate joke)

Where the Bugs Aren’t In real world, some cases may not be worth testing Must assume bugs exist so ideally test everything Save time, do not change input to check same idea No point in repeating tests unless results could differ Electricity costs money; do not waste on identical tests Pointless retesting case, test will not prove anything Pointless testing case again, does not help with coding

Where the Bugs Aren’t In real world, some cases may not be worth testing Must assume bugs exist so ideally test everything Save time, do not change input to check same idea No point in repeating tests unless results could differ Electricity costs money; do not waste on identical tests Pointless retesting case, test will not prove anything Pointless testing case again, does not help with coding

Where the Bugs Aren’t In real world, some cases may not be worth testing Must assume bugs exist so ideally test everything Save time, do not change input to check same idea Simple getters & setters rarely buggy, skip if limited Focus on possibilities, do not check for impossible cases

Where the Bugs Aren’t

What Do We Gain? Got from this…

What Do We Gain? Go from this… … to this

Life Lessons for $100 Once your code is complete and passes the unit tests, the worst thing you could do.

Life Lessons for $100 Once your code is complete and passes the unit tests, the worst thing you could do. Merge everything together at once

Why Is This a Bad Idea?

Life Lessons for $200 You (wisely) decide to integrate your modules one at a time, what should you then not do?

Life Lessons for $200 You (wisely) decide to integrate your modules one at a time, what should you then not do? Only use JUnit to do tests!

What Is Only Use JUnit? Integration testing goes through two phases Independent of method used to integrate modules Already been doing this, but in craptacular style Back-end modules combined during first phase All of the unit tests driven by mocking

What Is Only Use JUnit? Integration testing goes through two phases Independent of method used to integrate modules Already been doing this, but in craptacular style Back-end modules combined during first phase All of the unit tests driven by mocking

What Is Only Use JUnit? Integration testing goes through two phases Independent of method used to integrate modules Already been doing this, but in craptacular style Back-end modules combined during first phase All of the unit tests driven by mocks, stubs, & drivers Slowly replace with actual classes, but keep unit tests

Integration Testing Also need to test combination of modules Unit-level testing completed and passed already Incrementally go through and add modules to system If time to burn, add multiple modules at once Can be done using one of three approaches Top-down Bottom-up Sandwich

Top-Down Integration Modules tested with stubs for children Replace stubs one-by-one in depth-first manner Tests should be re-run with each integration A B F G Click twice! C D E

Bottom-Up Integration Use driver code to test modules at bottom Drivers replaced one-by-one in depth-first manner Modules integrated after grouped into clusters A B F G Only click twice! C D E

Sandwich Integration Stubs help test modules at top Modules at the bottom tested with drivers Bottom modules clustered & integrated together A B F G C D E

First Phase Verifies Only verifies code & that it matches design But what if the design is incorrect? Cannot validate code and that it is working properly For the back-end code important to verify first Could not be what client wanted, but still pass But this is back-end code, the client does not care

First Phase Verifies Only verifies code & that it matches design But what if the design is incorrect? Cannot validate code and that it is working properly For the back-end code important to verify first Could not be what client wanted, but still pass But this is back-end code, the client does not care

Second Phase Validates Second phase validates GUI front-end GUI classes can be checked against the use cases JUnit test cases less useful performing these tests Tests lack human touch; cannot check aesthetics Second phase needs more than simple JUnit tests Instead relies upon script defining actions & results Client happy with result is our ultimate goal

Other Testing Issues Utility: Is it useable or need an ad with Seinfeld?

Other Testing Issues Utility: Is it useable or need an ad with Seinfeld? Reliability: Will you end up subject on Dateline NBC?

Other Testing Issues Utility: Is it useable or need an ad with Seinfeld? Reliability: Will you end up subject on Dateline NBC? Robustness: How long of disclaimer will it need?

Other Testing Issues Utility: Is it useable or need an ad with Seinfeld? Reliability: Will you end up subject on Dateline NBC? Robustness: How long of disclaimer will it need? Performance: Will it finish before Buffalo wins title?