@DataProvider:
//@DataProvider - is annotation in testng
// can be used to
provide data (or) send data to Test Method
// define multiple sets of data
// ex: login functionality with multiple users
// ram mercury
// Sita mercury
// Geetha mercury
// we can perform Data
driven testing
// testing the application functionality with
multiple sets of data - DDT
package TestNGBasics2;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DataProviderBasics1 {
//@DataProvider // provide data to test method
// define
@DataProvider
@DataProvider
// Define
getData()
public Object
[][] getData()
{
//define
data
//
Declare 2 dim object array with 3 rows , 2 columns
Object
oarr [] [] = new Object [3][2];
// // 0-2 // 0 -1
// rows - represent how many times test has to
be executed
// 3 -
means it executes test method 3 times
//
Cols - represent how many parameters we are passing to test
method
//
ex: 2 how many parameters we are
passing to test method
// 2 parameters
//
Object - predefined class in java
// Object var -
store any type of value
// int, float, String,
double.....etc
oarr[0]
[0] = "ram";
oarr[0]
[1] = "mercury";
oarr[1]
[0] = "sita";
oarr[1]
[1] = "mercury";
oarr[2]
[0] = "Geetha";
oarr[2]
[1] = "mercury";
return
oarr;
}
// Define login()
- // get data from datprovider method
i.e getData to test methods
@Test(dataProvider
= "getData")
public void
login(String user, String pwd) //
{
System.out.println("Read
data from getData()="+ user);
System.out.println("Read
data from getData()="+ pwd);
}
}
o/p:
[RemoteTestNG] detected TestNG version 7.0.0
Read data from getData()=ram
Read data from getData()=mercury
Read data from getData()=sita
Read data from getData()=mercury
Read data from getData()=Geetha
Read data from getData()=mercury
PASSED: login("ram", "mercury")
PASSED: login("sita", "mercury")
PASSED: login("Geetha", "mercury")
===============================================
Default test
Tests run: 3, Failures:
0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 3, Passes: 3, Failures: 0, Skips: 0
===============================================
HW : define some @Dataprovider annotation, define data as below
Productname, Qty, Address
-------------------------
Lux, 5, Bangalore
Samsung Mobile, 1, Chennai
........................
........................
....... etc
Define test method- CreateOrder()
and Run Test method -CreateOrder() - 2 times by reading the data ?
-----------------------------------------
ex2:
error
Parameters count in @Test method must be equal with @DataProvider
method with Columns count from Array.
==
ex:
package TestNGBasics2;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DataProviderBasics1 {
//@DataProvider // provide data to test method
// define
@DataProvider
@DataProvider
// Define
getData()
public Object
[][] getData()
{
//define
data
//
Declare 2 dim object array with 3 rows , 2 columns
Object
oarr [] [] = new Object [3][3];
// // 0-2 // 0 -1
// rows - represent how many times test has to
be executed
// 3 -
means it executes test method 3 times
//
Cols - represent how many parameters we are passing to test
method
//
ex: 2 how many parameters we are
passing to test method
// 2 parameters
//
Object - predefined class in java
// Object var -
store any type of value
// int, float, String,
double.....etc
oarr[0]
[0] = "ram";
oarr[0]
[1] = "mercury";
oarr[1]
[0] = "sita";
oarr[1]
[1] = "mercury";
oarr[2]
[0] = "Geetha";
oarr[2]
[1] = "mercury";
return
oarr;
}
// Define login()
- // get data from datprovider method
i.e getData to test methods
@Test(dataProvider
= "getData")
// public void
login(String user, String pwd) //ok// if col= 3 , we must pass 2 paramters
// public void
login(String user) // throws Exception if col=2 but we are not passing 2
parameters
public void
login(String user, String pwd, String browser)// if col= 3 , we must pass 3
paramters
{
System.out.println("Read
data from getData()="+ user);
System.out.println("Read
data from getData()="+ pwd);
}
}
o/p:
[RemoteTestNG] detected
TestNG version 7.0.0
FAILED: login
org.testng.internal.reflect.MethodMatcherException:
[public void
TestNGBasics2.DataProviderBasics1.login(java.lang.String)] has no parameters
defined but was found to be using a data provider (either explicitly specified
or inherited from class level annotation).
Data provider mismatch
Method: login([Parameter{index=0, type=java.lang.String,
declaredAnnotations=[]}])
Arguments: [(java.lang.String) ram,(java.lang.String) mercury]
at
org.testng.internal.reflect.DataProviderMethodMatcher.getConformingArguments(DataProviderMethodMatcher.java:43)
at
org.testng.internal.Parameters.injectParameters(Parameters.java:925)
at
org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:34)
at
org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:804)
at
org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:145)
at
org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at
org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at
java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at
org.testng.TestRunner.privateRun(TestRunner.java:770)
at
org.testng.TestRunner.run(TestRunner.java:591)
at
org.testng.SuiteRunner.runTest(SuiteRunner.java:402)
at
org.testng.SuiteRunner.runSequentially(SuiteRunner.java:396)
at
org.testng.SuiteRunner.privateRun(SuiteRunner.java:355)
at
org.testng.SuiteRunner.run(SuiteRunner.java:304)
at
org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at
org.testng.TestNG.runSuitesSequentially(TestNG.java:1180)
at
org.testng.TestNG.runSuitesLocally(TestNG.java:1102)
at
org.testng.TestNG.runSuites(TestNG.java:1032)
at
org.testng.TestNG.run(TestNG.java:1000)
at
org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
at
org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at
org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
===============================================
Default test
Tests run: 1, Failures:
1, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 1, Passes: 0, Failures: 1, Skips: 0
===============================================
Single Data
Provider for Multiple classes:
package TestNGBasics2;
import java.lang.reflect.Method;
import org.testng.annotations.DataProvider;
public class SingleDataProviderBasics {
@DataProvider
// define
getData() and pass Method m refer var
public Object []
[] getData(Method m)
{
// import java.lang.reflect.Method;
// get Test
methods name in Run time
String
testMethodName = m.getName();
System.out.println("MethodName="+
testMethodName);
// testB
Object
oarr [] [] = new Object [3][2];
// if test method name = testA, define
data
if(testMethodName.equals("testA"))
{
// testA testA
//
testB testA
oarr[0]
[0] = "ram1";
oarr[0]
[1] = "mercury1";
oarr[1]
[0] = "sam1";
oarr[1]
[1] = "mercury1";
oarr[2]
[0] = "Sita1";
oarr[2]
[1] = "mercury1";
}
else
if (testMethodName.equals("testB"))
{
// if test method name = testB, define other data
//
testB testB =-
true
oarr[0]
[0] = "ram2";
oarr[0]
[1] = "mercury2";
oarr[1]
[0] = "sam2";
oarr[1]
[1] = "mercury2";
oarr[2]
[0] = "Sit2";
oarr[2]
[1] = "mercury2";
}
// if we have 100 test methods , we have to define 100 times else if conditions ,
//it
is time consuming
//
maintaining test data is very difficult
// We will
go for excel file -- define
data in excel and Read DATA FROM excel File --> Later
return
oarr;
}
}
Defined 2
classes and get data from data provider:
package TestNGBasics2;
import org.testng.annotations.Test;
public class TestA
{
// define
dataprovider, dataProviderClass =
// define
testA() and pass user,pwd
@Test(dataProvider
= "getData",dataProviderClass = SingleDataProviderBasics.class)
public void
testA(String user,String pwd)
{
System.out.println("user="+
user);
System.out.println("pwd="+
pwd);
}
}
Run class -TestA()
o/p:
[RemoteTestNG] detected TestNG version 7.0.0
MethodName=testA
for TestA(), user =ram1,pwd=mercury1
for TestA(), user =sam1,pwd=mercury1
for TestA(), user =Sita1,pwd=mercury1
PASSED: testA("ram1", "mercury1")
PASSED: testA("sam1", "mercury1")
PASSED: testA("Sita1", "mercury1")
===============================================
Default test
Tests run: 3, Failures:
0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 3, Passes: 3, Failures: 0, Skips: 0
===============================================
Define testB
class and get data from dataprovider :
package TestNGBasics2;
import org.testng.annotations.Test;
public class TestB {
// define
dataprovider, dataProviderClass =
// define
testB() and pass user,pwd
@Test(dataProvider
= "getData",dataProviderClass = SingleDataProviderBasics.class)
public void
testB(String user,String pwd)
{
System.out.println("user="+
user);
System.out.println("pwd="+
pwd);
}
}
o/p:
----
[RemoteTestNG] detected TestNG version 7.0.0
MethodName=testB
for TestB(), user =ram2,pwd=mercury2
for TestB(), user =sam2,pwd=mercury2
for TestB(), user =Sit2,pwd=mercury2
PASSED: testB("ram2", "mercury2")
PASSED: testB("sam2", "mercury2")
PASSED: testB("Sit2", "mercury2")
===============================================
Default test
Tests run: 3, Failures:
0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 3, Passes: 3, Failures: 0, Skips: 0
===============================================
FAQ what is
DataProvider annotation?
@Dataprovider
Object[][]
getData()
{
// define data
Object
oarr [] [ ] = [3] [2];
/// 3 - it
executes test method 3 times
// 2 -
paramters to pass @Test method
}
@Test(dataProvider = "getData")
public void login()
{
}
FAQ WAP to use @DataProvider?
FAQ Dataprovider method return type ?
Objec [][] 2 dim object
array
FAQ Can we use
String array instead of Object array in DataProvider Method ?
"abc134" , "1323"
yes. we can use String array instead of Object array.
package TestNGBasics2;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DataProviderBasics1 {
//@DataProvider // provide data to test method
// define
@DataProvider
@DataProvider
// Define
getData()
// public Object [][]
getData()
public String
[][] getData()
{
//define
data
//
Declare 2 dim object array with 3 rows , 2 columns
// Object
oarr [] [] = new Object [3][2];
String
oarr [] [] = new String [3][2];
// // 0-2 // 0 -1
// rows - represent how many times test has to
be executed
// 3 -
means it executes test method 3 times
//
Cols - represent how many parameters we are passing to test
method
//
ex: 2 how many parameters we are
passing to test method
// 2 parameters
//
Object - predefined class in java
// Object var -
store any type of value
// int, float, String,
double.....etc
oarr[0]
[0] = "ram";
oarr[0]
[1] = "mercury";
oarr[1]
[0] = "sita";
oarr[1]
[1] = "mercury";
oarr[2]
[0] = "Geetha";
oarr[2]
[1] = "mercury";
return
oarr;
}
// Define login()
- // get data from datprovider method
i.e getData to test methods
@Test(dataProvider
= "getData")
public void
login(String user, String pwd) //ok// if col= 3 , we must pass 2 paramters
// public void
login(String user) // throws Exception if col=2 but we are not passing 2
parameters
// public void
login(String user, String pwd, String browser)// if col= 3 , we must pass 3
paramters
{
System.out.println("Read
data from getData()="+ user);
System.out.println("Read
data from getData()="+ pwd);
}
}
run class:
[RemoteTestNG] detected TestNG version 7.0.0
Read data from getData()=ram
Read data from getData()=mercury
Read data from getData()=sita
Read data from getData()=mercury
Read data from getData()=Geetha
Read data from getData()=mercury
PASSED: login("ram", "mercury")
PASSED: login("sita", "mercury")
PASSED: login("Geetha", "mercury")
===============================================
Default test
Tests run: 3, Failures:
0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 3, Passes: 3, Failures: 0, Skips: 0
===============================================
-------------------------------------------
FAQ what is the disadvantage of @DataProviders
annontaion?
We have to define data in Class it self.
For each Test Method, we have to define multiple if conditions.
Maintaining the test data is difficult
(Or)
The @DataProvider annotation in TestNG is a powerful tool for
implementing Data-Driven Testing (DDT) by supplying multiple sets of data to
your test methods. While it offers several advantages, such as code reusability
and scalability, there are a few potential disadvantages to consider:
- Complexity: Using data providers can
introduce additional complexity, especially when managing large datasets
or complex data structures. This complexity can make the test code harder
to understand and maintain.
- Maintenance Overhead: As the number of test
cases and datasets grows, maintaining data providers and ensuring they
provide valid and relevant data can become cumbersome. Changes to the data
format or structure may require updates across multiple test classes.
- Dependency on External Data: Data providers often rely
on external data sources, such as CSV files, databases, or hard-coded
arrays. Managing and synchronizing these external data sources with test
cases may add overhead and increase the risk of test failures due to data
inconsistencies.
- Limited Flexibility in Test
Execution Order:
TestNG executes tests based on the order they are discovered, not
necessarily in the order defined in the code. This behavior can sometimes
lead to unexpected results when combined with data providers, especially
if test methods depend on specific data ordering.
- Debugging Challenges: When tests fail due to
issues with data providers (e.g., data mismatch or format errors),
debugging can be challenging. Identifying which dataset caused the failure
and why it failed may require detailed logging or debugging techniques.
- Performance Considerations: Using data providers with
large datasets or extensive data processing logic can impact test
execution performance. Each iteration of test data may incur additional
overhead, affecting the overall test suite execution time.
To
mitigate these disadvantages, it's essential to carefully design and structure
your data providers, use meaningful data sets, and implement robust error
handling and logging mechanisms. Additionally, leveraging TestNG's reporting
features can help in identifying and diagnosing issues related to data provider
failures during test execution.
No comments:
Post a Comment