What Is Unit Testing?
What Is Unit Testing?
What Is Unit Testing?
Testing is the process of checking the functionality of an application to ensure it runs as per
requirements. Unit testing comes into picture at the developers’ level; it is the testing of single
entity (class or method). Unit testing plays a critical role in helping a software company deliver
quality products to its customers.
Unit testing can be done in two ways: manual testing and automated testing.
This practice helps developers to discover failures in their logic behind their code and improve the
quality of their code. Also, unit testing can be used so as to ensure that the code will work as
expected in case of future changes.
Test coverage
In general, the development community has different opinion regarding the percentage of code
that should be tested (test coverage).Some developers believe that the code should have 100% test
coverage, while others are comprised with a test coverage of 50% or less. In any case, you should
write tests for complex or critical parts of your code.
JUnit introduction
JUnit is an open source testing framework which is used to write and run repeatable automated
tests, so that we can be ensured that our code works as expected. JUnit is widely used in industry
and can be used as stand alone Java program (from the command line) or within an IDE such as
Eclipse.
JUnit provides:
• Assertions for testing expected results.
• Test features for sharing common test data.
• Test suites for easily organizing and running tests.
• Graphical and textual test runners.
CalculateTest.java
import static org.junit.Assert.*;
import org.junit.Test;
public class CalculateTest {
Calculate calculation = new Calculate();
int sum = calculation.sum(2, 5);
int testSum = 7;
@Test
public void testSum() {
System.out.println("@Test sum(): " + sum + " = " + testSum);
assertEquals(sum, testSum);
}
}
Let’s explain the above code. Firstly, we can see that there is a @Test annotation above the testSum() method. This
annotation indicates that the public void method to which it is attached can be run as a test case. Hence, the testSum()
method is the method that will test the sum() public method. We can also observe a method called assertEquals(sum,
testsum). The method assertEquals ([String message], object expected, object actual) takes as inputs two objects and
asserts that the two objects are equal. If we run the test class, by right-clicking in the test class and select Run As!Junit
Test, the program output will look like that:
Adding values: 2 + 5
@Test sum(): 7 = 7
JUnit annotations
The table below presents a summary of those annotations:
Let’s see an example of a test class with some of the annotations mentioned above.
AnnotationsTest.java
package com.javacodegeeks.junit;
import static org.junit.Assert.*;
import java.util.*;
import org.junit.*;
public class AnnotationsTest {
private ArrayList testList;
@BeforeClass
public static void onceExecutedBeforeAll() {
System.out.println("@BeforeClass: onceExecutedBeforeAll");
}
@Before
public void executedBeforeEach() {
testList = new ArrayList();
System.out.println("@Before: executedBeforeEach");
}
@AfterClass
public static void onceExecutedAfterAll() {
System.out.println("@AfterClass: onceExecutedAfterAll");
}
@After
public void executedAfterEach() {
testList.clear();
System.out.println("@After: executedAfterEach");
}
@Test
public void EmptyCollection() {
assertTrue(testList.isEmpty());
System.out.println("@Test: EmptyArrayList");
}
@Test
public void OneItemCollection() {
testList.add("oneItem");
assertEquals(1, testList.size());
System.out.println("@Test: OneItemArrayList");
}
@Ignore
public void executionIgnored() {
System.out.println("@Ignore: This execution is ignored");
}
}
If we run the above test, the console output would be the
following:
@BeforeClass: onceExecutedBeforeAll
@Before: executedBeforeEach
@Test: EmptyArrayList
@After: executedAfterEach
@Before: executedBeforeEach
@Test: OneItemArrayList
@After: executedAfterEach
@AfterClass: onceExecutedAfterAll
JUnit assertions
In this section we will present a number of assertion methods. All those methods are provided by the Assert class
which extends the class java.lang.Object and they are useful for writing tests so as to detect failures. In the table below
there is a more detailed explanation of the most commonly used assertion methods.
The assertArrayEquals() will compare the two arrays and if they are equal, the method will
proceed without errors.Otherwise, a failure will be displayed in the JUnit window and the test will
abort.
Fixtures is a fixed state of a set of objects used as a baseline for running tests. The purpose of a
test fixture is to ensure that there is a well-known and fixed environment in which tests are run so
that results are repeatable. It includes:
import junit.framework.*;
public class JavaTest extends TestCase {
protected int value1, value2;
// assigning the values
protected void setUp(){
value1=3;
value2=3;
}
// test method to add two values
public void testAdd(){
double result= value1 + value2;
assertTrue(result == 6);
}
}
Test Suites
A test suite bundles a few unit test cases and runs them together. In JUnit, both @RunWith and @Suite
annotation are used to run the suite test. Given below is an example that uses TestJunit1 & TestJunit2 test
classes.
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
//JUnit Suite Test
@RunWith(Suite.class)
@Suite.SuiteClasses({
TestJunit1.class ,TestJunit2.class
})
public class JunitTestSuite {
}
import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;
public class TestJunit1 {
String message = "Robert";
MessageUtil messageUtil = new MessageUtil(message);
@Test
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
assertEquals(message, messageUtil.printMessage());
}
}
import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;
public class TestJunit2 {
String message = "Robert";
MessageUtil messageUtil = new MessageUtil(message);
@Test
public void testSalutationMessage() {
System.out.println("Inside testSalutationMessage()");
message = "Hi!" + "Robert";
assertEquals(message,messageUtil.salutationMessage());
}
}
Test Runners
Test runner is used for executing the test cases. Here is an example that assumes the test class TestJunit
already exists.
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
BASIC USAGE
Let us now have a basic example to demonstrate the step-by-step process of using Junit.
1. Create a Class
Create a java class to be tested
public class MessageUtil {
private String message;
//Constructor
//@param message to be printed
public MessageUtil(String message){
this.message = message;
}
// prints the message
public String printMessage(){
System.out.println(message);
return message;
}
}
4. Implement the test condition and check the condition using assertEquals API of
Junit.
Create a java class file name TestJunit.java
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Hello World";
MessageUtil messageUtil = new MessageUtil(message);
@Test
public void testPrintMessage() {
assertEquals(message,messageUtil.printMessage());
}
}
3. Create Test Runner Class
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}