In this chapter, we will discuss the @DataProvider
annotation, and the dataProvider
and dataProviderClass
attributes.
Let’s take a look at the code before discussing the annotation and both attributes.
public class LogIn1
{
public void logIn (String email, String password, boolean success)
{
System.out.println("Log In Credentials: " + "\n" +
" Email = " + email + "\n" +
" Password = " + password + "\n" +
" Successful Log In = " + success + "\n" );
}
public Object [] [] logInData ()
{
Object [][] data = new Object [3][3];
data [0][0] = "TestNG@Framework.com"; data [0][1] = "TestNG1234"; data [0][2] = true;
data [1][0] = "Joe@Doe.com"; data [1][1] = "DoeDoe34"; data [1][2] = false;
data [2][0] = "Test@AutomationU.com"; data [2][1] = "TAU1234"; data [2][2] = true;
return data;
}
}
Let's look at the logIn
method.
public void logIn (String email, String password, boolean success)
This method has 3 parameters: email
, password
, and success
. They will receive their argument values from the logInData
method.
The values are placed in a 2-dimensional array. There are three rows of test data.
The first column of data will pass email values to String email
.
The second column of data will pass password values to String password
.
The third column of data will pass success values to boolean success
.
The statement return data
helps us return values to the logIn
method. After the logIn
method receives the argument values then the parameters use those values. That’s a brief overview of this Java code for parameters, arguments, and the 2-dimensional array.
Now, let’s discuss the @DataProvider
annotation. The @DataProvider
annotation returns Java objects which are values to the test method. We implement this annotation by writing @DataProvider
above the method that has the test data.
In this case, logInData
has the test data. The logInData
method will supply data to the logIn
test method.
The @DataProvider
annotation presents two purposes at the same time. The first purpose is to pass an unlimited number of values to a test method. There is no restriction. The values can be any Java data type. In our example, we use a String and boolean data type.
The second purpose is to allow the test method to be invoked with different data sets. Each set will run and have its own test results. In our example, we have three sets of data.
The dataProvider
attribute connects the @DataProvider
annotation to the test method. This is how both methods converse with each other. Since it’s an attribute of the @Test
annotation, we write dataProvider
with a lowercase d and set it equal to the @DataProvider
's method name surrounded by double quotes.
public class LogIn1
{
@Test (dataProvider = "logInData")
public void logIn (String email, String password, boolean success)
{
System.out.println("Log In Credentials: " + "\n" +
" Email = " + email + "\n" +
" Password = " + password + "\n" +
" Successful Log In = " + success + "\n" );
}
@DataProvider
public Object [] [] logInData ()
{
Object [][] data = new Object [3][3];
data [0][0] = "TestNG@Framework.com"; data [0][1] = "TestNG1234"; data [0][2] = true;
data [1][0] = "Joe@Doe.com"; data [1][1] = "DoeDoe34"; data [1][2] = false;
data [2][0] = "Test@AutomationU.com"; data [2][1] = "TAU1234"; data [2][2] = true;
return data;
}
}
Let’s run.
Console Output
Log In Credentials:
Email = TestNG@Framework.com
Password = TestNG1234
Successful Log In = true
Log In Credentials:
Email = Joe@Doe.com
Password = DoeDoe34
Successful Log In = false
Log In Credentials:
Email = Test@AutomationU.com
Password = TAU1234
Successful Log In = true
The output shows three separate tests, each with a row of the data provider.
We can also give the @DataProvider
annotation a name. In this example, the name is login-provider
. If a data provider has a name, we connect the @DataProvider
annotation and the test method by using the data provider's name and not the method name. But as you can see, the data provider's name is optional as the test was executed successfully the last time without a name. Either way is okay.
The dataProviderClass
attribute allows us to separate the test method and data provider into different classes. Up to this point, our test method and data provider were located in the same class. The dataProviderClass
is an attribute of the @Test
annotation just like the dataProvider
.
Here we have one class which contains the data provider:
import org.testng.annotations.DataProvider;
public class SignInDP
{
@DataProvider (name = "signin-provider")
public static Object [] [] signInData ()
{
Object [] [] data = new Object [4] [3];
data [0] [0] = "Invalid"; data [0] [1] = "Invalid123"; data [0] [2] = false;
data [1] [0] = "Admin"; data [1] [1] = "admin123"; data [1] [2] = true;
data [2] [0] = "admin"; data [2] [1] = "admin123"; data [2] [2] = true;
data [3] [0] = "NotValid"; data [3] [1] = "NotValid34"; data [3] [2] = false;
return data;
}
}
and another class which contains the test method:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.Test;
public class OrangeHRM
{
WebDriver driver;
@Test (dataProviderClass = SignInDP.class, dataProvider = "signin-provider")
public void signIn (String usename, String password, boolean success)
{
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Rex Allen Jones II\\Downloads\\Drivers\\chromedriver.exe");
driver = new ChromeDriver ();
driver.manage().window().maximize();
driver.get("https://opensource-demo.orangehrmlive.com");
driver.findElement(By.id("txtUsername")).sendKeys(usename);
driver.findElement(By.id("txtPassword")).sendKeys(password);
driver.findElement(By.id(btnLogin)).click();
System.out.println("Sign In Credentials: " + "\n" +
" Username = " + usename + "\n" +
" Password = " + password + "\n" +
" Successful Sign In = " + success + "\n" );
String actualResult = driver.findElement(By.id("welcome)).getText();
String expectedResult = "Welcome Admin";
Assert.assertEquals(actualResult, expectedResult, "The Actual & Expected Results Do Not Match");
driver.quit();
}
}