This post demonstrates how to reuse our unit tests with JUnit
Parameterized
. Let’s say, we have a JUnit
test class that tests for, for example, a single web browser’s "browse-to-URL"
functionality in various scenarios and we want to reuse those tests for other browsers with the least code change.
JUnit
version: 4.12
Unit Tests – Firefox
The following codes uses WebBrowserInterface
and WebBrowserFactory
. WebBrowserInterface
is a common interface that all web browser implements; while WebBrowserFactory
instantiates appropriate WebBrowserInterface
implementation based on the argument passed to the createImpl
method. The argument can be either "firefox"
, "ie"
, or "chrome"
.
[wp_ad_camp_2]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.turreta.junit.parameterized; ... @RunWith(SpringRunner.class) @SpringBootTest public class NonParameterized01Tests { @Test public void testImpl01_usecase01() { Optional<WebBrowserInterface> optional = WebBrowserFactory.createImpl("firefox"); WebBrowserInterface tmp = optional.get(); Assert.assertTrue(tmp.browseTo("data1", "data2", "data3") == 0); } @Test public void testImpl01_usecase02() { Optional<WebBrowserInterface> optional = WebBrowserFactory.createImpl("firefox"); WebBrowserInterface tmp = optional.get(); Assert.assertTrue(tmp.browseTo("data4", "data5", "data6") == 0); } } |
Unit Tests – IE
We could copy-paste the codes above and modify them a bit for another browser, e.g., Internet Explorer
.
[wp_ad_camp_3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.turreta.junit.parameterized; ... @RunWith(SpringRunner.class) @SpringBootTest public class NonParameterized02Tests { @Test public void testImpl01_usecase01() { Optional<WebBrowserInterface> optional = WebBrowserFactory.createImpl("ie"); WebBrowserInterface tmp = optional.get(); Assert.assertTrue(tmp.browseTo("data1", "data2", "data3") == 0); } @Test public void testImpl01_usecase02() { Optional<WebBrowserInterface> optional = WebBrowserFactory.createImpl("ie"); WebBrowserInterface tmp = optional.get(); Assert.assertTrue(tmp.browseTo("data4", "data5", "data6") == 0); } } |
Unit Tests – Chrome
How about the same codes for Chrome? Yes, copy-paste might still work but our unit tests have started exhibit signs to hard-to-maintain codes (at least for unit tests).
[wp_ad_camp_4]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.turreta.junit.parameterized; ... @RunWith(SpringRunner.class) @SpringBootTest public class NonParameterized03Tests { @Test public void testImpl01_usecase01() { Optional<WebBrowserInterface> optional = WebBrowserFactory.createImpl("chrome"); WebBrowserInterface tmp = optional.get(); Assert.assertTrue(tmp.browseTo("data1", "data2", "data3") == 0); } @Test public void testImpl01_usecase02() { Optional<WebBrowserInterface> optional = WebBrowserFactory.createImpl("chrome"); WebBrowserInterface tmp = optional.get(); Assert.assertTrue(tmp.browseTo("data4", "data5", "data6") == 0); } } |
Parameterized Tests
We could reduce our duplicate codes by using JUnit
Parameterized Tests
using
org.junit.runners.Parameterized.
[wp_ad_camp_1]
All the codes above can be ported to the following codes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | package com.turreta.junit.parameterized; ... @RunWith(Parameterized.class) @SpringBootTest public class ParameterizedAllTests { /** * List contains "firefox", "ie", and "chrome". * It has to be public static. */ @Parameterized.Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][] { {"firefox" }, { "ie" }, {"chrome"} }); } private String implN; // Our tests is now a "backhole" blackbox public ParameterizedAllTests(String implN) { this.implN = implN; } @Test public void testImpl01_usecase01() { Optional<WebBrowserInterface> optional = WebBrowserFactory.createImpl(this.implN); WebBrowserInterface tmp = optional.get(); Assert.assertTrue(tmp.browseTo("data1", "data2", "data3") == 0); } @Test public void testImpl01_usecase02() { Optional<WebBrowserInterface> optional = WebBrowserFactory.createImpl(this.implN); WebBrowserInterface tmp = optional.get(); Assert.assertTrue(tmp.browseTo("data4", "data5", "data6") == 0); } } |
Download the Codes
[wp_ad_camp_5]
https://github.com/Turreta/Reuse-Unit-Tests-by-Converting-them-to-Parameterized-Tests