An introduction to pragmatic unit testing with JUnit

  • Slides: 52
Download presentation
An introduction to pragmatic unit testing with JUnit Presented to Dr. Cunningham’s ENGR 660

An introduction to pragmatic unit testing with JUnit Presented to Dr. Cunningham’s ENGR 660 Class Jian Weng 05 November 2020 jweng@olemiss. edu

Outline • • • Resource references JUnit features & goals for unit testing Overview

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 11/5/2020 ENGR 660/Software Engineering II 2

Resource references • Get JUnit resources and documents from the official home pages: http:

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 My. Eclipse websites: http: //www. eclipse. org http: //www. myeclipseide. com • Write JUnit test in Jython website: http: //www. jython. org/ 11/5/2020 ENGR 660/Software Engineering II 3

Outline • • • Resource references JUnit features & goals for unit testing Overview

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 11/5/2020 ENGR 660/Software Engineering II 4

JUnit features & goals for unit testing Two key conceptions: • • What is

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

JUnit features & goals for unit testing What is unit testing? • • •

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. 11/5/2020 ENGR 660/Software Engineering II 6

JUnit features & goals for unit testing What are the objectives of unit testing?

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 11/5/2020 ENGR 660/Software Engineering II 7

JUnit features & goals for unit testing JUnit features • • An instance of

JUnit features & goals for unit testing JUnit features • • An instance of the x. Unit 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 11/5/2020 ENGR 660/Software Engineering II 8

JUnit features & goals for unit testing JUnit Goals • • • Keep the

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 11/5/2020 ENGR 660/Software Engineering II 9

Outline • • • Resource references JUnit features & goals for unit testing Overview

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 11/5/2020 ENGR 660/Software Engineering II 10

Overview of JUnit framework • Composite structure of JUnit framework A utility to run

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 11/5/2020 ENGR 660/Software Engineering II 11

Overview of JUnit framework • JUnit framework is integrated into popular Java environments (IDE)

Overview of JUnit framework • JUnit framework is integrated into popular Java environments (IDE) as below: - 11/5/2020 JDeveloper Eclipse Forte/Netbeans Intelli. J JBuilder Together. J Visual. Age ENGR 660/Software Engineering II 12

Overview of JUnit framework JUnit support files • junit. jar - Put this file

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

Overview of JUnit framework User interfaces for viewing JUnit test results • Text -

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 Test. Runner class manually in command-line window 11/5/2020 ENGR 660/Software Engineering II 14

