JUnit
framework provides Unit Testing support in Javapackage main.java;
public class MySimpleMath {
/**
* A simple method that takes and input and returns
* "positive" or "negative" depending on the input number
*/
public String checkSign(int number) {
if(number >= 0 ) {
return "positive";
} else {
return "negative";
}
}
}
public static void main(String args[]) {
MySimpleMath sm = new MySimpleMath();
// Check a positive
System.out.println("Input 10: " + sm.checkSign(10));
// Check a negative
System.out.println("Input -2: " + sm.checkSign(-2));
// Check a positive
System.out.println("Input 0: " + sm.checkSign(0));
}
The output of the execution should be
Input 10: positive
Input -2: negative
Input 0: positive
System.out.println()
) in places of interestDynamic verification that the program has the expected behavior in a suitably selected final set of test cases
Unit testing is a method of testing individual units of source code to determine if they are fit for use
Example:
Test classes should follow the same package structure with the functional classes
package test.main;
import org.junit.*;
import main.java.MySimpleMath;
public class MySimpleMathTest {
@Test
public void testCheckSignShouldReturnPositive() {
MySimpleMath sm = new MySimpleMath();
Assert.assertEquals("positive", sm.checkSign(5));
Assert.assertEquals("positive", sm.checkSign(0));
}
@Test
public void testCheckSignShouldReturnNegative() {
MySimpleMath sm = new MySimpleMath();
Assert.assertEquals("negative", sm.checkSign(-5));
}
}
@Test
method is a test case that tests a very simple functionality of a method. On method can be tested by many test casesnull
, etc)@
@xxx
are used over the methods in order to depict their functionality@Test
- defines a method as a test method@Test(expected=Exception.class)
– Fails if the method does not throw the expected Exception@Test(timeout=xxxx)
– Fails if the test method requires more time than xxxx milliseconds to execute@Before
& @After
– This method is executed before (or after) each test method@BeforeClass
& @AfterClass
– This method is executed once before (or after) the execution of all test methods@Ignore
– Ignores a test method during the execution of the testsAssert
assertTrue(“message”,boolean condition)
assertFalse(…)
assertEquals(“message”, expected, actual, tolerance)
assertNotEquals(unexpected, actual);
assertNull(“message”, object)
assertNotNull(…)
assertSame(“message”, expected, actual)
assertNotSame(…)
assertArrayEquals(…)
assertArrayNotEquals(…)
fail()
double divide(int num, int denom)
in our MySimpleMath classpackage main.java;
public class MySimpleMath {
/**
* A simple method that takes and input and returns
* "positive" or "negative" depending on the input number
*/
public String checkSign(int number) {
if(number >= 0 ) {
return "positive";
} else {
return "negative";
}
}
/**
* Returns the division of numerator by the denominator.
* If the denominator is zero, it throws an Exception
*/
public double divide(int num, int denom) {
if(denom == 0) {
throw new ArithmeticException("Cannot divide by zero");
} else {
return num/(double)denom;
}
}
}
package test.main;
import org.junit.*;
import main.java.MySimpleMath;
public class MySimpleMathTest {
@Test
public void testCheckSignShouldReturnPositive() {
MySimpleMath sm = new MySimpleMath();
Assert.assertEquals("positive", sm.checkSign(5));
Assert.assertEquals("positive", sm.checkSign(0));
}
@Test
public void testCheckSignShouldReturnNegative() {
MySimpleMath sm = new MySimpleMath();
Assert.assertEquals("negative", sm.checkSign(-5));
}
@Test
public void testDivisionShouldReturnPositiveQuotient() {
MySimpleMath sm = new MySimpleMath();
Assert.assertEquals(2.0, sm.divide(10, 5), 0);
Assert.assertEquals(0.0, sm.divide(0, 5), 0);
}
@Test
public void testDivisionShouldReturnNegativeQuotient() {
MySimpleMath sm = new MySimpleMath();
Assert.assertEquals(-2.0, sm.divide(10, -5), 0);
}
@Test (expected = ArithmeticException.class)
public void testDivisionShouldThrowArithmeticException() {
MySimpleMath sm = new MySimpleMath();
sm.divide(10, 0);
}
}
Arrays
findMin(int[] array)
and the multiply(int[] array, int factor)
where the first finds the min in an array, and the second multiplies each element of the array with a factor respectivellypackage main.java;
public class MySimpleArrayOperations {
public int findMin(int[] array) {
if(!(array.length > 0)) {
throw new IllegalArgumentException("Input array is empty");
}
int min = Integer.MAX_VALUE;
for(int i=0; i<array.length; i++) {
if(array[i] <= min)
min = array[i];
}
return min;
}
public void multiply(int[] array, int factor) {
if(!(array.length > 0)) {
throw new IllegalArgumentException("Input array is empty");
}
for( int i=0; i<array.length; i++ ) {
array[i] = array[i] * factor;
}
}
}
assertArrayEquals(...)
method provided by the JUnit librarypackage test.main;
import org.junit.*;
import static org.junit.Assert.*;
import main.java.MySimpleArrayOperations;
public class MySimpleArrayOperationsTest {
@Test
public void testFindMin() {
MySimpleArrayOperations msao = new MySimpleArrayOperations();
int[] array = {10, 2, 3, 10, 1, 0, 2, 3, 16, 0, 2};
assertEquals(0, msao.findMin(array));
assertNotEquals(10, msao.findMin(array));
}
@Test (expected = IllegalArgumentException.class)
public void testFindMinShouldThrowException() {
MySimpleArrayOperations msao = new MySimpleArrayOperations();
msao.findMin(new int[]{});
}
@Test
public void testMultiply() {
MySimpleArrayOperations msao = new MySimpleArrayOperations();
int[] array = {10, 2, 3, 10, 1, 0, 2, 3, 16, 0, 2};
msao.multiply(array, 10);
assertArrayEquals(new int[]{100, 20, 30, 100, 10, 0, 20, 30, 160, 0, 20}, array);
}
@Test (expected = IllegalArgumentException.class)
public void testMultiplyShouldThrowException() {
MySimpleArrayOperations msao = new MySimpleArrayOperations();
msao.multiply(new int[]{}, 0); //method call with dummy arguments
}
}
@Before
method if you want to the perform the same operation (ex. initializing instance variables) before the execution of each test casepackage test.main;
import org.junit.*;
import static org.junit.Assert.*;
import main.java.MySimpleArrayOperations;
public class MySimpleArrayOperationsTest {
private MySimpleArrayOperations msao = new MySimpleArrayOperations();
private int[] array;
@Before
public void initInstanceVariables() {
System.out.println(this.getClass().getName() + " --> initializing fields");
this.msao = new MySimpleArrayOperations();
this.array = new int[] {10, 2, 3, 10, 1, 0, 2, 3, 16, 0, 2};
}
@Test
public void testFindMin() {
assertEquals(0, msao.findMin(array));
assertNotEquals(10, msao.findMin(array));
}
@Test (expected = IllegalArgumentException.class)
public void testFindMinShouldThrowException() {
msao.findMin(new int[]{});
}
@Test
public void testMultiply() {
msao.multiply(array, 10);
assertArrayEquals(new int[]{100, 20, 30, 100, 10, 0, 20, 30, 160, 0, 20}, array);
}
@Test (expected = IllegalArgumentException.class)
public void testMultiplyShouldThrowException() {
msao.multiply(new int[]{}, 0); //method call with dummy arguments
}
}
MySimpleMathTest
and the MySimpleArrayOperationsTest
), is there a way to run both of them in one take?@RunWith
and the @Suite.SuiteClasses
annotationspackage test.java;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({ MyMathTest.class, MyMathSimpleTest.class })
public class MathTestSuite {
/* the class remains empty, used only as a holder for
* the above annotations
*/
}
JUnitCore.runClasses
allows the execution of multiple Test classes and suites.Result
object as defined by the JUnit framework.JUnitCore
in (for example) main
method like the following:package test.java;
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(MathTestSuite.class,
MyArrayOperationsTest.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
Lists
Lists, Vectors, Stacks
are Collections
and collections can be represented as arrays
by calling the method aList.toArray();
List
to an array
and test it as we did in the testing arrays slideLists
(2)import java.util.ArrayList;
import java.util.Arrays;
public class MyIntegerList {
private ArrayList<Integer> list;
public MyIntegerList(Integer[] array) {
this.list = new ArrayList<>(Arrays.asList(array));
}
public Integer[] getListAsAnArray() {
return (Integer[]) this.list.toArray();
}
public void add(int n) {
this.list.add(n);
}
public void remove() {
if(!this.list.isEmpty())
this.list.remove(this.list.size()-1);
}
public int get(int index) {
if(this.list.size() - 1 >= index)
return this.get(index);
else
return (Integer) null;
}
public int size() {
return this.list.size();
}
public void clear() {
this.list.clear();
}
}
package test.main;
import org.junit.*;
import static org.junit.Assert.*;
import main.java.MyIntegerList;
public class MyIntegerListTest {
private MyIntegerList myList;
@Before
public void initInstanceVariables() {
System.out.println(this.getClass().getName() + "--> initializing array");
Integer array[] = {1,2,3,4,5};
this.myList = new MyIntegerList(array);
}
@Test
public void testSize() {
assertEquals(5, this.myList.size());
assertEquals(0, new MyIntegerList(new Integer[]{}).size());
this.myList.add(6);
assertEquals(6, this.myList.size());
}
@Test
public void testAdd() {
this.myList.add(10);
assertArrayEquals(new Integer[]{1,2,3,4,5,10},this.myList.getListAsAnArray());
}
// the other test cases are omitted to simplify the example
}
main.mymath
MyCalculator
that implements a calculator and provides the following functionalities (methods) for any pair of positive integers :test.mymath
in the same projectMyCalculatorTest
in the package and implement test cases to challenge the functionality of all methods in the MyCalculator
classMyAdvancedMath
and implement the following methodsint factorial(int n)
: Calculates and returns the factorial of a given non-negative number n
. If n < 0
throw an IllegalArgumentException("n cannot be < 0")
. Also investigate which is the largest factorial that can fit in an integer variable and do not allow the user (throw an IllegalArgumentException
) to give an n
larger than the value that causes an overflow.double power(int b, int n)
: Calculates and returns the power of a number, where b
is the base and n
is the exponent. The exponent (n) can be any integer between [0, 20]. If the input is larger than that, an IllegalArgumentException("n should be 0 <= n <= 20")
should be thrownint[] reverse(int[] array)
which should return an array which is the reversed of the one you gave as an inputJUnitCore.runClasses
, store the results in a Result
object and print the failures (if exist)