web-dev-qa-db-ja.com

TestNG DataProviderにパラメーターを渡すことは可能ですか?

データ値のセットに対していくつかのテストをそれぞれ実行し、同じ条件がそれぞれに当てはまることを確認します。データは現在、フラットファイルまたは単純なExcelスプレッドシートに保存されています。

私の最初の考えは、ファイルからデータをロードし、各データ値に対して一度テストメソッドを呼び出すために使用されるTestNG DataProviderを作成することでした。私の問題は、さまざまなテストがさまざまなファイルからデータをロードする必要があり、パラメーターをDataProviderに送信する方法がないように見えることです。 これが可能かどうか誰かが知っていますか?

理想的には、コードを次のようにする(簡単な例):

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

TestNGの依存性注入機能 を使用して、DataProviderで定義されたすべてのパラメーターにアクセスできます。これは、「test_param」パラメータを必要とするDataProviderの例です。

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

これには、「test_param」を定義する必要があります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>

ITestContextクラスの詳細については、 TestNG JavaDoc を参照してください。

17
desolat

TestNG docs から取得:

@DataProviderをJava.lang.reflect.Method最初のパラメーターとして、TestNGはこの最初のパラメーターの現在のテストメソッドを渡します。これは、複数のテストメソッドが同じ@DataProviderを使用し、データを提供するテストメソッドに応じて異なる値を返すようにする場合に特に便利です。

たとえば、次のコードは、@ 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) {
}

したがって、次のように表示されます。

test1
test2

これをdesolatが提供するソリューションと組み合わせて、コンテキストとメソッドに応じてデータを決定することもできます。

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

これを行うより一般的な方法は、groupsアノテーションを使用して値のカスタムリストを作成することです。

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

あるいは、カスタム要素を取り込む独自の注釈クラスを作成して、次のようなことを行うこともできます。

@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

Yshuaからの回答は、データプロバイダー内のファイルパスをハードコードする必要があるため、少し制限があります。つまり、ソースコードを変更してから、再コンパイルしてテストを再実行する必要があります。これは、XMLファイルを使用してテスト実行を構成する目的を無効にします。

ソリューションのより確実な、よりハッキーで厄介なことは、スイートの前に実行されるダミーの@testメソッドを作成し、ファイルパスをパラメーターとして受け取り、これらのテストメソッドを含むクラス内にこの情報を保存することです。

このソリューションは完璧ではありませんが、TestNGがより良いパラメーターの受け渡しを許可するまで(これは変更されている可能性があります)、ニーズに応じて実行できる可能性があります。

1
esiegel

上記の私の答えに追加するには、EasyTestフレームワークを使用してそれを行う方法の完全なコードを次に示します。

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

}

等々。 EasyDataで@DataLoaderアノテーションがどのように機能するかについて詳しく知りたい場合は、以下を参照してください。 https://github.com/EaseTech/easytest/wiki/EasyTest-:-Loading-Data-using-Excel

XML、Excel、CSV、または独自のカスタムローダーを使用してデータをロードでき、次の例に示すように、すべてを同じテストクラスで一度に使用できることに注意してください: https://github.com/EaseTech /easytest/blob/master/src/test/Java/org/easetech/easytest/example/TestCombinedLoadingAndWriting.Java

お役に立てば幸いです。

0
Anuj