1 / 52

An introduction to pragmatic unit testing with JUnit

An introduction to pragmatic unit testing with JUnit. Presented to Dr.Cunningham’s ENGR660 Class Jian Weng January 1, 2020 jweng@olemiss.edu. Outline. Resource references JUnit features & goals for unit testing Overview of JUnit test framework - JUnit framework

carriee
Download Presentation

An introduction to pragmatic unit testing with JUnit

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. An introduction to pragmatic unit testing with JUnit Presented to Dr.Cunningham’s ENGR660 Class Jian Weng January 1, 2020 jweng@olemiss.edu

  2. Outline • Resource references • JUnit features & goals for unit testing • Overview of JUnit test framework - JUnit framework - IDE environment - JUnit support files - User interfaces for viewing test results - Basic Code examples • Strategies for developing JUnit tests - Create new test case - Write JUnit test by Right-BICEP guidelines - Run JUnit tests • Conclusions • Advanced topics ENGR660/Software Engineering II

  3. Resource references • Get JUnit resources and documents from the official home pages: http://www.junit.org/ http://junit.sourceforge.net/ • Pragmatic unit testing, Anderew Hunt and David Thomas • Test-Driven Development, Kent Beck • Eclipse Distilled, David Carlson • Eclipse and MyEclipse websites: http://www.eclipse.org http://www.myeclipseide.com • Write JUnit test in Jython website: http://www.jython.org/ ENGR660/Software Engineering II

  4. Outline • Resource references • JUnit features & goals for unit testing • Overview of JUnit test framework - JUnit framework - IDE environment - JUnit support files - User interfaces for viewing test results - Basic Code examples • Strategies for developing JUnit tests - Create new test case - Write JUnit test by Right-BICEP guidelines - Run JUnit tests • Conclusions • Advanced topics ENGR660/Software Engineering II

  5. JUnit features & goals for unit testing Two key conceptions: • What is unit testing? • What are the objectives of unit testing? ENGR660/Software Engineering II

  6. JUnit features & goals for unit testing What is unit testing? • A unit test is a piece of code that exercises a small, specific area of functionality, e.g., a particular method in a particular context. • A unit test seeks to demonstrate that the code does what the developer expects. • If testing indicates that code works as expected, we proceed to assemble and test the whole system. ENGR660/Software Engineering II

  7. JUnit features & goals for unit testing What are the objectives of unit testing? • Coding with more confidence • Finding bugs as early as possible • Locating bugs as soon as possible • Lessening the time spent on debugging • Checking the consistency among requirements, design patterns and implementation code ENGR660/Software Engineering II

  8. JUnit features & goals for unit testing JUnit features • An instance of the xUnit architecture for unit testing frameworks • A unit testing framework for Java programs • A simple framework to write repeatable tests • The test-first design methodology or test-driven development thought ENGR660/Software Engineering II

  9. JUnit features & goals for unit testing JUnit Goals • Keep the design simple right from the start • Keep the design easy to change • Help developers create automated tests • Create tests that retain their value over time • Simple to achieve regression testing ENGR660/Software Engineering II

  10. Outline • Resource references • JUnit features & goals for unit testing • Overview of JUnit test framework - JUnit framework - IDE environment - JUnit support files - User interfaces for viewing test results - Basic Code examples • Strategies for developing JUnit tests - Create new test case - Write JUnit test by Right-BICEP guidelines - Run JUnit tests • Conclusions • Advanced topics ENGR660/Software Engineering II

  11. Overview of JUnit framework • Composite structure of JUnit framework A utility to run a suite of tests Helper methods assist to determine a method performing correctly or not A collection of tests that are run at the sane time A collection of one or more related test methods ENGR660/Software Engineering II

  12. Overview of JUnit framework • JUnit framework is integrated into popular Java environments (IDE) as below: - JDeveloper - Eclipse - Forte/Netbeans - IntelliJ - JBuilder - TogetherJ - VisualAge ENGR660/Software Engineering II

  13. Overview of JUnit framework JUnit support files • junit.jar - Put this file in CLASSPATH environmental variable • src.jar - JUnit sources for reference ENGR660/Software Engineering II

  14. Overview of JUnit framework User interfaces for viewing JUnit test results • Text - Run the test cases and view the test results in JUnit IDE • GUI - Execute the GUI TestRunner class manually in command-line window ENGR660/Software Engineering II

  15. Overview of JUnit framework • Code for basic JUnit test case ( SimpleTest.java) • package junit.samples; • import junit.framework.*; • public class SimpleTest extends TestCase { • protected int fValue1; • protected int fValue2; • protected void setUp() { • fValue1= 2; • fValue2= 3; • } • protected void tearDown() { • } ENGR660/Software Engineering II

  16. public void testAdd() { • double result= fValue1 + fValue2; • // forced failure result == 5 • assertTrue(result == 6); • } • public void testDivideByZero() { • int zero= 0; • int result= 8/zero; • } • public void testEquals() { • assertEquals(12, 12); • assertEquals(12L, 12L); • assertEquals(new Long(12), new Long(12)); • assertEquals("Size", 12, 13); • assertEquals("Capacity", 12.0, 11.99, 0.0); • } ENGR660/Software Engineering II

  17. public static Test suite() { • TestSuite suite= new TestSuite(); • suite.addTest(new SimpleTest("add") { • protected void runTest() { testAdd(); } • }); • suite.addTest(new SimpleTest("testDivideByZero") { • protected void runTest() { testDivideByZero();} • }); • return suite; • } • public static void main (String[] args) { • junit.textui.TestRunner.run(suite()); • } ENGR660/Software Engineering II

  18. Outline • Resource references • JUnit features & goals for unit testing • Overview of JUnit test framework - JUnit framework - IDE environment - JUnit support files - User interfaces for viewing test results - Basic Code examples • Strategies for developing JUnit tests - Create new test case - Write JUnit test by Right-BICEP guidelines - Run JUnit tests • Conclusions • Advanced topics ENGR660/Software Engineering II

  19. Strategies for developing JUnit tests • Eclipse overview ENGR660/Software Engineering II

  20. Strategies for developing JUnit tests Create a new JUnit test case • Import junit.jar file into the current project ENGR660/Software Engineering II

  21. Strategies for developing JUnit tests ENGR660/Software Engineering II

  22. Strategies for developing JUnit tests ENGR660/Software Engineering II

  23. Strategies for developing JUnit tests Create a new JUnit test case • Import junit.jar file into the current project • Create a new JUnit test case by wizard • Derive the new test case from junit.framework.TestCase. • Add setUp(), tearDown(), main(), or constructor functions into JUnit test framework ENGR660/Software Engineering II

  24. Strategies for developing JUnit tests JUnit test cases will extend from the base class Some methods can be added into the test framework first Import the methods under test to the JUnit test framework ENGR660/Software Engineering II

  25. Strategies for developing JUnit tests Create a new JUnit test case • Import junit.jar file into the current project • Create a new JUnit test case by wizard • Derive the new test case from junit.framework.TestCase. • Add setUp(), tearDown(), main(), or constructor functions into JUnit test framework • Import methods under test into the JUnit test framework ENGR660/Software Engineering II

  26. Strategies for developing JUnit tests Pick up the methods that need to be under test ENGR660/Software Engineering II

  27. Strategies for developing JUnit tests • Code generated from the wizard • import junit.framework.TestCase; • public class MoneyTest extends TestCase { • public static void main(String[] args) { • } • protected void setUp() throws Exception { • super.setUp(); • } • protected void tearDown() throws Exception { • super.tearDown(); • } • /* • * Test method for 'Money.hashCode()' • */ • public void testHashCode() { • } ENGR660/Software Engineering II

  28. Strategies for developing JUnit tests • /* • * Test method for 'Money.add(IMoney)' • */ • public void testAdd() { • } • /* • * Test method for 'Money.addMoney(Money)' • */ • public void testAddMoney() { • } • /* • * Test method for 'Money.amount()' • */ • public void testAmount() { • } ENGR660/Software Engineering II

  29. Strategies for developing JUnit tests • /* • * Test method for 'Money.currency()' • */ • public void testCurrency() { • } • /* • * Test method for 'Money.equals(Object)' • */ • public void testEqualsObject() { • } • /* • * Test method for 'Money.multiply(int)' • */ • public void testMultiply() { • } • } ENGR660/Software Engineering II

  30. Strategies for developing JUnit tests Right-BICEP Guidelines • Right : Are the results right? • B : Are all theboundaryconditions CORRECT? • I : Can you check the inverse relationship? • C : Can you cross-check results using other means? • E : Can you force error conditions to happen? • P : Are performance characteristics within bounds? ENGR660/Software Engineering II

  31. Strategies for developing JUnit tests RIGHT • Depends on requirements • Write the test code first by what the code is expected to do • For instance, to test whether a value returned from largest() function correct or not, we can test large amounts of data read from a file. ENGR660/Software Engineering II

  32. Strategies for developing JUnit tests Boundary check - CORRECT • Conformance - Verify a value conforms to an expected format • Order - Verify the set of values ordered • Range - Verify a value within the reasonable minimum and maximum values • Reference - Verify the code that reference something external that isn’t under direct control of the code itself • Existence - Verify whether a value exists • Cardinality - Verify there’re exactly enough values • Time - Verify everything is happening in order, at the right time, or in time. ENGR660/Software Engineering II

  33. Strategies for developing JUnit tests Inverse Check • Check a method by applying its logical inverse • For instance, check a method that calculates a square root by squaring the result and test that it is tolerably close to the original number ENGR660/Software Engineering II

  34. Strategies for developing JUnit tests Cross-check • If there are more than one way to calculate the quantity, the result can be cross-checked by a different method • This technique is applicable to the testing system when there is a proven, known way which is too inflexible or too slow ENGR660/Software Engineering II

  35. Strategies for developing JUnit tests Force error conditions • Mock objects can be used to simulate errors from the real-world such as network lines drop, system load, and disks fill up. ENGR660/Software Engineering II

  36. Strategies for developing JUnit tests Performance characteristics • Assure the code meets performance targets • Achieve the quick regression test of performance characteristics • For instance, an URL filter works fine for a small URL list, it is necessary to test if it still works well for a large URL list ENGR660/Software Engineering II

  37. Strategies for developing JUnit tests • package junit.samples.money; • import junit.framework.TestCase; • public class MoneyTest extends TestCase { • protected void setUp() { • f12CHF= new Money(12, "CHF"); • f14CHF= new Money(14, "CHF"); • } • public void testMoneyEquals() { • assertTrue(!f12CHF.equals(null)); • Money equalMoney= new Money(12, "CHF"); • assertEquals(f12CHF, f12CHF); • assertEquals(f12CHF, equalMoney); • assertEquals(f12CHF.hashCode(), equalMoney.hashCode()); • assertTrue(!f12CHF.equals(f14CHF)); • } • public void testHashCode() { • assertTrue(!f12CHF.equals(null)); • Money equal= new Money(12, "CHF"); • assertEquals(f12CHF.hashCode(), equal.hashCode()); • } ENGR660/Software Engineering II

  38. Strategies for developing JUnit tests • public void testAddMoney() { • // [12 CHF] + [14 CHF] == [26 CHF] • Money expected= new Money(26, "CHF"); • assertEquals(expected, f12CHF.add(f14CHF)); • } • public void testMultiply() { • // [14 CHF] *2 == [28 CHF] • Money expected= new Money(28, "CHF"); • assertEquals(expected, f14CHF.multiply(2)); • } • public void testSimpleNegate() { • // [14 CHF] negate == [-14 CHF] • Money expected= new Money(-14, "CHF"); • assertEquals(expected, f14CHF.negate()); • } • public void testSimpleSubtract() { • // [14 CHF] - [12 CHF] == [2 CHF] • Money expected= new Money(2, "CHF"); • assertEquals(expected, f14CHF.subtract(f12CHF)); • } • } ENGR660/Software Engineering II

  39. Strategies for developing JUnit tests Tricks on writing JUnit tests • The package with class under test need to be imported if it is not in the same package as the test case • Test class must extend TestCase and each test method must start with “test” • Test methods have no arguments • Order of test method execution varies • Use assertTrue() and assertEquals() to verify code • Use setUp() & tearDown() to prepare test fixture • Create some test methods manually in the test case ENGR660/Software Engineering II

  40. Debug or run JUnit test cases in Eclipse Strategies for developing JUnit tests The run JUnit test name can be changed Test case class name Identify the location of failed test step ENGR660/Software Engineering II

  41. Debug or run tests in command-line window Strategies for developing JUnit tests Identify the location of failed test steps ENGR660/Software Engineering II

  42. Strategies for developing JUnit tests • import junit.framework.*; • /** • * TestSuite that runs all the sample tests • * • */ • public class MoneyTest { • public static void main (String[] args) { • junit.textui.TestRunner.run (suite()); • } • public static Test suite ( ) { • TestSuite suite= new TestSuite("JUnit Money Test"); • suite.addTest(SimpleTest.suite()); • suite.addTest(new TestSuite(MoneyTest.class)); • return suite; • } • } ENGR660/Software Engineering II

  43. Tricks on running JUnit test cases JUnit runs all test methods in one test case automatically in Eclipse view To run a few methods of a test case, JUnit need to have suite() method with particular test methods added manually. Three ways to run test methods in a test case - add a whole test case - add certain methods of a test case - add the suite method of a test case To run JUnit test case in command-line window, main() function shall be added into the test case, it use testRunner to run the cases through text ui, swing ui, or awt ui Strategies for developing JUnit tests ENGR660/Software Engineering II

  44. Outline • Resource references • JUnit features & goals for unit testing • Overview of JUnit test framework - JUnit framework - IDE environment - JUnit support files - User interfaces for viewing test results - Basic Code examples • Strategies for developing JUnit tests - Create new test case - Write JUnit test by Right-BICEP guidelines - Run JUnit tests • Conclusions • Advanced topics ENGR660/Software Engineering II

  45. Conclusions • Simple to create the JUnit test framework through integrated Java environment, e.g., Eclipse • Support many different unit testing strategies • Run tests flexibly with an entire suite of test methods or any of its parts • Identify points of failure quickly by comparing expected with actual values • View test results through JUnit user interfaces ENGR660/Software Engineering II

  46. Outline • Resource references • JUnit features & goals for unit testing • Overview of JUnit test framework - JUnit framework - IDE environment - JUnit support files - User interfaces for viewing test results - Basic Code examples • Strategies for developing JUnit tests - Create new test case - Write JUnit test by Right-BICEP guidelines - Run JUnit tests • Conclusions • Advanced topics ENGR660/Software Engineering II

  47. Advanced topics • Improve a class design by defining and verifying the “class invariant” - A class invariant is an assertion about objects of a class - For an object to be valid, this assertion must be true - For instance, we can add CheckInvariant method to a stack class to check the stack to be empty or overflow, thus to avoid bugs in the code. ENGR660/Software Engineering II

  48. Advanced topics • Test-driven development is a valuable technique that is to write tests before writing the methods to test. - The point of TDD is to drive out the functionality the software actually needs, rather than what the programmer thinks it probably ought to have. ENGR660/Software Engineering II

  49. Advanced topics • Test invalid parameters - It depends on the software functionality. That is if it’s not the code’s responsibility to check for input data problem, it’s unnecessary to do so; but if it is, then the extra checking for input data is required ENGR660/Software Engineering II

  50. Advanced topics • A mock object is simply a debug replacement for a real-world object, it is kind of a testing pattern and can be implemented in three key steps as: - Use an interface to describe the object - Implement the interface production code - Implement the interface of a mock object for testing ENGR660/Software Engineering II

More Related