簡體   English   中英

TestNG:使用dataProvider在測試用例之間交替

[英]TestNG: alternate between test cases with dataProvider

我已經實現了 dataProvider,它適用於每個 class,但它不會在測試用例之間交替。

它目前所做的是:從測試用例 1 和 go 開始,遍歷 dataProvider 中的所有數據集,然后轉到測試用例 2,並對所有數據集執行相同的操作。

我想在測試用例之間交替:

  • 從 dataProvider 的第 1開始:測試用例 1 和數據集的第 1,然后移動到測試用例 2 和 dataProvider 的第 1 行,然后是測試用例 3 和 dataProvider 的第 1 行...完成所有測試用例后,然后

  • 移動到 dataProvider 的第 2 行並重新開始:測試用例 1 和 dataProvider 的第 2 行,然后是測試用例2和 dataProvider 的第 2......這可能嗎?

您在尋找類級別的 DataProvider 嗎?

為了參數化測試 class,請按以下方式使用@Factory + @DataProvider

import org.testng.annotations.DataProvider
import org.testng.annotations.Factory
import org.testng.annotations.Test

class MyTestClass {

    String arg1;
    String arg2;

    @Factory(dataProvider = "provideClassArgs")
    public MyTestClass(String arg1, String arg2) {
        this.arg1 = arg1;
        this.arg2 = arg2;
    }

    @DataProvider
    public static Object[][] provideClassArgs() {
        return new Object[]{
                {"arg1-value1", "arg2-value1"},
                {"arg1-value2", "arg2-value2"}

        };
    }

    @Test
    public void test1() {
        System.out.println("Do test1 with: " + arg1 + ", " + arg2);
    }

    @Test
    public void test2() {
        System.out.println("Do test2 with: " + arg1 + ", " + arg2);
    }

    @Test
    public void test3() {
        System.out.println("Do test3 with: " + arg1 + ", " + arg2);
    }
}

與下一個textng.xml

注意:應定義group-by-instances="true"

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Test Suite" group-by-instances="true">
    <test name="Test">
        <classes>
            <class name="samples.MyTestClass"/>
        </classes>
    </test>
</suite>

你會得到:

Do test1 with: arg1-value2, arg2-value2
Do test2 with: arg1-value2, arg2-value2
Do test3 with: arg1-value2, arg2-value2
Do test1 with: arg1-value1, arg2-value1
Do test2 with: arg1-value1, arg2-value1
Do test3 with: arg1-value1, arg2-value1

Class 執行單

默認情況下,DataProvider 項目將以隨機順序啟動類。

固定順序的最簡單方法:覆蓋測試類的toString()方法。

對於這個例子:

@Override
public String toString() {
    return "MyTestClass";
}

測試將根據 DataProvider args 按字母順序排序,轉換為字符串。 這不會像 DataProvider 中那樣是自然順序,但至少不是隨機的。

查看更多:


將 Factory 與 DataProvider 一起用於多個類

注意:請求是在每個 args 行運行所有類,然后在每個 arg 行運行相同的類,等等。

  1. 為所有測試類創建父類 class。

    • 它應該定義所有必需的 arguments
    • 它應該有一個用於所有 arguments 的構造函數
    • 它應該覆蓋toString()方法,結果將由所有參數反映。 這對於執行順序是有價值的
public class MyClassParent {

  String arg1;
  String arg2;

  public MyClassParent(String arg1, String arg2) {
      this.arg1 = arg1;
      this.arg2 = arg2;
  }

  @Override
  public String toString() {
      arg1.toString() + arg2.toString();
  }
}
  1. 實現測試類,例如:

    • MyClassParent擴展
    • 創建相同的構造函數
public class MyTestClass1 extends MyClassParent {

    public MyTestClass1(String arg1, String arg2) {
        super(arg1, arg2);
    }

    @Test
    public void test1() {
        System.out.println("MyTestClass1: Do test1 with: " + arg1 + ", " + arg2);
    }

}
  1. 使用 DataProvider 實現工廠。

帶有 DataProvider 的工廠移動到單獨的 class 並生成測試 class 對象數組。

  • 為了應用正確的排序IMethodInterceptor TestNG 實現了監聽器接口。
  • 並通過@Listeners(MyFactory)申請了 class 。
  • intercept方法被覆蓋並在此處應用排序。
  • 為排序實現的自定義比較器,它根據它的toString()結果比較 2 個MyClassParent

因此,雖然toString()依賴於MyClassParent args,但相同 args 的所有類都將在同一組中。

import org.testng.IMethodInstance
import org.testng.IMethodInterceptor
import org.testng.ITestContext
import org.testng.annotations.DataProvider
import org.testng.annotations.Factory
import org.testng.annotations.Listeners

@Listeners(MyFactory)
public class MyFactory implements IMethodInterceptor {

    @Factory(dataProvider = "provideClassArgs")
    public Object[] generateTests(String arg1, String arg2) {
        return new Object[] {
                new MyTestClass1(arg1, arg2),
                new MyTestClass2(arg1, arg2),
                new MyTestClass3(arg1, arg2),
                new MyTestClass4(arg1, arg2),
                new MyTestClass5(arg1, arg2)
        };
    }

    @DataProvider
    public static Object[][] provideClassArgs() {
        return new Object[]{
                {"arg1-value1", "arg2-value1"},
                {"arg1-value2", "arg2-value2"},
                {"arg1-value3", "arg2-value2"}

        };
    }

    @Override
    List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
        // applying sorting is essential to change the tests order
        methods.sort(new MyTestClassComparator());
        return methods;
    }

    // internal class added, assumed it should compare only methods from MainImpClass
    // here compareTo delegated to getA() results
    class MyTestClassComparator implements Comparator<IMethodInstance> {

        @Override
        int compare(IMethodInstance o1, IMethodInstance o2) {
            return ((MyClassParent)o1.getInstance()).toString().compareTo(((MyClassParent)o2.getInstance()).toString());
        }
    }
}

4 TestNG xml:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Test Suite" group-by-instances="true">
    <test name="Test">
        <classes>
            <class name="samples.MyFactory"/>
        </classes>
    </test>
</suite>

最后的output:

MyTestClass1: Do test1 with: arg1-value1, arg2-value1
MyTestClass2: Do test2 with: arg1-value1, arg2-value1
MyTestClass3: Do test3 with: arg1-value1, arg2-value1
MyTestClass4: Do test4 with: arg1-value1, arg2-value1
MyTestClass5: Do test5 with: arg1-value1, arg2-value1
MyTestClass1: Do test1 with: arg1-value2, arg2-value2
MyTestClass2: Do test2 with: arg1-value2, arg2-value2
MyTestClass3: Do test3 with: arg1-value2, arg2-value2
MyTestClass4: Do test4 with: arg1-value2, arg2-value2
MyTestClass5: Do test5 with: arg1-value2, arg2-value2
MyTestClass1: Do test1 with: arg1-value3, arg2-value2
MyTestClass2: Do test2 with: arg1-value3, arg2-value2
MyTestClass3: Do test3 with: arg1-value3, arg2-value2
MyTestClass4: Do test4 with: arg1-value3, arg2-value2
MyTestClass5: Do test5 with: arg1-value3, arg2-value2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM