method - ¿Es posible pasar parámetros a TestNG DataProvider?
testng docu (5)
Nos gustaría ejecutar algunas de nuestras pruebas cada una contra un conjunto de valores de datos, verificando que las mismas condiciones se cumplen para cada una. Los datos se almacenan actualmente en archivos planos o en simples hojas de cálculo de Excel.
Mi primer pensamiento fue crear un TestNG DataProvider que cargaría los datos del archivo y se utilizaría para llamar al método de prueba una vez para cada valor de datos. Mi problema es que las diferentes pruebas necesitan cargar datos de diferentes archivos y no parece haber ninguna forma de enviar un parámetro al proveedor de datos. ¿Alguien sabe si esto es posible?
Lo ideal es que mi código se vea como el siguiente (ejemplo simplificado):
public class OddTest {
@DataProvider(name = "excelLoader")
public Iterator<Object[]> loadExcelData(String fileName) {
...
}
@Test(dataProvider = "excelLoader" dataProviderParameters = { "data.xls" })
public void checkIsOddWorks(int num)
assertTrue(isOdd(num));
}
}
La respuesta de yshua es un poco limitante porque aún tiene que codificar las rutas de archivo dentro de su proveedor de datos. Esto significa que tendrá que cambiar el código fuente y luego volver a compilar para volver a ejecutar la prueba. Esto anula el propósito de usar archivos XML para configurar la ejecución de prueba.
Una solución mejor, definitivamente más intrincada, sería crear un método ficticio de @test que se ejecute antes de la suite, tome sus filepaths como parámetros y guarde esta información dentro de la Clase que contiene estos métodos de prueba.
Esta solución no es perfecta, pero hasta que TestNG permita una mejor transferencia de parámetros (quizás esto haya cambiado), esto podría ser viable para sus necesidades.
Para agregar a mi respuesta anterior, aquí está el código completo de cómo puedes hacerlo usando EasyTest Framework:
@RunWith(DataDrivenTestRunner.class)
public class MyTestClass {
@Test
@DataLoader(filePaths={myTestFile.xls}, loaderType=LoaderType.EXCEL)
public void testFirstMethod(@Param()
Map<String, Object> inputData) {
System.out.print("Executing testFirstMethod:");
System.out.println("library Id : " + inputData.get("LibraryId"));
}
@Test
@DataLoader(filePaths={mySecondTestFile.xls}, loaderType=LoaderType.EXCEL)
public void testSecondMethod(@Param(name="input")
MyClassObject inputData) {
System.out.print("Executing testSecondMethod:");
System.out.println("library Id : " + inputData.get("LibraryId"));
}
Y así. Si desea saber más sobre cómo funciona la anotación @DataLoader en EasyTest, consulte lo siguiente: https://github.com/EaseTech/easytest/wiki/EasyTest-:-Loading-Data-using-Excel
Tenga en cuenta que puede usar XML, Excel, CSV o su propio cargador personalizado para cargar los datos y todos pueden usarse en la misma clase de prueba a la vez, como se muestra en este ejemplo: https://github.com/EaseTech/easytest/blob/master/src/test/java/org/easetech/easytest/example/TestCombinedLoadingAndWriting.java
Espero que haya sido útil.
Puede acceder a todos los parámetros definidos en su Proveedor de datos utilizando las capacidades de inyección de dependencias de TestNG . Este es un ejemplo de DataProvider que necesita el parámetro "test_param":
@DataProvider(name = "usesParameter")
public Object[][] provideTestParam(ITestContext context) {
String testParam = context.getCurrentXmlTest().getParameter("test_param");
return new Object[][] {{ testParam }};
}
Esto requiere que se defina "test_param" en tu suite.xml
:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="suite">
<parameter name="test_param" value="foo" />
<test name="tests">
<classes>
...
</classes>
</test>
</suite>
Consulte el TestNG JavaDoc para obtener detalles sobre la clase ITestContext.
Tomado de los documentos de TestNG :
Si declara que su @DataProvider toma un java.lang.reflect.Method
como primer parámetro, TestNG pasará el método de prueba actual para este primer parámetro. Esto es particularmente útil cuando varios métodos de prueba usan el mismo @DataProvider y desea que retorne valores diferentes dependiendo del método de prueba para el que está suministrando datos.
Por ejemplo, el siguiente código imprime el nombre del método de prueba dentro de su @DataProvider:
@DataProvider(name = "dp")
public Object[][] createData(Method m) {
System.out.println(m.getName()); // print test method name
return new Object[][] { new Object[] { "Cedric" }};
}
@Test(dataProvider = "dp")
public void test1(String s) {
}
@Test(dataProvider = "dp")
public void test2(String s) {
}
y por lo tanto mostrará:
test1
test2
Esto también se puede combinar con la solución proporcionada por desolat para determinar los datos del contexto y el método en consecuencia:
@DataProvider(name = "dp")
public Object[][] foodp(ITestContext ctx, Method method) {
// ...
}
Una forma más genérica de hacer esto sería utilizar la anotación de groups
para crear una lista de valores personalizada:
@DataProvider(name = "excelLoader")
public Object[][] createData(Method m) {
ArrayList<Object[]> excelFiles = new ArrayList<Object[]>;
// iterate over all the groups listed in the annotation
for (String excelFile : ((Test) m.getAnnotation(Test.class)).groups()) {
// add each to the list
excelFiles.add(new Object[] { excelFile });
}
// convert the list to an array
return excelFiles.toArray(new Object[excelFiles.size()]);
}
@Test(dataProvider = "excelLoader", groups = { "data1", "data2" })
public void test1(String excelFile) {
// we will test "data1.xls" and "data2.xls" in this test
String testExcelFile = excelFile + ".xls";
}
@Test(dataProvider = "excelLoader", groups = { "data2", "data3" })
public void test2(String excelFile) {
// we will test "data2.xls" and "data3.xls" in this test
String testExcelFile = excelFile + ".xls";
}
Alternativamente, también puede crear su propia clase de anotación que toma elementos personalizados para que pueda hacer algo más como:
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE, CONSTRUCTOR})
public @interface FilesToTest {
public String[] value() default {};
}
@DataProvider(name = "excelLoader")
public Object[][] createData(Method m) {
ArrayList<Object[]> excelFiles = new ArrayList<Object[]>;
// iterate over all the groups listed in the annotation
for (String excelFile : ((FilesToTest) m.getAnnotation(FilesToTest.class)).value()) {
// add each to the list
excelFiles.add(new Object[] { excelFile });
}
// convert the list to an array
return excelFiles.toArray(new Object[excelFiles.size()]);
}
@Test(dataProvider = "excelLoader")
@FilesToTest({ "data1.xls", "data2.xls" })
public void myTest(String excelFile) {
// we will test "data1.xls" and "data2.xls" in this test
}