Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 5: Test-Driven Development Basics

Similar presentations


Presentation on theme: "Lecture 5: Test-Driven Development Basics"— Presentation transcript:

1 Lecture 5: Test-Driven Development Basics
CSE 116/504 – Intro. To Computer Science for Majors II Lecture 5: Test-Driven Development Basics

2 Announcements Normal homework schedule starting with this one
Always due Mondays at 12:45PM (15 min. before class) Use problems to learn concepts before quiz & tests Can always attempt problems before its lecture When the topics seem difficult, do not get too worried Wait for lecture to ask questions, will cover topics then

3 Today’s Goals Continue real-life TDD example: TopHat
Learn test-driven development goals & benefits Think & discuss why do we care about testing? How TDD differs and why it improves code quality Discuss what is an annotation & how used in testing JUnit test case basics & best practices discussed

4 Good Code Key Concept #1

5 Good Code Key Concept #1 Good Code Works

6 Good Code Works

7 Good Code Works

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

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

10 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 Requires tests written BEFORE implementations Write stubs (but no code) for class & methods Knowing correct outputs, write tests to check Implement methods to pass your tests (& check often)

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

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

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

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

15 TDD Objections Feels weird to start with tests when you first try…
.. but objections reflect poor programming habits Know method’s outcomes when starting to write… … but you may not know how it will be done Effects, not process, checked by good test cases It might be that you find faster code for method Other methods not rewritten as result of improvement Important that your tests show changes not needed

16 Check method’s results NOT method’s processes
TDD Key Concept #1 Check method’s results NOT method’s processes

17 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

18 Unit Testing Library Nearly everyone 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

19 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

20 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

21 Writing Test Methods Test methods MUST have @Test annotation
Only non-static void methods can use annotation To be usable, 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 often are included Can instantiate objects and call methods on objects Other methods can use assert___ & be called by tests

22 JUnit Annotations Loop over each test case in the entire class
JUnit executes all methods Optional methods initialize any data before each test Will have exactly 1 method executed Pass if no crashes & no incorrect asserts occur during test Fails & stops running when assert____ does not pass Executes all methods Also optional, cleans mess made

23 JUnit Annotations Loop over each test case in the entire class
JUnit executes all methods Optional methods initialize any data before each test Will have exactly 1 method executed Pass if no crashes & no incorrect asserts occur during test Fails & stops running when assert____ does not pass Executes all methods Also optional, cleans mess made

24 assert____ Statements
Java statements which actually check results: assertTrue(boolean test) assertFalse(boolean test) assertEquals(X expected, X actual) assertNull(Object objTest) assertNotNull(Object objTest) fail()

25 assert____ Statements
Java statements which actually check results: assertTrue(String message, boolean test) assertFalse(String message, boolean test) assertEquals(String message,X expected, X actual) assertNull(String message, Object objTest) assertNotNull(String message, Object objTest) fail(String message) Can add optional message. Use it when you have additional information for failing test.

26 Outline of (Most) Test Methods
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 object arguments are correct

27 JUnit Tests Key Concept #2
method should execute AT LEAST 1 assert_____()

28 JUnit Test Case Ordering
1 Place lines into proper order 1. assertEquals(2,actual); 2. al.add(s); al.add(s); 3. int actual = al.size(); 4. ArrayList<String> al = new ArrayList<String>(); String s = “Testing”;

29 JUnit Test Case Ordering
1 Place lines into proper order 1. assertEquals(2,actual); 2. al.add(s); al.add(s); 3. int actual = al.size(); 4. ArrayList<String> al = new ArrayList<String>(); String s = “Testing”; Convince your neighbor your answer is correct

30 JUnit Test Case Ordering
1 Place lines into proper order 1. assertEquals(2,actual); 2. al.add(s); al.add(s); 3. int actual = al.size(); 4. ArrayList<String> al = new ArrayList<String>(); String s = “Testing”;

31 JUnit Test Case Ordering
1 4. ArrayList<String> al = new ArrayList<String>(); String s = “Testing”; 3. int actual = al.size(); 1. assertEquals(2,actual); 2. al.add(s); al.add(s);

32 JUnit Test Case Ordering
1 4. ArrayList<String> al = new ArrayList<String>(); String s = “Testing”; 3. int actual = al.size(); 1. assertEquals(2,actual); 2. al.add(s); al.add(s);

33 JUnit Test Case Ordering
1 4. ArrayList<String> al = new ArrayList<String>(); String s = “Testing”; 3. int actual = al.size(); 1. assertEquals(2,actual); 2. al.add(s); al.add(s);

34 JUnit Test Case Ordering
1 4. ArrayList<String> al = new ArrayList<String>(); String s = “Testing”; 3. int actual = al.size(); 1. assertEquals(2,actual); 2. al.add(s); al.add(s);

