1 CSE 331 Unit Testing with JUnit slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R. Mercer, Wikipedia

Slides:



Advertisements
Similar presentations
11-Jun-14 The assert statement. 2 About the assert statement The purpose of the assert statement is to give you a way to catch program errors early The.
Advertisements

Slides adapted from Alex Mariakakis, with material from Krysta Yousoufian, Mike Ernst, and Kellen Donohue Section 4: Graphs and Testing.
MAHDI OMAR JUNIT TUTORIAL. CONTENTS Installation of Junit Eclipse support for Junit Using Junit exercise JUnit options Questions Links and Literature.
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.
GoogleTest Primer. Outline Basic Concepts Assertions Basic Assertions Binary Comparison String Comparison Floating-Point Comparison Simple Tests Test.
T ESTING WITH J UNIT IN E CLIPSE Farzana Rahman. I NTRODUCTION The class that you will want to test is created first so that Eclipse will be able to find.
Objectives: Test Options JUnit Testing Framework TestRunners Test Cases and Test Suites Test Fixtures JUnit.
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION SOFTWARE TESTING Autumn 2011 Creative Commons Attribution-Share Alike 3.0 Unported LicenseCreative Commons Attribution-Share.
11-Jun-15 Exceptions. 2 Errors and Exceptions An error is a bug in your program dividing by zero going outside the bounds of an array trying to use a.
1 Software Testing and Quality Assurance Lecture 23 – JUnit Tutorial.
JUnit. Why is testing good? Due to psychological factors, programmers are bad testers. A computer can test much faster than a human Philosophy: “If it.
24-Jun-15 JUnit. 2 Test suites Obviously you have to test your code to get it working in the first place You can do ad hoc testing (running whatever tests.
Software Testing. “Software and Cathedrals are much the same: First we build them, then we pray!!!” -Sam Redwine, Jr.
14-Jul-15 JUnit 4. Comparing JUnit 3 to JUnit 4 All the old assertXXX methods are the same Most things are about equally easy JUnit 4 makes it easier.
CSE 403 Lecture 13 Black/White-Box Testing Reading: Software Testing: Principles and Practices, Ch. 3-4 (Desikan, Ramesh) slides created by Marty Stepp.
1 Functional Testing Motivation Example Basic Methods Timing: 30 minutes.
Unit Testing & Defensive Programming. F-22 Raptor Fighter.
© Dr. A. Williams, Fall Present Software Quality Assurance – JUnit Lab 1 JUnit A unit test framework for Java –Authors: Erich Gamma, Kent Beck Objective:
System/Software Testing
Testing. What is Testing? Definition: exercising a program under controlled conditions and verifying the results Purpose is to detect program defects.
Computer Science and Engineering College of Engineering The Ohio State University JUnit The credit for these slides goes to Professor Paul Sivilotti at.
CSE 403 Lecture 12 Effective Unit Testing Reading: The Art of Unit Testing, Ch. 7 (Osherove) slides created by Marty Stepp
CSE 219 Computer Science III Testing. Testing vs. Debugging Testing: Create and use scenarios which reveal incorrect behaviors –Design of test cases:
Hello.java Program Output 1 public class Hello { 2 public static void main( String [] args ) 3 { 4 System.out.println( “Hello!" ); 5 } // end method main.
Programming for Beginners Martin Nelson Elizabeth FitzGerald Lecture 5: Software Design & Testing; Revision Session.
1.  Writing snippets of code that try to use methods (functions) from your program.  Each snippet should test one (and only one) function......by calling.
(1) Unit Testing and Test Planning CS2110: SW Development Methods These slides design for use in lab. They supplement more complete slides used in lecture.
Introduction to JUnit 3.8 SEG 3203 Winter ‘07 Prepared By Samia Niamatullah.
Unit Testing with JUnit and Clover Based on material from: Daniel Amyot JUnit Web site.
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.
JUnit. Introduction JUnit is an open source Java testing framework used to write and run repeatable tests JUnit is integrated with several IDEs, including.
1 CSE 403 Testing Reading: Code Complete, Ch. 22 (McConnell) Object-Oriented Software Engineering, Ch. 9 (B. Bruegge, A. Dutoit) These lecture slides are.
1 Unit Testing with JUnit CS 3331 JUnit website at Kent Beck and Eric Gamma. Test Infected: Programmers Love Writing Tests, Java Report,
CSE 143 Lecture 4 More ArrayIntList : Pre/postconditions; exceptions; testing reading: slides created by Marty Stepp and Hélène Martin
Building Java Programs Chapter 15 Lecture 15-2: testing ArrayIntList; pre/post conditions and exceptions reading:
Unit Testing. F-22 Raptor Fighter Manufactured by Lockheed Martin & Boeing How many parts does the F-22 have?
Unit Testing with FlexUnit
Justin Bare and Deric Pang with material from Erin Peach, Nick Carney, Vinod Rathnam, Alex Mariakakis, Krysta Yousoufian, Mike Ernst, Kellen Donohue Section.
Unit Testing in Eclipse Presented by David Eisler 08/09/2014.
Today protected access modifier Using the debugger in Eclipse JUnit testing TDD Winter 2016CMPE212 - Prof. McLeod1.
Testing (final thoughts). equals() and hashCode() Important when using Hash-based containers class Duration { public final int min; public final int sec;
CSE 143 Lecture 14: testing.
SWE 434 SOFTWARE TESTING AND VALIDATION LAB2 – INTRODUCTION TO JUNIT 1 SWE 434 Lab.
Black/White-Box Testing Reading:
Section 4: Graphs and Testing
CompSci 280 S Introduction to Software Development
Unit Testing.
They both stop working when you open Windows!
Unit Testing with JUnit
Testing Tutorial 7.
Introduction to JUnit CS 4501 / 6501 Software Testing
Testing and Debugging.
slides created by Ethan Apter
Credit to Eclipse Documentation
Introduction to JUnit CS 4501 / 6501 Software Testing
slides created by Ethan Apter
CSE 403 Lecture 13 Black/White-Box Testing Reading:
Introduction to JUnit IT323 – Software Engineering II
Section 3 Graphs & Testing
CSE 143 Lecture 4 More ArrayIntList:
CS 240 – Advanced Programming Concepts
Section 4: Graphs and Testing
Go to pollev.com/cse143.
Testing and debugging A short interlude 17-Apr-19.
CSE 143 Lecture 5 More ArrayIntList:
JUnit Reading: various web pages
You’ll get better code in less time (If you do it for a while)
CSE 143 Lecture 6 interfaces; eclipse; testing
slides created by Ethan Apter and Marty Stepp
slides created by Ethan Apter
Presentation transcript:

1 CSE 331 Unit Testing with JUnit slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R. Mercer, Wikipedia

2 Bugs and testing software reliability: Probability that a software system will not cause failure under specified conditions.  Measured by uptime, MTTF (mean time till failure), crash data. Bugs are inevitable in any complex software system.  Industry estimates: bugs per 1000 lines of code.  A bug can be visible or can hide in your code until much later. testing: A systematic attempt to reveal errors.  Failed test: an error was demonstrated.  Passed test: no error was found (for this particular situation).

3 Difficulties of testing Perception by some developers and managers:  Testing is seen as a novice's job.  Assigned to the least experienced team members.  Done as an afterthought (if at all). "My code is good; it won't have bugs. I don't need to test it." "I'll just find the bugs by running the client program." Limitations of what testing can show you:  It is impossible to completely test a system.  Testing does not always directly reveal the actual bugs in the code.  Testing does not prove the absence of errors in software.

4 Unit testing unit testing: Looking for errors in a subsystem in isolation.  Generally a "subsystem" means a particular class or object.  The Java library JUnit helps us to easily perform unit testing. The basic idea:  For a given class Foo, create another class FooTest to test it, containing various "test case" methods to run.  Each method looks for particular results and passes / fails. JUnit provides "assert" commands to help us write tests.  The idea: Put assertion calls in your test methods to check things you expect to be true. If they aren't, the test will fail.

5 JUnit and Eclipse To add JUnit to an Eclipse project, click:  Project  Properties  Build Path  Libraries  Add Library...  JUnit  JUnit 4  Finish To create a test case:  right-click a file and choose New  Test Case  or click File  New  JUnit Test Case  Eclipse can create stubs of method tests for you.

6 A JUnit test class import org.junit.*; import static org.junit.Assert.*; public class name public void name () { // a test case method... }  A method is flagged as a JUnit test case. methods run when JUnit runs your test class.

7 JUnit assertion methods Each method can also be passed a string to display if it fails:  e.g. assertEquals(" message ", expected, actual )  Why is there no pass method? assertTrue( test ) fails if the boolean test is false assertFalse( test ) fails if the boolean test is true assertEquals( expected, actual ) fails if the values are not equal assertSame( expected, actual ) fails if the values are not the same (by == ) assertNotSame( expected, actual ) fails if the values are the same (by == ) assertNull( value ) fails if the given value is not null assertNotNull( value ) fails if the given value is null fail() causes current test to immediately fail

8 ArrayIntList JUnit test import org.junit.*; import static org.junit.Assert.*; public class TestArrayIntList public void testAddGet1() { ArrayIntList list = new ArrayIntList(); list.add(42); list.add(-3); list.add(15); assertEquals(42, list.get(0)); assertEquals(-3, list.get(1)); assertEquals(15, list.get(2)); public void testIsEmpty() { ArrayIntList list = new ArrayIntList(); assertTrue(list.isEmpty()); list.add(123); assertFalse(list.isEmpty()); list.remove(0); assertTrue(list.isEmpty()); }...

9 Running a test Right click it in the Eclipse Package Explorer at left; choose: Run As  JUnit Test The JUnit bar will show green if all tests pass, red if any fail. The Failure Trace shows which tests failed, if any, and why.

10 JUnit exercise Given a Date class with the following methods:  public Date(int year, int month, int day)  public Date() // today  public int getDay(), getMonth(), getYear()  public void addDays(int days) // advances by days  public int daysInMonth()  public String dayOfWeek() // e.g. "Sunday"  public boolean equals(Object o)  public boolean isLeapYear()  public void nextDay() // advances by 1 day  public String toString() Come up with unit tests to check the following:  That no Date object can ever get into an invalid state.  That the addDays method works properly. It should be efficient enough to add 1,000,000 days in a call.

11 What's wrong with this? public class DateTest public void test1() { Date d = new Date(2050, 2, 15); d.addDays(4); assertEquals(d.getYear(), 2050); assertEquals(d.getMonth(), 2); assertEquals(d.getDay(), 19); public void test2() { Date d = new Date(2050, 2, 15); d.addDays(14); assertEquals(d.getYear(), 2050); assertEquals(d.getMonth(), 3); assertEquals(d.getDay(), 1); }

12 Well-structured assertions public class DateTest public void test1() { Date d = new Date(2050, 2, 15); d.addDays(4); assertEquals(2050, d.getYear()); // expected assertEquals(2, d.getMonth()); // value should assertEquals(19, d.getDay()); // be at LEFT public void test2() { Date d = new Date(2050, 2, 15); d.addDays(14); assertEquals("year after +14 days", 2050, d.getYear()); assertEquals("month after +14 days", 3, d.getMonth()); assertEquals("day after +14 days", 1, d.getDay()); } // test cases should usually have messages explaining } // what is being checked, for better failure output

13 Expected answer objects public class DateTest public void test1() { Date d = new Date(2050, 2, 15); d.addDays(4); Date expected = new Date(2050, 2, 19); assertEquals(expected, d); // use an expected answer } // object to minimize tests // (Date must have // and equals methods) public void test2() { Date d = new Date(2050, 2, 15); d.addDays(14); Date expected = new Date(2050, 3, 1); assertEquals("date after +14 days", expected, d); }

14 Naming test cases public class DateTest public void test_addDays_withinSameMonth_1() { Date actual = new Date(2050, 2, 15); actual.addDays(4); Date expected = new Date(2050, 2, 19); assertEquals("date after +4 days", expected, actual); } // give test case methods really long descriptive public void test_addDays_wrapToNextMonth_2() { Date actual = new Date(2050, 2, 15); actual.addDays(14); Date expected = new Date(2050, 3, 1); assertEquals("date after +14 days", expected, actual); } // give descriptive names to expected/actual values }

15 What's wrong with this? public class DateTest public void test_addDays_addJustOneDay_1() { Date actual = new Date(2050, 2, 15); actual.addDays(1); Date expected = new Date(2050, 2, 16); assertEquals( "should have gotten " + expected + "\n" + " but instead got " + actual\n", expected, actual); }... }

16 Good assertion messages public class DateTest public void test_addDays_addJustOneDay_1() { Date actual = new Date(2050, 2, 15); actual.addDays(1); Date expected = new Date(2050, 2, 16); assertEquals("adding one day to 2050/2/15", expected, actual); }... } // JUnit will already show // the expected and actual // values in its output; // // don't need to repeat them // in the assertion message

17 Tests with a = 5000) public void name () {... }  The above method will be considered a failure if it doesn't finish running within 5000 ms private static final int TIMEOUT = = TIMEOUT) public void name () {... }  Times out / fails after 2000 ms

18 Pervasive timeouts public class DateTest = DEFAULT_TIMEOUT) public void test_addDays_withinSameMonth_1() { Date d = new Date(2050, 2, 15); d.addDays(4); Date expected = new Date(2050, 2, 19); assertEquals("date after +4 days", expected, d); = DEFAULT_TIMEOUT) public void test_addDays_wrapToNextMonth_2() { Date d = new Date(2050, 2, 15); d.addDays(14); Date expected = new Date(2050, 3, 1); assertEquals("date after +14 days", expected, d); } // almost every test should have a timeout so it can't // lead to an infinite loop; good to set a default, too private static final int DEFAULT_TIMEOUT = 2000; }

19 Testing for = ExceptionType.class) public void name () {... }  Will pass if it does throw the given exception. If the exception is not thrown, the test fails. Use this to test for expected = ArrayIndexOutOfBoundsException.class ) public void testBadIndex() { ArrayIntList list = new ArrayIntList(); list.get(4); // should fail }

20 Setup and public void name () {... public void name () {... }  methods to run before/after each test case method is public static void name () {... public static void name () {... }  methods to run once before/after the entire test class runs

21 Tips for testing You cannot test every possible input, parameter value, etc.  So you must think of a limited set of tests likely to expose bugs. Think about boundary cases  positive; zero; negative numbers  right at the edge of an array or collection's size Think about empty cases and error cases  0, -1, null; an empty list or array test behavior in combination  maybe add usually works, but fails after you call remove  make multiple calls; maybe size fails the second time only

22 What's wrong with this? public class DateTest { // test every day of the = 10000) public void tortureTest() { Date date = new Date(2050, 1, 1); int month = 1; int day = 1; for (int i = 1; i < 365; i++) { date.addDays(1); if (day < DAYS_PER_MONTH[month]) {day++;} else {month++; day=1;} assertEquals(new Date(2050, month, day), date); } private static final int[] DAYS_PER_MONTH = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec }

23 Trustworthy tests Test one thing at a time per test method.  10 small tests are much better than 1 test 10x as large. Each test method should have few (likely 1) assert statements.  If you assert many things, the first that fails stops the test.  You won't know whether a later assertion would have failed. Tests should avoid logic.  minimize if/else, loops, switch, etc.  avoid try/catch If it's supposed to throw, use expected=... if not, let JUnit catch it. Torture tests are okay, but only in addition to simple tests.

24 JUnit exercise Given our Date class seen previously:  public Date(int year, int month, int day)  public Date() // today  public int getDay(), getMonth(), getYear()  public void addDays(int days) // advances by days  public int daysInMonth()  public String dayOfWeek() // e.g. "Sunday"  public boolean equals(Object o)  public boolean isLeapYear()  public void nextDay() // advances by 1 day  public String toString() Come up with unit tests to check the following:  That no Date object can ever get into an invalid state.  That the addDays method works properly. It should be efficient enough to add 1,000,000 days in a call.

25 Squashing redundancy public class DateTest = DEFAULT_TIMEOUT) public void addDays_withinSameMonth_1() { addHelper(2050, 2, 15, +4, 2050, 2, 19); = DEFAULT_TIMEOUT) public void addDays_wrapToNextMonth_2() { addHelper(2050, 2, 15, +14, 2050, 3, 1); } // use lots of helpers to make actual tests extremely short private void addHelper(int y1, int m1, int d1, int add, int y2, int m2, int d2) { Date act = new Date(y, m, d); actual.addDays(add); Date exp = new Date(y2, m2, d2); assertEquals("after +" + add + " days", exp, act); } // can also use "parameterized tests" in some frameworks...

26 Flexible helpers public class DateTest = DEFAULT_TIMEOUT) public void addDays_multipleCalls_wrapToNextMonth2x() { Date d = addHelper(2050, 2, 15, +14, 2050, 3, 1); addhelper(d, +32, 2050, 4, 2); addhelper(d, +98, 2050, 7, 9); } // Helpers can box you in; hard to test many calls/combine. // Create variations that allow better flexibility private Date addHelper(int y1, int m1, int d1, int add, int y2, int m2, int d2) { Date date = new Date(y, m, d); addHelper(date, add, y2, m2, d2); return d; } private void addHelper(Date date, int add, int y2, int m2, int d2) { date.addDays(add); Date expect = new Date(y2, m2, d2); assertEquals("date after +" + add + " days", expect, d); }...

27 Regression testing regression: When a feature that used to work, no longer works.  Likely to happen when code changes and grows over time.  A new feature/fix can cause a new bug or reintroduce an old bug. regression testing: Re-executing prior unit tests after a change.  Often done by scripts during automated testing.  Used to ensure that old fixed bugs are still fixed.  Gives your app a minimum level of working functionality. Many products have a set of mandatory check-in tests that must pass before code can be added to a source code repository.

28 Test-driven development Unit tests can be written after, during, or even before coding.  test-driven development: Write tests, then write code to pass them. Imagine that we'd like to add a method subtractWeeks to our Date class, that shifts this Date backward in time by the given number of weeks. Write code to test this method before it has been written.  Then once we do implement the method, we'll know if it works.

29 Tests and data structures Need to pass lots of arrays? Use array literals public void exampleMethod(int[] values) {... }... exampleMethod(new int[] {1, 2, 3, 4}); exampleMethod(new int[] {5, 6, 7}); Need a quick ArrayList ? Try Arrays.asList List list = Arrays.asList(7, 4, -2, 3, 9, 18); Need a quick set, queue, etc.? Many collections can take a list Set list = new HashSet ( Arrays.asList(7, 4, -2, 9));

30 What's wrong with this? public class DateTest { // shared Date object to test with (saves memory!!1) private static Date = DEFAULT_TIMEOUT) public void addDays_sameMonth() { DATE = new Date(2050, 2, 15); // first test; addhelper(DATE, +4, 2050, 2, 19); // DATE = 2/15 here = DEFAULT_TIMEOUT) public void addDays_nextMonthWrap() { // second test; addhelper(DATE, +10, 2050, 3, 1); // DATE = 2/19 here = DEFAULT_TIMEOUT) public void addDays_multipleCalls() { // third test; addDays_sameMonth(); // go back to 2/19; addhelper(DATE, +1, 2050, 2, 20); // test two calls addhelper(DATE, +1, 2050, 2, 21); }... }

31 Test case "smells" Tests should be self-contained and not care about each other. "Smells" (bad things to avoid) in tests:  Constrained test order: Test A must run before Test B. (usually a misguided attempt to test order/flow)  Tests call each other: Test A calls Test B's method (calling a shared helper is OK, though)  Mutable shared state: Tests A/B both use a shared object. (If A breaks it, what happens to B?)

32 Test suites test suite: One class that runs many JUnit tests.  An easy way to run all of your app's tests at once. import org.junit.runner.*; TestCaseName.class,... TestCaseName.class, }) public class name {}

33 Test suite example import org.junit.runner.*; WeekdayTest.class, TimeTest.class, CourseTest.class, ScheduleTest.class, CourseComparatorsTest.class }) public class HW2Tests {}

34 JUnit summary Tests need failure atomicity (ability to know exactly what failed).  Each test should have a clear, long, descriptive name.  Assertions should always have clear messages to know what failed.  Write many small tests, not one big test. Each test should have roughly just 1 assertion at its end. Always use a timeout parameter to every test. Test for expected errors / exceptions. Choose a descriptive assert method, not always assertTrue. Choose representative test cases from equivalent input classes. Avoid complex logic in test methods if possible. Use to reduce redundancy between tests.