When unit tests do not have parameters, executing them will provide the same result, over and over.
Using unit tests with parameters makes the unit tests dynamic and with better coverage.
How is this done in JUNIT?
Lets start with a simple JUNIT test class that has only one unit test:
public class ScriptsWithParameters { private int variable1 = 1; private int variable2 = 2; @Test public void test() { System.out.println(variable1 + " - " + variable2); } }
The class has 2 members (variable1, variable2) that have default values.
Executing the unit test displays
1 - 2
What we want is to be able to have the unit test executed repeteadly.
Every time it is executed, the variables values should change.
To do this, we need 2 things:
- create the list of values
- a way of passing the values to the class members (variable1, variable2)
Create the list of parameter values
The list of values is added to the test class as follows:
@RunWith(Parameterized.class) public class ScriptsWithParameters { @Parameters public static Collection data() { return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } }); } private int variable1; private int variable2; @Test public void test() { System.out.println(variable1 + " - " + variable2); } }
The list is in reality a list of lists of values.
Each element of the list is a list of values.
Every time a unit test runs, a value from the list is selected.
The @Parameters annotation is required.
Pass the values to the parameter class members
This happens through the test class constructor:
@RunWith(Parameterized.class) public class ScriptsWithParameters { @Parameters public static Collection data() { return Arrays.asList(new Object[][] { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } }); } private int variable1; private int variable2; public ScriptsWithParameters(int p1, int p2) { variable1 = p1; variable2 = p2; } @Test public void test() { System.out.println(variable1 + " - " + variable2); } }
How does it work?
- Before the unit test runs, the test class is loaded.
- When the test class is loaded, a list of values is selected: {0, 0}
- The values are provided as parameters to the constructor of the class.
{
variable1 = p1;
variable2 = p2;
}
- In the constructor, the constructor parameters are assigned to the class members.
Executing the test class will execute the unit test multiple times, once for each set of values:
0 - 0
1 - 1
2 - 1
3 - 2
4 - 3
5 - 5
6 - 8
The JUNIT execution status shows one result line for each list of values:
Can unit tests with parameters be done differently?
Unit tests with parameters can be created without using the test class constructor:
@RunWith(Parameterized.class) public class ScriptsWithParameters3 { @Parameters public static Collection data() { return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } }); } @Parameter public int variable1; @Parameter(value = 1) public int variable2; @Test public void test() { System.out.println(variable1 + " - " + variable2); } }
In this case, the class members are annotated with @Parameter.
Before the unit test runs, the test class is loaded.
When the test class is loaded, a list of values is selected:
{0, 0}
The first value is assigned to variable1.
The second value is assigned to variable2.
How do use unit tests with parameters for test automation?
The test case to be automated is this:
1. open the www.vpl.ca site
2. do a keyword search using java as the keyword
3. validate that the number of results is greater than 0
4. on the results page, change the sort order from the default sort order to Author
5. verify that the new sort order is correct
When creating the test automation script, the keyword and sort order should be parameterized.
The following values can be used for the 2 parameters:
search keyword: java, vancouver, cats, dogs
sort order: Author, Title, Rating, Relevance
The test automation script without parameters is below:
public class tests { public WebDriver driver; //use this class member for the search keyword value private String keywordValue = "java"; //use this class member for the new sort order private String sortOrderValue = "Author"; @Before public void setUp() { System.setProperty("webdriver.chrome.driver", "C:\\Users\\asiminiuc\\AppData\\Local\\Google\\Chrome\\Application\\chromedriver.exe"); driver = new ChromeDriver(); } @After public void tearDown() { driver.quit(); } @Test public void tests1() throws InterruptedException { HomePage homePage = new HomePage(driver); ResultsPage resultsPage = homePage.search(keywordValue); assertTrue(resultsPage.getItemsNumber() > 0); resultsPage = resultsPage.changeSortOrder(sortOrderValue); assertEquals(resultsPage.getSortOrderValue(), sortOrderValue); }
The test script with parameters is very similar
@RunWith(value = Parameterized.class) public class testsPARAMETERS { public WebDriver driver; private String keywordValue, sortOrderValue; public testsPARAMETERS(String keyword, String sortOrder) { keywordValue = keyword; sortOrderValue = sortOrder; } @Parameters public static Collection data() throws IOException { Object[][] data = { {"java,Author"}, {"vancouver,Title"}, {"cats,Rating"}, {"dogs,Relevance"} }; return Arrays.asList(data); } @Before public void setUp() { System.setProperty("webdriver.chrome.driver", "C:\\Users\\asiminiuc\\AppData\\Local\\Google\\Chrome\\Application\\chromedriver.exe"); driver = new ChromeDriver(); } @After public void tearDown() { driver.quit(); } @Test public void tests1() throws InterruptedException { HomePage homePage = new HomePage(driver); ResultsPage resultsPage = homePage.search(keywordValue); assertTrue(resultsPage.getItemsNumber() >= 0); resultsPage = resultsPage.changeSortOrder(sortOrderValue); assertEquals(resultsPage.getSortOrderValue(), sortOrderValue); } }
READ NEXT
1. Why is unit testing essential for test automation?
2. WebDriver test automation is like driving a taxi
3. How to learn test automation from zero
0 Comment to "Make Your Automation Scripts Dynamic With Parameters"
Post a Comment