Overview of JUnit framework • Code for basic JUnit test case ( Simple. Test.

Overview of JUnit framework • Code for basic JUnit test case ( Simple. Test. java) • package junit. samples; • import junit. framework. *; • • • public class Simple. Test extends Test. Case { protected int f. Value 1; protected int f. Value 2; • • • 11/5/2020 protected void set. Up() { f. Value 1= 2; f. Value 2= 3; } protected void tear. Down() { } ENGR 660/Software Engineering II 15

 • • • • public void test. Add() { double result= f. Value

• • • • public void test. Add() { double result= f. Value 1 + f. Value 2; // forced failure result == 5 assert. True(result == 6); } public void test. Divide. By. Zero() { int zero= 0; int result= 8/zero; } public void test. Equals() { assert. Equals(12, 12); assert. Equals(12 L, 12 L); assert. Equals(new Long(12), new Long(12)); assert. Equals("Size", 12, 13); assert. Equals("Capacity", 12. 0, 11. 99, 0. 0); • • • 11/5/2020 } ENGR 660/Software Engineering II 16

 • • • • 11/5/2020 public static Test suite() { Test. Suite suite=

• • • • 11/5/2020 public static Test suite() { Test. Suite suite= new Test. Suite(); suite. add. Test(new Simple. Test("add") { protected void run. Test() { test. Add(); } }); suite. add. Test(new Simple. Test("test. Divide. By. Zero") { protected void run. Test() { test. Divide. By. Zero(); } }); return suite; } public static void main (String[] args) { junit. textui. Test. Runner. run(suite()); } ENGR 660/Software Engineering II 17

Outline • • • Resource references JUnit features & goals for unit testing Overview

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 11/5/2020 ENGR 660/Software Engineering II 18

Strategies for developing JUnit tests • Eclipse overview 11/5/2020 ENGR 660/Software Engineering II 19

Strategies for developing JUnit tests • Eclipse overview 11/5/2020 ENGR 660/Software Engineering II 19

Strategies for developing JUnit tests Create a new JUnit test case • Import junit.

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

Strategies for developing JUnit tests 11/5/2020 ENGR 660/Software Engineering II 21

Strategies for developing JUnit tests 11/5/2020 ENGR 660/Software Engineering II 21

Strategies for developing JUnit tests 11/5/2020 ENGR 660/Software Engineering II 22

Strategies for developing JUnit tests 11/5/2020 ENGR 660/Software Engineering II 22

Strategies for developing JUnit tests Create a new JUnit test case • • Import

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. Test. Case. Add set. Up(), tear. Down(), main(), or constructor functions into JUnit test framework 11/5/2020 ENGR 660/Software Engineering II 23

Strategies for developing JUnit tests JUnit test cases will extend from the base class

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 11/5/2020 ENGR 660/Software Engineering II 24

Strategies for developing JUnit tests Create a new JUnit test case • • •

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. Test. Case. Add set. Up(), tear. Down(), main(), or constructor functions into JUnit test framework Import methods under test into the JUnit test framework 11/5/2020 ENGR 660/Software Engineering II 25

Strategies for developing JUnit tests Pick up the methods that need to be under

Strategies for developing JUnit tests Pick up the methods that need to be under test 11/5/2020 ENGR 660/Software Engineering II 26

Strategies for developing JUnit tests • Code generated from the wizard • import junit.

Strategies for developing JUnit tests • Code generated from the wizard • import junit. framework. Test. Case; • public class Money. Test extends Test. Case { • • public static void main(String[] args) { } protected void set. Up() throws Exception { super. set. Up(); } protected void tear. Down() throws Exception { super. tear. Down(); } • /* * Test method for 'Money. hash. Code()' */ public void test. Hash. Code() { • } • • • 11/5/2020 ENGR 660/Software Engineering II 27

Strategies for developing JUnit tests • /* * Test method for 'Money. add(IMoney)' */

Strategies for developing JUnit tests • /* * Test method for 'Money. add(IMoney)' */ public void test. Add() { • } • • /* * Test method for 'Money. add. Money(Money)' */ public void test. Add. Money() { • } • • /* * Test method for 'Money. amount()' */ public void test. Amount() { • } • • • 11/5/2020 ENGR 660/Software Engineering II 28

Strategies for developing JUnit tests • /* * Test method for 'Money. currency()' */

Strategies for developing JUnit tests • /* * Test method for 'Money. currency()' */ public void test. Currency() { • } • • /* * Test method for 'Money. equals(Object)' */ public void test. Equals. Object() { • } • • /* * Test method for 'Money. multiply(int)' */ public void test. Multiply() { • } • • } 11/5/2020 ENGR 660/Software Engineering II 29

Strategies for developing JUnit tests Right-BICEP Guidelines • • • Right : Are the

Strategies for developing JUnit tests Right-BICEP Guidelines • • • Right : Are the results right? B : Are all the boundary conditions 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? 11/5/2020 ENGR 660/Software Engineering II 30

Strategies for developing JUnit tests RIGHT • • • Depends on requirements Write the

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. 11/5/2020 ENGR 660/Software Engineering II 31

Strategies for developing JUnit tests Boundary check - CORRECT • • Conformance - Verify

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. 11/5/2020 ENGR 660/Software Engineering II 32

Strategies for developing JUnit tests Inverse Check • • Check a method by applying

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 11/5/2020 ENGR 660/Software Engineering II 33

Strategies for developing JUnit tests Cross-check • • If there are more than one

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 11/5/2020 ENGR 660/Software Engineering II 34

Strategies for developing JUnit tests Force error conditions • Mock objects can be used

Strategies for developing JUnit tests Force error conditions • Mock objects can be used to simulate errors from the realworld such as network lines drop, system load, and disks fill up. 11/5/2020 ENGR 660/Software Engineering II 35

Strategies for developing JUnit tests Performance characteristics • • • Assure the code meets

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 11/5/2020 ENGR 660/Software Engineering II 36

Strategies for developing JUnit tests • package junit. samples. money; • import junit. framework.

Strategies for developing JUnit tests • package junit. samples. money; • import junit. framework. Test. Case; • public class Money. Test extends Test. Case { • • • • • 11/5/2020 protected void set. Up() { f 12 CHF= new Money(12, "CHF"); f 14 CHF= new Money(14, "CHF"); } public void test. Money. Equals() { assert. True(!f 12 CHF. equals(null)); Money equal. Money= new Money(12, "CHF"); assert. Equals(f 12 CHF, f 12 CHF); assert. Equals(f 12 CHF, equal. Money); assert. Equals(f 12 CHF. hash. Code(), equal. Money. hash. Code()); assert. True(!f 12 CHF. equals(f 14 CHF)); } public void test. Hash. Code () { assert. True(!f 12 CHF. equals(null)); Money equal= new Money(12, "CHF"); assert. Equals(f 12 CHF. hash. Code(), equal. hash. Code()); } ENGR 660/Software Engineering II 37

Strategies for developing JUnit tests • • • • • • } 11/5/2020 public

Strategies for developing JUnit tests • • • • • • } 11/5/2020 public void test. Add. Money() { // [12 CHF] + [14 CHF] == [26 CHF] Money expected= new Money(26, "CHF"); assert. Equals(expected, f 12 CHF. add(f 14 CHF)); } public void test. Multiply() { // [14 CHF] *2 == [28 CHF] Money expected= new Money(28, "CHF"); assert. Equals(expected, f 14 CHF. multiply(2)); } public void test. Simple. Negate() { // [14 CHF] negate == [-14 CHF] Money expected= new Money(-14, "CHF"); assert. Equals(expected, f 14 CHF. negate()); } public void test. Simple. Subtract() { // [14 CHF] - [12 CHF] == [2 CHF] Money expected= new Money(2, "CHF"); assert. Equals(expected, f 14 CHF. subtract(f 12 CHF)); } ENGR 660/Software Engineering II 38

Strategies for developing JUnit tests Tricks on writing JUnit tests • • The package

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 Test. Case and each test method must start with “test” Test methods have no arguments Order of test method execution varies Use assert. True() and assert. Equals() to verify code Use set. Up() & tear. Down() to prepare test fixture Create some test methods manually in the test case 11/5/2020 ENGR 660/Software Engineering II 39

Strategies for developing JUnit tests • Debug or run JUnit test cases in Eclipse

Strategies for developing JUnit tests • Debug or run JUnit test cases in Eclipse The run JUnit test name can be changed Test case class name Identify the location of failed test step 11/5/2020 ENGR 660/Software Engineering II 40

Strategies for developing JUnit tests • Debug or run tests in command-line window Identify

Strategies for developing JUnit tests • Debug or run tests in command-line window Identify the location of failed test steps 11/5/2020 ENGR 660/Software Engineering II 41

Strategies for developing JUnit tests • • • import junit. framework. *; /** *

Strategies for developing JUnit tests • • • import junit. framework. *; /** * Test. Suite that runs all the sample tests * */ public class Money. Test { • • • } 11/5/2020 public static void main (String[] args) { junit. textui. Test. Runner. run (suite()); } public static Test suite ( ) { Test. Suite suite= new Test. Suite("JUnit Money Test"); suite. add. Test(Simple. Test. suite()); suite. add. Test(new Test. Suite(Money. Test. class)); return suite; } ENGR 660/Software Engineering II 42

Strategies for developing JUnit tests Tricks on running JUnit test cases • • JUnit

Strategies for developing JUnit tests 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 test. Runner to run the cases through text ui, swing ui, or awt ui 11/5/2020 ENGR 660/Software Engineering II 43

Outline • • • Resource references JUnit features & goals for unit testing Overview

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 11/5/2020 ENGR 660/Software Engineering II 44

Conclusions • • • Simple to create the JUnit test framework through integrated Java

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 11/5/2020 ENGR 660/Software Engineering II 45

Outline • • • Resource references JUnit features & goals for unit testing Overview

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 11/5/2020 ENGR 660/Software Engineering II 46

Advanced topics • Improve a class design by defining and verifying the “class invariant”

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 Check. Invariant method to a stack class to check the stack to be empty or overflow, thus to avoid bugs in the code. 11/5/2020 ENGR 660/Software Engineering II 47

Advanced topics • Test-driven development is a valuable technique that is to write tests

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. 11/5/2020 ENGR 660/Software Engineering II 48

Advanced topics • Test invalid parameters - It depends on the software functionality. That

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 11/5/2020 ENGR 660/Software Engineering II 49

Advanced topics • A mock object is simply a debug replacement for a real-world

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 11/5/2020 ENGR 660/Software Engineering II 50

Advanced topics • JUnit tests can be written in Jython(Python for java) - Python

Advanced topics • JUnit tests can be written in Jython(Python for java) - Python is a preferable language for writing tests because it can integrate very well with the platform it runs on - Python is quite straightforward because of dynamic typing - Jython tests and test results can be integrated inside the same view by adding Jython. jar file to the Eclipse project. That is to install Jython plugins. 11/5/2020 ENGR 660/Software Engineering II 51

Thank You! 11/5/2020 ENGR 660/Software Engineering II 52

Thank You! 11/5/2020 ENGR 660/Software Engineering II 52