JUnit Parametric Testing Example

0

If your scenario needs to be for different parametric values, instead of creating a new test case for each set of parameters, JUnit allows you to create a generic test case and run the test multiple times, once for every parameter you’ve create. In this article, we see couple of examples of JUnit parametric testing.

Single Parameter Testing

In the below example, we will show how to run some generic tests on collection for each implementation of Collection, like ArrayList, >code>HashSet and LinkedList.
If you notice all the tests are generic in nature and we don’t use any method parameter to pass in the actual implementation.

Each instance of the test class CollectionTestUsingParameters will be constructed with the default constructor. The test depends on collection object, the actual collection instance will be inject to the field annotated by @Parameter. There can be more than one parameter. The test data is either as object array or Iterable of object. If more than one parameter, the data will be a two dimensional Object[][] array or Iterable<Object[]>.

The data feeder method arguments() is a public static method that is annotated with @Parameters annotation.

    @Parameters
    public static Iterable<Collection<Integer>> arguments() {
        return Arrays.<Collection<Integer>> asList(new ArrayList<Integer>(),
                new HashSet<Integer>(), new LinkedList<Integer>());
    }

The data is injected using class member field annotated with <[email protected]
Finally, the test case must be run with the Parameterized class via the @RunWith annotation.

CollectionTestUsingParameters:

package com.javarticles.junit;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class CollectionTestUsingParameters {
    @Parameter
    public Collection<Integer> collection;

    @SuppressWarnings("unchecked")
    @Parameters
    public static Iterable<Collection<Integer>> arguments() {
        return Arrays.<Collection<Integer>> asList(new ArrayList<Integer>(),
                new HashSet<Integer>(), new LinkedList<Integer>());
    }

    @Before
    public void populateCollection() {
        collection.clear();
        collection.add(1);
        collection.add(2);
        collection.add(3);
    }

    @Test
    public void sizeCheck() {
        assertEquals(3, collection.size());
    }

    @Test
    public void getElement() {
        Iterator<Integer> itr = collection.iterator();
        assertEquals(new Integer(1), itr.next());
        assertEquals(new Integer(2), itr.next());
        assertEquals(new Integer(3), itr.next());
    }

    @Test
    public void removeElement() {
        assertTrue(collection.remove(3));
        assertEquals(2, collection.size());
        assertFalse(collection.contains(3));
    }
}

When running a parameterized test class, instances are created for the cross-product of the test methods and the test data elements. We have three tests and three set of data, the test has run nine times.

Output:

junit_parameteric_testing_results

Results – 9 tests ran

Multiple Parameters Testing

In the below example, we show a group of parameters. Main purpose is to evaluate a calculation which can be a sum or multiplication. We have one generic test that evaluates the expression using the inputs x and y, the calculation is represented by the interface ICalculation.
Here is the data feeder method. You can either return as Object[][] or an Iterable of Object[]. The data set includes an instance o fICalculation, x, y values and the result expected.

    @Parameters
    public static Iterable<Object[]> arguments() {
        return Arrays.asList(new Object[][] {{new Sum(), 2, 3, 5},
                                             {new Multiply(), 2, 3, 6}});
    }

We have three parameters, each parameter is injected into a class member defined. Index range must start at 0.

CalculatorUsingParameters:

public class CalculatorUsingParameters {
    @Parameter(0)
    public ICalculator calculator;
    
    @Parameter(1)
    public Integer x;
    
    @Parameter(2)
    public Integer y;
    
    @Parameter(3)
    public Integer result;
...
}

Calculator interface:

ICalculator:

package com.javarticles.junit;

public interface ICalculator {
    Integer evaluate(int x, int y);
}

Concrete classes of calculator to be tested:

Sum:

package com.javarticles.junit;

public class Sum implements ICalculator {
    public Integer evaluate(int x, int y) {
        return x + y;
    } 
}

Multiply:

package com.javarticles.junit;

public class Multiply implements ICalculator {
    public Integer evaluate(int x, int y) {
        return x * y;
    }  
}

CalculatorUsingParameters:

package com.javarticles.junit;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class CalculatorUsingParameters {
    @Parameter(0)
    public ICalculator calculator;
    
    @Parameter(1)
    public Integer x;
    
    @Parameter(2)
    public Integer y;
    
    @Parameter(3)
    public Integer result;

    @Parameters
    public static Iterable<Object[]> arguments() {
        return Arrays.asList(new Object[][] {{new Sum(), 2, 3, 5},
                                             {new Multiply(), 2, 3, 6}});
    }

    @Test
    public void evaluateOperation() {
        assertEquals(result, calculator.evaluate(x, y));
    }
}

Download the source code

This was an example about JUnit parametric testing.

You can download the source code here: junitPrametericTestingExample.zip
Share.

Comments are closed.