webentwicklung-frage-antwort-db.com.de

Möglich, Parameter an TestNG DataProvider zu übergeben?

Wir möchten einige unserer Tests jeweils mit einer Reihe von Datenwerten durchführen, um sicherzustellen, dass für alle dieselben Bedingungen gelten. Die Daten werden derzeit entweder in Einfachdateien oder in einfachen Excel-Arbeitsblättern gespeichert.

Mein erster Gedanke war, einen TestNG-Datenprovider zu erstellen, der die Daten aus der Datei lädt und zum einmaligen Aufrufen der Testmethode für jeden Datenwert verwendet wird. Mein Problem ist, dass verschiedene Tests Daten aus verschiedenen Dateien laden müssen und es keine Möglichkeit zu geben scheint, einen Parameter an den DataProvider zu senden. Weiß jemand, ob dies möglich ist?

Im Idealfall möchte ich, dass mein Code wie folgt aussieht (vereinfachtes Beispiel):

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));
    }
}
20
Benjamin Lee

Sie können auf alle definierten Parameter in Ihrem DataProvider zugreifen, indem Sie TestNGs Abhängigkeitsinjektionsfähigkeiten verwenden. Dies ist ein Beispiel für einen DataProvider, der den Parameter "test_param" benötigt:

@DataProvider(name = "usesParameter")
public Object[][] provideTestParam(ITestContext context) {
    String testParam = context.getCurrentXmlTest().getParameter("test_param");
    return new Object[][] {{ testParam }};
}

Dies erfordert, dass "test_param" in Ihrem suite.xml definiert ist:

<!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>

Weitere Informationen zur ITestContext-Klasse finden Sie in TestNG JavaDoc .

17
desolat

Aus den TestNG-Dokumenten entnommen

Wenn Sie erklären, dass Ihr @DataProvider einen Java.lang.reflect.Method als ersten Parameter verwendet, besteht TestNG die aktuelle Testmethode für diesen ersten Parameter. Dies ist besonders nützlich, wenn mehrere Testmethoden denselben @DataProvider verwenden und Sie möchten, dass er unterschiedliche Werte zurückgibt, je nachdem für welche Testmethode er Daten liefert.

Mit dem folgenden Code wird beispielsweise der Name der Testmethode in seinem @DataProvider gedruckt:

@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) {
}

und wird daher anzeigen:

test1
test2

Dies kann auch mit der von desolat bereitgestellten Lösung kombiniert werden, um Daten aus dem Kontext und der Methode entsprechend zu ermitteln:

    @DataProvider(name = "dp")
    public Object[][] foodp(ITestContext ctx, Method method) {
        // ...
    }
15
user64051

Eine allgemeinere Methode wäre, die Annotation groups zu verwenden, um eine benutzerdefinierte Liste von Werten zu erstellen:

@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";
}

Alternativ können Sie auch eine eigene Anmerkungsklasse erstellen, die benutzerdefinierte Elemente enthält, sodass Sie etwas mehr tun können:

@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
}
3
Godwin

Die Antwort von yshua ist ein wenig einschränkend, da Sie die Dateipfade in Ihrem Datenprovider immer noch hart codieren müssen. Dies bedeutet, dass Sie den Quellcode ändern und dann erneut kompilieren müssen, um den Test erneut auszuführen. Dies verhindert die Verwendung von XML-Dateien zur Konfiguration des Testlaufs. 

Eine bessere, definitiv hacklige Lösung einer Lösung wäre, eine [email protected] zu erstellen, die vor suite ausgeführt wird, Ihre Dateipfade als Parameter verwendet und diese Informationen in der Klasse speichert, in der diese Testmethoden untergebracht sind.

Diese Lösung ist nicht perfekt, aber bis TestNG eine bessere Parameterübergabe zulässt (möglicherweise hat sich dies geändert), kann dies für Ihre Anforderungen sinnvoll sein.

1
esiegel

Um zu meiner Antwort oben hinzuzufügen, geben Sie den vollständigen Code für die Verwendung von EasyTest Framework ein:

@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"));

}

Und so weiter. Wenn Sie mehr darüber wissen möchten, wie die @ DataLoader-Annotation in EasyTest funktioniert, sehen Sie sich Folgendes an: https://github.com/EaseTech/easytest/wiki/EasyTest-:- Laden von Daten mit Excel

Beachten Sie, dass Sie XML, Excel, CSV oder Ihren eigenen benutzerdefinierten Loader verwenden können, um die Daten zu laden. Alle können in derselben Testklasse verwendet werden, wie in diesem Beispiel gezeigt: https://github.com/EaseTech/easytest /blob/master/src/test/Java/org/easetech/easytest/example/TestCombinedLoadingAndWriting.Java

Ich hoffe es war nützlich.

0
Anuj