程序代写代做代考 junit C html Java Test-Driven Development (TDD) with JUnit

Test-Driven Development (TDD) with JUnit
EECS2030 B: Advanced Object Oriented Programming Fall 2019
CHEN-WEI WANG
Motivating Example: Two Types of Errors (2)
Approach 1 – Specify: Indicate in the method signature that a specific exception might be thrown.
Example 1: Method that throws the exception
Example 2: Method that calls another which throws the exception
3 of 48
class C1 {
void m1(int x) throws ValueTooSmallException {
if(x < 0) { throw new ValueTooSmallException("val " + x); } } } class C2 { C1 c1; void m2(int x) throws ValueTooSmallException { c1.m1(x); } } Motivating Example: Two Types of Errors (1) Consider two kinds of exceptions for a counter: Any thrown object instantiated from these two classes must be handled ): public class ValueTooLargeException extends Exception { ValueTooLargeException(String s) { super(s); } } public class ValueTooSmallException extends Exception { ValueTooSmallException(String s) { super(s); } } ( catch-specify requirement ○ Either throws . . . in the method signature (i.e., propagating it to other caller) specify ○ Or handle it in a try-catch block 2 of 48 Motivating Example: Two Types of Errors (3) Approach 2 – Catch: Handle the thrown exception(s) in a try-catch block. 4 of 48 class C3 { public static void main(String[] args) { Scanner input = new Scanner(System.in); int x = input.nextInt(); C2 c2 = new c2(); try { c2.m2(x); } catch(ValueTooSmallException e) { ... } } } A Simple Counter (1) Consider a class for keeping track of an integer counter value: public class Counter { public final static int MAX_VALUE = 3; public final static int MIN_VALUE = 0; private int value; public Counter() { this.value = Counter.MIN_VALUE; } public int getValue() { return value; } ... /* more later! */ ○ Access private attribute value using public accessor getValue. ○ Two class-wide (i.e., static) constants (i.e., final) for lower and upper bounds of the counter value. ○ Initialize the counter value to its lower bound. ○ Requirement : The counter value must be between its lower and upper bounds. 5 of 48 A Simple Counter (2) /* class Counter */ public void increment() throws ValueTooLargeException { if(value == Counter.MAX_VALUE) { throw new ValueTooLargeException("value is " + value); } else { value ++; } } public void decrement() throws ValueTooSmallException { if(value == Counter.MIN_VALUE) { throw new ValueTooSmallException("value is " + value); } else { value --; } } } ○ Change the counter value via two mutator methods. ○ Changes on the counter value may trigger an exception: ● Attempttoincrementwhencounteralreadyreachesitsmaximum. 7 of 48 ● Attempt to decrement when counter already reaches its minimum. Exceptional Scenarios Consider the two possible exceptional scenarios: ● An attempt to increment above the counter’s upper bound. ● An attempt to decrement below the counter’s lower bound. 6 of 48 Components of a Test ● Manipulate the relevant object(s). e.g., Initialize a counter object c, then call c.increment(). e.g., Initialize a counter object c, then call c.decrement(). ● What do you expect to happen ? e.g., value of counter is such that Counter.MIN VALUE + 1 e.g., ValueTooSmallException is thrown ● What does your program actually produce ? e.g., call c.getValue() to find out. e.g., Use a try-catch block to find out (to discuss!). ● A test: ○ if expected outcome occurs. ○ if expected outcome does not occur. Passes Fails ● So far, you ran tests via a tester class with the main method. 8 of 48 Testing Counter via Console V1 (1.1) 1 2 3 4 5 6 7 8 9 10 11 12 13 9 of 48 public class CounterTester1 { public static void main(String[] args) { Counter c = new Counter(); println("Init val: " + c.getValue()); try { c.decrement(); println("Error: ValueTooSmallException NOT thrown."); } catch (ValueTooSmallException e) { println("Success: ValueTooSmallException thrown."); } } /* end of main method */ } /* end of class CounterTester1 */ ○ L3 sets c.value to 0. ○ At L6, if method decrement was implemented: ● Correctly⇒weexpectaValueTooSmallException. ⇒ Execution jumps to L9, L10 – L12, then the program terminates. ● Incorrectly ⇒ expected ValueTooSmallException wouldn’t occur. ⇒ Execution continues to L7, L8, L12, then the program terminates. See the equivalent, automated JUnit test testDecFromMinValue. Testing Counter via Console V1 (1.3.1) ● The real value of a test is: ○ Not only to confirm when your implementation is correct, ○ But also to reveal errors when your implementation is incorrect. ● Say now method decrement was implemented incorrectly: ● Is the same console tester able to reveal this incorrect implementation? 11 of 48 class Counter { ... public void decrement() throws ValueTooSmallException { if(value < Counter.MIN_VALUE) { throw new ValueTooSmallException("value is " + value); } else { value --; } } } Testing Counter via Console V1 (1.2) 1 2 3 4 5 6 7 8 9 10 11 12 13 ● Say method decrement is implemented correctly. ● Lines 3 – 6, 9 – 11, 12 executed, giving the Console Output: public class CounterTester1 { public static void main(String[] args) { Counter c = new Counter(); println("Init val: " + c.getValue()); try { c.decrement(); println("Error: ValueTooSmallException NOT thrown."); } catch (ValueTooSmallException e) { println("Success: ValueTooSmallException thrown."); } } /* end of main method */ } /* end of class CounterTester1 */ 10 of 48 Init val: 0 Success: ValueTooSmallException thrown. Testing Counter via Console V1 (1.3.2) 1 2 3 4 5 6 7 8 9 10 11 12 13 ● Say method decrement is implemented incorrectly. ● Lines 3 – 6, 7 – 8, 12 executed, giving the Console Output: public class CounterTester1 { public static void main(String[] args) { Counter c = new Counter(); println("Init val: " + c.getValue()); try { c.decrement(); println("Error: ValueTooSmallException NOT thrown."); } catch (ValueTooSmallException e) { println("Success: ValueTooSmallException thrown."); } } /* end of main method */ } /* end of class CounterTester1 */ 12 of 48 Init val: 0 Error: ValueTooSmallException NOT thrown. Testing Counter via Console V1 (2.1) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 13 of 48 See the equivalent, automated JUnit test testIncFromMaxValue. public class CounterTester2 { public static void main(String[] args) { Counter c = new Counter(); println("Current val: " + c.getValue()); try { c.increment(); c.increment(); c.increment(); println("Current val: " + c.getValue()); try { c.increment(); println("Error: ValueTooLargeException NOT thrown."); } /* end of inner try */ catch (ValueTooLargeException e) { println("Success: ValueTooLargeException thrown."); } /* end of inner catch */ } /* end of outer try */ catch (ValueTooLargeException e) { println("Error: ValueTooLargeException thrown unexpectedly."); } /* end of outer catch */ } /* end of main method */ } /* end of CounterTester2 class */ Testing Counter via Console V1 (2.3.1) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 15 of 48 public class CounterTester2 { public static void main(String[] args) { Counter c = new Counter(); println("Current val: " + c.getValue()); try { c.increment(); c.increment(); c.increment(); println("Current val: " + c.getValue()); try { c.increment(); println("Error: ValueTooLargeException NOT thrown."); } /* end of inner try */ catch (ValueTooLargeException e) { println("Success: ValueTooLargeException thrown."); } /* end of inner catch */ } /* end of outer try */ catch (ValueTooLargeException e) { println("Error: ValueTooLargeException thrown unexpectedly."); } /* end of outer catch */ } /* end of main method */ } /* end of CounterTester2 class */ ○ Exercise: Give an incorrect method increment, so that ○ Lines 3 – 6, 16 – 18, 19 executed, with Console Output: Current val: 0 Error: ValueTooLargeException was thrown unexpectedly. Testing Counter via Console V1 (2.2) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class CounterTester2 { public static void main(String[] args) { Counter c = new Counter(); println("Current val: " + c.getValue()); try { c.increment(); c.increment(); c.increment(); println("Current val: " + c.getValue()); try { c.increment(); println("Error: ValueTooLargeException NOT thrown."); } /* end of inner try */ catch (ValueTooLargeException e) { println("Success: ValueTooLargeException thrown."); } /* end of inner catch */ } /* end of outer try */ catch (ValueTooLargeException e) { println("Error: ValueTooLargeException thrown unexpectedly."); } /* end of outer catch */ } /* end of main method */ } /* end of CounterTester2 class */ 14 of 48 ○ Say method increment is implemented correctly. ○ Lines 3 – 9, 12 – 15, 19 executed, with Console Output: Current val: 0 Current val: 3 Success: ValueTooLargeException thrown. Testing Counter via Console V1 (2.3.2) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class CounterTester2 { public static void main(String[] args) { Counter c = new Counter(); println("Current val: " + c.getValue()); try { c.increment(); c.increment(); c.increment(); println("Current val: " + c.getValue()); try { c.increment(); println("Error: ValueTooLargeException NOT thrown."); } /* end of inner try */ catch (ValueTooLargeException e) { println("Success: ValueTooLargeException thrown."); } /* end of inner catch */ } /* end of outer try */ catch (ValueTooLargeException e) { println("Error: ValueTooLargeException thrown unexpectedly."); } /* end of outer catch */ } /* end of main method */ } /* end of CounterTester2 class */ 16 of 48 ○ Exercise: Give an incorrect method increment, so that ○ Lines 3 – 11, 15, 19 executed, with Console Output: Current val: 0 Current val: 3 Error: ValueTooLargeException was NOT thrown. Testing Counter via Console V1 (2.3.3) Question. Can this alternative to ConsoleTester2 work (without nested try-catch)? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class CounterTester2 { public static void main(String[] args) { Counter c = new Counter(); println("Current val: " + c.getValue()); try { c.increment(); c.increment(); c.increment(); println("Current val: " + c.getValue()); } catch (ValueTooLargeException e) { println("Error: ValueTooLargeException thrown unexpectedly."); } try { c.increment(); println("Error: ValueTooLargeException NOT thrown."); } /* end of inner try */ catch (ValueTooLargeException e) { println("Success: ValueTooLargeException thrown."); } /* end of inner catch */ } /* end of main method */ } /* end of CounterTester2 class */ ● Sayoneofthefirst3c.increment()mistakenlythrowsVTLE. ● AfterL10isexecuted,flowofexecutionstillcontinuestoL12. 17of48 ● Thisallowsthe4thc.incrementtobeexecuted! Testing Counter via Console (V2): Test 1 Test Case 1: Decrement when the counter value is too small. 19 of 48 Enter "inc", "dec", or "val": val 0 Enter "inc", "dec", or "val": dec Value too small! Enter "inc", "dec", or "val": exit Bye! Testing Counter via Console (V2) import java.util.Scanner; public class CounterTester3 { public static void main(String[] args) { Scanner input = new Scanner(System.in); String cmd = null; Counter c = new Counter(); boolean userWantsToContinue = true; while(userWantsToContinue) { println("Enter \"inc\", \"dec\", or \"val\":"); cmd = input.nextLine(); try { if(cmd.equals("inc")) { else if(cmd.equals("dec")) { else if(cmd.equals("val")) { println( ; } ; } c.increment() c.decrement() ); } else { userWantsToContinue = false; println("Bye!"); } c.getValue() } /* end of try */ catch(ValueTooLargeException e){ println("Value too big!"); } catch(ValueTooSmallException e){ println("Value too small!"); } } /* end of while */ } /* end of main method */ } /* end of class CounterTester3 */ 18 of 48 Testing Counter via Console (V2): Test 2 Test Case 2: Increment when the counter value is too big. 20 of 48 Enter "inc", "dec", or "val": inc Enter "inc", "dec", or "val": inc Enter "inc", "dec", or "val": inc Enter "inc", "dec", or "val": val 3 Enter "inc", "dec", or "val": inc Value too big! Enter "inc", "dec", or "val": exit Bye! Limitations of Testing from the Console ● Do Test Cases 1 & 2 suffice to test Counter’s correctness? ○ Is it plausible to claim that the implementation of Counter is correct because it passes the two test cases? ● What other test cases can you think of? c.getValue() c.increment() c.decrement() 0 1 ValueTooSmall 120 231 3 ValueTooLarge 2 ● So in total we need 8 test cases. ⇒ 6 more separate ○ CounterTester classes to create (like CounterTester1)! ○ Console interactions with CounterTester3! ● Problems? It is inconvenient to: ○ Run each TC by executing main of a CounterTester and 21 of 48 : Any change introduced to your software must not compromise its established correctness. comparing console outputs with your eyes. ○ manually all TCs whenever Counter is changed. Re-run Regression Testing How to Use JUnit: Packages Step 1: ○ In Eclipse, create a Java project ExampleTestingCounter ○ Separation of concerns : ● Groupclassesforimplementation(i.e.,Counter) into package implementation. 23 of 48 ● Groupclassesclassesfortesting(tobecreated) into package tests. Why JUnit? ● Automate the testing of correctness of your Java classes. ● Once you derive the list of tests, translate it into a JUnit test case, which is just a Java class that you can execute upon. ● JUnit tests are helpful callers/clients of your classes, where each test may: ○ Either attempt to use a method in a legal way (i.e., satisfying its precondition), and report: ● Successiftheresultisasexpected ● Failureiftheresultisnotasexpected ○ Or attempt to use a method in an illegal way (i.e., not satisfying its precondition), and report: ● Successiftheexpectedexception (e.g., ValueTooSmallException) occurs. 22of48 ● Failureiftheexpectedexceptiondoesnotoccur. How to Use JUnit: New JUnit Test Case (1) Step 2: Create a new JUnit Test Case in tests package. Create one JUnit Test Case to test one Java class only. ⇒ If you have n Java classes to test, create n JUnit test cases. 24 of 48 How to Use JUnit: New JUnit Test Case (2) Step 3: Select the version of JUnit (JUnit 4); Enter the name of test case (TestCounter); Finish creating the new test case. 25 of 48 How to Use JUnit: Generated Test Case 27 of 48 “Not yet implemented”. ○ Lines 6 – 8: test is just an ordinary mutator method that has a one-line implementation body. ○ Line 5 is critical: Prepend the tag @Test verbatim, requiring that the method is to be treated as a JUnit test. ⇒ When TestCounter is run as a JUnit Test Case, only those methods prepended by the @Test tags will be run and reported. ○ Line 7: By default, we deliberately fail the test with a message How to Use JUnit: Adding JUnit Library Upon creating the very first test case, you will be prompted to add the JUnit library to your project’s build path. 26 of 48 How to Use JUnit: Running Test Case Step 4: Run the TestCounter class as a JUnit Test. 28 of 48 ○ How to Use JUnit: Generating Test Report A report is generated after running all tests (i.e., methods prepended with @Test) in TestCounter. 29 of 48 How to Use JUnit: Revising Test Case Now, the body of test simply does nothing. ⇒ Neither assertion failures nor exceptions will occur. ⇒ The execution of test will be considered as a success. ∵ There is currently only one test in TestCounter. ∴ We will receive a green bar! Caution: test which passes at the moment is not useful at all! 31 of 48 ○ How to Use JUnit: Interpreting Test Report ● A test is a method prepended with the @Test tag. ● The result of running a test is considered: ○ Failure if either ● anassertionfailure(e.g.,causedbyfail,assertTrue, assertEquals) occurs; or ● anunexpectedexception(e.g.,NullPointerException, ArrayIndexOutOfBoundException) is thrown. ○ Success if neither assertion failures nor unexpected exceptions occur. ● After running all tests: ○ A green bar means that all tests succeed. ⇒ Keep challenging yourself if more tests may be added. ○ A red bar means that at least one test fails. ⇒ Keep fixing the class under test and re-runing all tests, until you receive a green bar. ● Question: What is the easiest way to making test a success? Answer: Delete the call fail("Not yet implemented"). 30 of 48 How to Use JUnit: Re-Running Test Case A new report is generated after re-running all tests (i.e., methods prepended with @Test) in TestCounter. 32 of 48 ○ How to Use JUnit: Adding More Tests (1) ● Recall the complete list of cases for testing Counter: c.getValue() c.increment() c.decrement() 0 10 21 32 1 ValueTooSmall ● Let’s turn the two cases in the 1st row into two JUnit tests: ○ Test for the green cell succeeds if: ● Nofailuresandexceptionsoccur;and ● Thenewcountervalueis1. ○ Tests for red cells succeed if the expected exceptions occur 2 3 ValueTooLarge 33 of 48 ● void assertNull(Object o) ● void assertEquals(int expected, int actual) ● void assertEquals(double exp, double act, double epsilon) ● void assertArrayEquals(expected, actuals) ● void assertTrue(boolean condition) ● void fail(String message) (ValueTooSmallException & ValueTooLargeException). ○ Common JUnit assertion methods: JUnit Assertions: Examples (2) ● Consider the following class: ● How do we test c.getArea()? ○ Mathematically:3.4×3.4×3.14=36.2984 ○ However, base-10 numbers cannot be represented perfectly in the binary format. ○ When comparing fractional numbers, allow some tolerance : 36.2984 − 0.01 ≤ c.getArea() ≤ 36.2984 + 0.01 ● Then consider these assertions. Do they pass or fail? Circle c = new Circle(3.4); assertTrue(36.2984, c.getArea(), 0.01); ✓ 35 of 48 class Circle { double radius; Circle(double radius) { this.radius = radius; } int getArea() { return 3.14 * radius * radius; } } JUnit Assertions: Examples (1) Consider the following class: Then consider these assertions. Do they pass or fail? class Point { int x; int y; Point(int x, int y) { this.x = x; this.y = y; } int getX() { return this.x; } int getY() { return this.y; } } Point p; assertNull(p); ✓ assertTrue(p == null); ✓ assertFalse(p != null); ✓ assertEquals(3, p.getX()); × /* NullPointerException */ p = new Point(3, 4); assertNull(p); × assertTrue(p == null); × assertFalse(p != null); × assertEquals(3, p.getX()); ✓ assertTrue(p.getX() == 3 && p.getY() == 4); ✓ 34 of 48 How to Use JUnit: Assertion Methods 36 of 48 How to Use JUnit: Adding More Tests (2.1) 1 2 3 4 5 6 7 8 9 10 11 12 13 @Test public void testIncAfterCreation() { Counter c = new Counter(); assertEquals(Counter.MIN_VALUE, c.getValue()); try { c.increment(); assertEquals(1, c.getValue()); } catch(ValueTooBigException e) { /* Exception is not expected to be thrown. */ fail ("ValueTooBigException is not expected."); } } ○ Line 6 requires a try-catch block ∵ potential ValueTooBigException ○ Lines 4, 7 11 are all assertions: ● Lines4&7assertthatc.getValue()returnstheexpectedvalues. ● Line11:anassertionfailure∵unexpectedValueTooBigException ○ Line 7 can be rewritten as assertTrue(1 == c.getValue()). 37 of 48 How to Use JUnit: Adding More Tests (3.1) 1 2 3 4 5 6 7 8 9 10 11 12 39 of 48 @Test public void testDecFromMinValue() { Counter c = new Counter(); assertEquals(Counter.MIN_VALUE, c.getValue()); try { c.decrement(); fail ("ValueTooSmallException is expected."); } catch(ValueTooSmallException e) { /* Exception is expected to be thrown. */ } } ○ Line 6 requires a try-catch block ∵ potential ValueTooBigException ○ Lines 4 & 7 are both assertions: ● Lines4assertsthatc.getValue()returnstheexpectedvalue(i.e., Counter.MIN_VALUE). ● Line7:anassertionfailure∵expectedValueTooSmallExceptionnot thrown See the equivalent, manual ConsoleTester1. How to Use JUnit: Adding More Tests (2.2) ● Don’t lose the big picture! ● JUnit test in previous slide automates this console interaction: Enter "inc", "dec", or "val": val 0 Enter "inc", "dec", or "val": inc Enter "inc", "dec", or "val": val 1 Enter "inc", "dec", or "val": exit Bye! ● Automation is exactly rationale behind using JUnit! 38 of 48 How to Use JUnit: Adding More Tests (3.2) ● Again, don’t lose the big picture! ● JUnit test in previous slide automates CounterTester1 and the following console interaction for CounterTester3: Enter "inc", "dec", or "val": val 0 Enter "inc", "dec", or "val": dec Value too small! Enter "inc", "dec", or "val": exit Bye! ● Again, automation is exactly rationale behind using JUnit! 40 of 48 How to Use JUnit: Adding More Tests (4.1) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 41 of 48 @Test public void testIncFromMaxValue() { Counter c = new Counter(); try { c.increment(); c.increment(); c.increment(); } catch (ValueTooLargeException e) { fail("ValueTooLargeException was thrown unexpectedly."); } assertEquals(Counter.MAX_VALUE, c.getValue()); try { c.increment(); fail("ValueTooLargeException was NOT thrown as expected."); } catch (ValueTooLargeException e) { /* Do nothing: ValueTooLargeException thrown as expected. */ } } ○ L4 – L9: a VTLE is not expected; L11 – 17: a VTLE is expected. See the equivalent, manual ConsoleTester2. How to Use JUnit: Adding More Tests (4.3) Q: Can we rewrite testIncFromMaxValue to: 1 2 3 4 5 6 7 8 9 10 11 12 13 @Test public void testIncFromMaxValue() { Counter c = new Counter(); try { c.increment(); c.increment(); c.increment(); assertEquals(Counter.MAX_VALUE, c.getValue()); c.increment(); fail("ValueTooLargeException was NOT thrown as expected."); } catch (ValueTooLargeException e) { } } No! At Line 12, we would not know which line throws the VTLE: ○ If it was any of the calls in L5 – L7, then it’s not right. ○ If it was L9, then it’s right. 43 of 48 How to Use JUnit: Adding More Tests (4.2) ● JUnit test in previous slide automates CounterTester2 and the following console interaction for CounterTester3: 42 of 48 Enter "inc", "dec", or "val": inc Enter "inc", "dec", or "val": inc Enter "inc", "dec", or "val": inc Enter "inc", "dec", or "val": val 3 Enter "inc", "dec", or "val": inc Value too big! Enter "inc", "dec", or "val": exit Bye! How to Use JUnit: Adding More Tests (5) Loops can make it effective on generating test cases: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Test public void testIncDecFromMiddleValues() { Counter c = new Counter(); try { for(int i = Counter.MIN_VALUE; i < Counter.MAX_VALUE; i ++) { int currentValue = c.getValue(); c.increment(); assertEquals(currentValue + 1, c.getValue()); } for(int i = Counter.MAX_VALUE; i > Counter.MIN_VALUE; i –) {
int currentValue = c.getValue(); c.decrement();
assertEquals(currentValue – 1, c.getValue());
} }
catch(ValueTooLargeException e) { fail(“ValueTooLargeException is thrown unexpectedly”);
}
catch(ValueTooSmallException e) {
fail(“ValueTooSmallException is thrown unexpectedly”); }
}
44 of 48

Exercises
1. Run all 8 tests and make sure you receive a green bar.
2. Now, introduction an error to the implementation: Change the line value ++ in Counter.increment to –.
45 of 48
○ Re-run all 8 tests and you should receive a red bar. [ Why? ] ○ Undo the error injection, and re-run all 8 tests. [ What happens? ]
Resources
● Official Site of JUnit 4: http://junit.org/junit4/ ● API of JUnit assertions:
http://junit.sourceforge.net/javadoc/org/junit/Assert.html
● Another JUnit Tutorial example: https://courses.cs.washington.edu/courses/cse143/11wi/
eclipse- tutorial/junit.shtml
47 of 48
Test-Driven Development (TDD)
Java Classes (e.g., Counter)
derive
JUnit Test Case (e.g., TestCounter)
extend, maintain
(re-)run as junit test case
when all tests pass add more tests
JUnit Framework
fix the Java class under test when some test fails
Maintain a collection of tests which define the correctness of your Java class under development (CUD):
● Derive and run tests as soon as your CUD is testable .
i.e., A Java class is testable when defined with method signatures.
● Redbarreported:Fixtheclassundertest(CUT)untilgreenbar. 46of48 ● Greenbarreported:AddmoretestsandFixCUTwhennecessary.
Index (1)
Motivating Example: Two Types of Errors (1) Motivating Example: Two Types of Errors (2) Motivating Example: Two Types of Errors (3) A Simple Counter (1)
Exceptional Scenarios
A Simple Counter (2)
Components of a Test
Testing Counter via Console V1 (1.1) Testing Counter via Console V1 (1.2) Testing Counter via Console V1 (1.3.1) Testing Counter via Console V1 (1.3.2) Testing Counter via Console V1 (2.1) Testing Counter via Console V1 (2.2)
Testing Counter via Console V1 (2.3.1)
48 of 48

Index (2)
Testing Counter via Console V1 (2.3.2) Testing Counter via Console V1 (2.3.3) Testing Counter via Console (V2) Testing Counter via Console (V2): Test 1 Testing Counter via Console (V2): Test 2
Limitations Why JUnit? How to Use How to Use How to Use How to Use How to Use How to Use
How to Use
49 of 48
of Testing from the Console
JUnit: Packages
JUnit: New JUnit Test Case (1) JUnit: New JUnit Test Case (2) JUnit: Adding JUnit Library JUnit: Generated Test Case JUnit: Running Test Case JUnit: Generating Test Report
Index (4)
How to Use JUnit: Adding More Tests (5)
Exercises
Test-Driven Development (TDD)
Resources
51 of 48
Index (3)
How to Use JUnit: Interpreting Test Report How to Use JUnit: Revising Test Case How to Use JUnit: Re-Running Test Case
How to Use JUnit: Adding More Tests JUnit Assertions: Examples (1)
JUnit Assertions: Examples (2)
How to Use JUnit: Assertion Methods How to Use JUnit: Adding More Tests How to Use JUnit: Adding More Tests How to Use JUnit: Adding More Tests How to Use JUnit: Adding More Tests How to Use JUnit: Adding More Tests How to Use JUnit: Adding More Tests
How to Use JUnit: Adding More Tests
50 of 48
(1)
(2.1) (2.2) (3.1) (3.2) (4.1) (4.2) (4.3)