Junit Materials For Students PDF
Junit Materials For Students PDF
Junit Materials For Students PDF
⚫ JUnit test cases are Java classes that contain one or more unit test methods
⚫ JUnit tests are pass/fail tests explicitly designed to run without human
intervention JUnit can be integrated with several IDEs, including Eclipse
Advantages:
• it's simple to use
• it can test a single class at a time, or a suite of tests can be created for a group of
classes
• it greatly increases your confidence in the correctness of your code
• it often improves the design of the class you are testing - since you spend more
time thinking about how an object is actually used, instead of its implementation,
defects in its interface become more obvious.
Example:
package junit.first;
public class Calculator
{
public int add(int x,int y)
{
return x+y;
}
public int sub(int x,int y)
{
return x-y;
}
}
• set the source folder to "test“ – the test class gets created
• This is because the testAdd and testSub are not implemented correctly
• The test method need not start with the test keyword
Example:
@Test
public void testAdd()
{
Calculator c=new Calculator();
assertEquals("Result",5,c.add(2,3));
}
Now let’s provide implementation to the code and run the test again
package junit.first;
import static org.junit.Assert.*;
import org.junit.Test;
public class CalculatorTest
{
@Test
public void testAdd()
{
Calculator c=new Calculator();
assertEquals(5,c.add(2,3));
}
@Test
public void testSub()
{
Calculator c=new Calculator();
assertEquals(20,c.sub(100,80));
}
}
Unit Test
Unit tests are implemented as classes with test methods. Each test method usually
tests a single method of the target class.
Sometimes, a test method can test more than one method in the target class, and
sometimes, if the method to test is big, you split the test into multiple test methods.
• The unit test class is an ordinary class, with two methods, tesAdd() and testSub.
Notice how this method is annotated with the JUnit annotation @Test. This is done
to signal to the unit test runner, that this is method represents a unit test, that
should be executed. Methods that are not annotated with @Test are not executed by
the test runner.
Inside the testAdd() method an instance of Calculator is created. Then it's add()
method is called with two integer values.
• Finally, the assertEquals() method is called. It is this method that does the actual
testing. In this method we compare the output of the called method (add()) with the
expected output.
• If the two values are equal, nothing happens. The assertEquals() method returns
normally. If the two values are not equal, an exception is thrown, and the test
method stops executing here.
Notice the static import of this class at the top of MyUnitTest. Using the static
import of the method is shorter than writing
Assert.assertEquals().
Example:
assertArrayEquals(expectedArray, resultArray);
assertEquals()
– It compares two objects for their equality.
Example:
assertArrayEquals()
Used to test if two arrays are equal to each other. If the arrays are equal, the
assertArrayEquals() will proceed without errors. If the arrays are not equal, an
exception will be thrown, and the test aborted. Any test code after the
assertArrayEquals() will not be executed.
• assertEquals
The assertEquals() method can compare any two objects to each other. If the two
objects compared are not same, then an AssertionError will be thrown.
The new assertEquals methods use Autoboxing, and hence all the
assertEquals(primitive, primitive) methods will be tested as assertEquals(Object,
Object).
This may lead to some interesting results. For example autoboxing will convert
all numbers to the Integer class, so an Integer(10) may not be equal to Long(10).
Example:
Calc class and it’s corresponding test CalcTest will give you an error.
public class Calc {
public long add(int a, int b) {
return a+b;
}
}
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class CalcTest {
@Test
public void testAdd() {
assertEquals(5, new Calc().add(2, 3));
}
}
You will end up with the following error.
java.lang.AssertionError: expected:<5> but was:<5>
This is due to autoboxing. By default all the integers are cast to Integer, but we were
expecting long here. Hence the error. In order to overcome this problem, it is
better if you type cast the first parameter in the assert
Equals to the appropriate return type for the tested method as follows
assertEquals((long)5, new Calc().add(2, 3));
assertTrue() , assertFalse()
assertTrue (testClass.isSafe());
assertFalse(testClass.isSafe());
• assertNull(),assertNotNull()
assertNotNull(testClass.getObject());
Example:
String s1="Hello";
String s2="Hello";
assertSame(s1,s2); ->true
assertTrue() , assertFalse()
• If the isSafe() method returns true, the assertTrue() method will return normally.
Else an exception will be thrown, and the test will stop there.
• If the isSafe() method returns false, the assertFalse() method will return normally.
Else an exception will be thrown, and the test will stop there.
assertNull(),assertNotNull()
• assertSame(),assertNotSame()
• Used to check if two object references point to the same object or not.
Fixtures
– The set of common resources or data that you need to run one or more tests
• @Before
– It is used to call the annotated function before running each of the tests
• @After
– It is used to call the annotated function after each test method
Example:
OUTPUT:
Before Test
Add function
After Test
Before Test
Sub function
After Test
ANNOTATIONS:
Let's consider the case in which each of the tests that you design needs a common
set of objects. One approach can be to create those objects in each of the methods.
Alternatively, the JUnit framework provides two special methods, setUp()
and tearDown(), to initialize and clean up any common objects.
This avoids duplicating the test code necessary to do the common setup and cleanup
tasks. These are together referred to as fixtures. The framework calls the setup()
before and tearDown() after each test method—thereby ensuring that
there are no side effects from one test run to the next.
In Junit 4.x the @Before annotation does the role of the setUp() method and the
@After annotation performs the role of the tearDown() method of JUnit 3.x
@BeforeClass
– The annotated method will run before executing any of the test method
– The method has to be static
@AfterClass
– The annotated method will run after executing all the test methods
– The method has to be static
Example:
O/P :
Before Test
Add function
Sub function
After Test
@Ignore
– Used for test cases you wanted to ignore
@Test
• @Test
– Used to identify that a method is a test method
Two optional parameters are supported by Test Annotation.
1. ‘expected’ is used to declare that a test method should throw an exception. If it
doesn't throw an exception or if it throws a different exception than the one declared,
the test fails.
Example,
@Test(expected=IndexOutOfBoundsException.class)
new ArrayList<String>().get(1);
2.‘timeout’, causes a test to fail if it takes longer than a specified amount of clock
time (measured in milliseconds). The following test fails:
@Test(timeout=1000)
while(true);
Timeout
– It defines a timeout period in miliseconds with “timeout” parameter
while (true)
Parameterized test
New feature added in JUnit 4
@RunWith(Parameterized.class)
– Because each array element will be passed to the constructor for every run
• A test method
•The constructor is simply expected to store each data set in the class's fields, where
they can be accessed by the test methods. Note that only a single constructor may be
provided. This means that each array provided by the data-generating method must
be the same size, and you might have to pad your data sets with nulls if you don't
always need a particular value.
Example:
package junit.first;
import junit.first.Stringmanip.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@RunWith(Parameterized.class)
public class StringmanipTest2
{
// Fields
private String datum;
private String expected;
/*
Constructor.
*/
public StringmanipTest2(String datum, String expected)
{
this.datum = datum;
this.expected = expected;
}
/*
Test data generator.
This method is called the the JUnit parameterized test runner and returns
a Collection of Arrays. For each Array in the Collection, each
array element corresponds to a parameter in the constructor.
*/
@Parameters
public static Collection<Object[]> generateData()
{
// In this example, the parameter generator returns a List of
// arrays. Each array has two elements: { datum, expected }.
// These data are hard-coded into the class, but they could be
// generated or loaded in any way you like.
Object[][] data = new Object[][]{
{ “Smita", “SMITA" },
{ “smita", “SMITA" },
{ “SMITA", “SMITA" }
};
return Arrays.asList(data);
}
/*
This test method is run once for each element in the Collection returned by the
test data generator -- that is, every time this class is instantiated. Each time this
class is instantiated, it will have a different data set, which is available to the
test method through the
instance's fields.
*/
@Test
public void testUpperCase()
{
Stringmanip s = new Stringmanip(this.datum);
String actualResult = s.upperCase();
assertEquals(actualResult, this.expected);
}
}
Test Suite
Test Suite is a Convenient way to group together tests that are related
• Used to bundle a few unit test cases and run it together
• Annotations used for this
– @RunWith
• Used to invoke the class which is annotated to run the tests in that class
– @Suite
• Allows you to manually build a suite containing tests from many classes
Example:
package junit.first;
public class Stringmanip {
String datum;
public Stringmanip(String datum) {
this.datum = datum;
}
public String upperCase() {
return datum.toUpperCase();
}
}
package junit.first;
import junit.first.Stringmanip.*;
import java.util.*;
import org.junit.Test;
import org.junit.runners.*;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@RunWith(Parameterized.class)
public class StringmanipTest2
{
// Fields
private String datum;
private String expected;
public StringmanipTest2(String datum, String expected) {
this.datum = datum;
this.expected = expected;
}
@Parameters
public static Collection<Object[]> generateData()
{ Object[][] data = new Object[][] {
{ “Smita", “SMITA" },
{ “smita", “SMITA" },
{ “SMitA", “SMITA" }
};
return Arrays.asList(data);
}
@Test
public void testUpperCase()
{
Stringmanip s = new Stringmanip(this.datum);
String actualResult = s.upperCase();
assertEquals(actualResult, this.expected);
}
}
package junit.first;
public class Calc {
public int add( int v1, int v2) {
return v1+v2;
}
public int sub( int v1, int v2) {
return v1-v2;
}
// You can add more functions here as needed..
}
package junit.first;
import static org.junit.Assert.*;
import org.junit.Test;
public class CalcTest {
Calc c = new Calc();
@Test
public void testAdd() {
assertEquals(5, c.add(10,-5));
assertEquals(5, c.add(10,-5));
assertEquals(5, c.add(20,-15));
assertEquals(5, c.add(0,5));
}
@Test
public void testSub() {
assertEquals(5, c.sub(10,5));
assertEquals(95, c.sub(100,5));
assertEquals(5, c.sub(20,15));
assertEquals(5, c.sub(10,5));
}
In JUnit, both @RunWith and @Suite annotation are used to run the suite test.
• When a class is annotated with @RunWith,
JUnit will invoke the class it references to run the tests in that class.
• Using Suite as a runner allows you to manually build a suite containing tests f
rom many classes.
@RunWith(Suite.class)
@Suite.SuiteClasses({
CalcTest.class,
StringmanipTest2.class
})
public class AllTests
{
}
When all the test cases are executed successfully, itshows green color signal
When any one test cases fails, it shows brown color signal
Sample programs
Circle.java:
package com.kce.entity;
if (radius >= 0) {
this.radius = radius;
} else {
throw new ArithmeticException();
}
Circletest:
package com.kce.test;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import com.kce.entity.Circle;
@Before
public void beforeEach() {
System.out.println("before each test");
}
@Test
public void testGetArea1() {
Circle c = new Circle();
c.setRadius(1);
assertEquals(0, c.getArea(), 0.001);
}
@Test(expected = ArithmeticException.class)
public void testGetArea2() {
Circle c = new Circle();
c.setRadius(-12);
@After
public void afterEach() {
System.out.println("after each test");
}
@AfterClass
public static void last() {
System.out.println("after");
}
Factorial.java
package com.kce.entity;
Factorialtest:
package com.kce.test;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import com.kce.entity.Factorial;
@RunWith(Parameterized.class)
public class FactorialTest {
@Parameters
public static Collection<Object[]> getData(){
Object[][] data = {
{0,1},
{1,1},
{5,120},
{7,5040},
{6,720}
};
return Arrays.asList(data);
}
@Test
public void testGetFactorial() {
Factorial f = new Factorial();
assertEquals(this.expected, f.getFactorial(this.input));
}
}
================================================================================
Testsuite.class
package com.kce.test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({CircleTest.class,FactorialTest.class})
public class TestSuite {
===========================================================
Testrunner.class
package com.kce.test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;