35 JUnit Test Case Ordering
1 4. ArrayList<String> al = new ArrayList<String>(); String s = “Testing”; 3. int actual = al.size(); 1. assertEquals(2,actual); 2. al.add(s); al.add(s);

36 JUnit Test Case Ordering
1 4. ArrayList<String> al = new ArrayList<String>(); String s = “Testing”; 3. int actual = al.size(); 3. int actual = al.size(); 2. al.add(s); al.add(s);

37 Reminder

38 JUnit Test Case Ordering
1 4. ArrayList<String> al = new ArrayList<String>(); String s = “Testing”; 2. al.add(s); al.add(s); 3. int actual = al.size(); 1. assertEquals(2,actual);

39 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; } }

40 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 will be 32 and not 5. Our tests need to find this!

41 Starting to Write Test Cases
Traditionally, test class adds “Test” to class name Each case is method annotation 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()); }

42 Starting to Write Test Cases
Traditionally, test class adds “Test” to class name Each case is method annotation 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()); }

43 Starting to Write Test Cases
Traditionally, test class adds “Test” to class name Each case is method annotation 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()); }

44 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”)); }

45 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”)); }

46 Better Tests to Write Get more detailed results with assertEquals()
@Test public void muchImproved() { Operational xByOne = new Operational(-2, 1); Operational oneByX = new Operational(1, 4); assertEquals(xByOne.multiply(), “Product is 2”); }

47 Better Tests to Write Get more detailed results with assertEquals()
@Test public void muchImproved() { Operational xByOne = new Operational(-2, 1); Operational oneByX = new Operational(1, 4); assertEquals(xByOne.multiply(), “Product is 2”); }

48 JUnit Tests Key Concept #3
Use assertTrue() & assertFalse() only with boolean variables & methods

49 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)); }

50 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)); }

51 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)); }

52 More Test Gotchas Will this pass?
@Test public void passingIsNotFailing() { Operational xByOne = new Operational(-2, 1); xByOne.sum(); }

53 More Test Gotchas Will this pass?
@Test public void passingIsNotFailing() { Operational xByOne = new Operational(-2, 1); xByOne.sum(); }

54 More Test Gotchas Will this pass?
@Test public void passingIsNotFailing() { Operational xByOne = new Operational(-2, 1); xByOne.sum(); }

55 JUnit Tests Key Concept #2
method should call AT LEAST 1 assert_____()

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

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

58 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()); }

59 Select Real JUnit Annotation(s)
@Test @First @Fail @After @TestClass

60 Select Real JUnit Annotation(s)
@Test @First @Fail @After @TestClass Convince your neighbor of the correct answer(s)

61 Select Real JUnit Annotation(s)
@Test @First @Fail @After @TestClass

62 Select Real JUnit Annotation(s)
@Test needed by JUnit to know methods it should run @Test @First @Fail @After @TestClass

63 Select Real JUnit Annotation(s)
JUnit cannot guarantee order methods are run @Test @First @Fail @After @TestClass

64 Select Real JUnit Annotation(s)
fail() is JUnit assertion that method calls to force test to fail @Test @First @Fail @After @TestClass

65 Select Real JUnit Annotation(s)
@After used on method(s) run after each JUnit test method @Test @First @Fail @After @TestClass

66 Select Real JUnit Annotation(s)
I just made this one up @Test @First @Fail @After @TestClass Image from:

67 Select Real JUnit Annotation(s)
@Test @First @Fail @After @TestClass

68 Last Detail Often make assumptions when writing code
True writing code and still true writing test cases Passing != correct; could be no tests were run May not check what you think; care needed writing tests Tests should be written & run before coding Tests better fail, since code has not yet been written! Before wasting time, always check assumptions

69 Last Detail Often make assumptions when writing code
True writing code and still true writing test cases Passing != correct; could be no tests were run May not check what you think; care needed writing tests Tests should be written & run before coding Tests better fail, since code has not yet been written! Before wasting time, always check assumptions

70 Good Code Key Concept #1 Good Code Works

71 Check method’s results NOT method’s processes
TDD Key Concept #1 Check method’s results NOT method’s processes

72 JUnit Tests Key Concept #2
method should execute AT LEAST 1 assert_____()

73 JUnit Tests Key Concept #3
Use assertTrue() & assertFalse() only with boolean variables & methods

74 For Next Lecture Read webpage & section 2.4 – 2.7 for Monday
Going more in depth into writing good JUnit tests How to decide code done when grading no longer occurs Will discuss shortcuts for developing suites of test cases Week #2 homework posted and ready to finish Past add/drop so will always be due on Monday at 12:45


Download ppt "Lecture 5: Test-Driven Development Basics"

Similar presentations


Ads by Google