走進Java接口測試之測試框架TestNG
簡介
快速 Demo
基本注釋
常用斷言方法
testng.xml
測試方法,測試類和測試組
測試方法
測試組
群組
排除組
部分組
簡介
快速 Demo
基本注釋
常用斷言方法
testng.xml
測試方法,測試類和測試組
測試方法
測試組
群組
排除組
部分組
參數化
testng.xml 中的參數
使用 DataProviders 的參數
依賴性
帶注釋的依賴關系
XML 中的依賴關系
工廠
忽略測試
并行和超時
并行套件
并行測試,類和方法
重新運行失敗的測試
YAML文件
簡介
TestNG 是一個受 JUnit 和 NUnit 啟發的測試框架,旨在簡化廣泛的測試需求,從單元測試到接口測試。
但引入了一些新功能,使其更強大,更易于使用,例如:
注釋。
在線程池中運行測試,并提供各種可用策略(單線程,多線程等等)
測試的代碼是多線程安全的
靈活的測試配置
支持數據驅動的測試(使用 @DataProvider)
支持參數化
強大的執行模型(不再是 TestSuite)
由各種工具和插件(Eclipse,IDEA,Maven 等)支持。
嵌入 BeanShell 腳本以獲得更大的靈活性
用于運行時和日志記錄的缺省 JDK 函數(無依賴項)
應用服務器測試的依賴方法
TestNG旨在涵蓋所有類別的測試:單元,接口,端到端,集成等…
快速 Demo
編寫測試通常需要三個步驟:
編寫測試代碼插入TestNG注釋。
在 testng.xml 中添加有關測試的信息(例如:類名,要運行的組等)。
運行TestNG。
一個快速示例
package example1; import org.testng.annotations.*; public class SimpleTest { @BeforeClass public void setUp() { // 實例化時調用此代碼 } @Test(groups = { "fast" }) public void aFastTest() { System.out.println("Fast test"); } @Test(groups = { "slow" }) public void aSlowTest() { System.out.println("Slow test"); } }
在構建測試類之后和運行任何測試方法之前,將調用 方法 setUp()。在這個例子中,我們將快速運行組,所以 aFastTest() 將被調用,而 aSlowTest() 將被跳過。
注意事項:
無需擴展類或實現接口。
盡管上面的示例使用了JUnit 約定,但我們的方法可以被稱為任何名稱,它是告訴 TestNG 它們是什么的注釋。
測試方法可以屬于一個或多個組。
將測試類編譯到構建目錄后,可以使用命令行,ant 任務(如下所示)或 XML 文件調用測試
使用用 ant 調用它
c:> ant Buildfile: build.xml test: [testng] Fast test [testng] =============================================== [testng] Suite for Command line test [testng] Total tests run: 1, Failures: 0, Skips: 0 [testng] =============================================== BUILD SUCCESSFUL Total time: 4 seconds
然后,可以瀏覽測試結果:
start test-output\index.html (on Windows)
本文檔中使用的概念如下:
測試套件由一個 XML 文件表示。它可以包含一個或多個測試,并由 < suite > 標記定義。
測試由 < test > 表示,可以包含一個或多個 TestNG 類。
TestNG 類是一個包含至少一個 TestNG 注釋的 Java 類。它由 < class > 標記表示,可以包含一個或多個測試方法。
測試方法是由源中的 @Test 注釋的 Java 方法。
可以通過 @BeforeXXX 和 @AfterXXX 注釋來配置 TestNG 測試,該注釋允許在某個點之前和之后執行某些 Java 邏輯,這些點是上面列出的項目之一。
基本注釋
以下是 TestNG 中可用注釋及其屬性的概述表。
當放置在 TestNG 類的超類上時,上述注釋也將被繼承。例如,這對于在公共超類中集中多個測試類的測試設置非常有用。
在這種情況下,TestNG保證“@Before”方法以繼承順序執行(首先是最高超類,然后是繼承),而“@After”方法則按相反的順序執行(向上繼承鏈)。
@dataProvider: 將方法標記為為測試方法提供數據。
記一種方法來提供測試方法的數據。 注釋方法必須返回一個Object [] [],其中每個Object [] 可以被分配給測試方法的參數列表。 要從該DataProvider接收數據的 @Test 方法需要使用與此注釋名稱相等的dataProvider名稱。
@Factory: 將方法標記為工廠,返回將由 TestNG 用作 Test 類的對象。該方法必須返回 Object []。
@Listeners :在測試類上定義偵聽器。
@Parameters: 描述如何將參數傳遞給 @Test 方法。
@Test : 將類或方法標記為測試的一部分。
注意:如果未指定 invocationCount,則忽略此屬性
常用斷言方法
為了方便判斷測試用例是否執行成功,TestNG 特定提供了一個斷言類,里面含有多種形式的斷言方法。
testng.xml
您可以通過幾種不同的方式調用 TestNG:
使用 testng.xml 文件
ant
maven,如 mvn clean test -U -Dxml=xmlFileName
命令行
本節介紹 testng.xml 的格式(您將在下面找到有關ant和命令行的文檔)。
這是一個示例 testng.xml 文件
指定包名
在此示例中,TestNG 將執行包 test.sample 中的所有類, 并僅保留具有 TestNG 注釋的類。
指定要包含和排除的組和方法
在 testng.xml 中定義新組,并在屬性中指定其他詳細信息,例如是否并行運行測試,使用多少線程,是否運行測試等等…
默認情況下,TestNG 將按照 XML 文件中的順序運行測試。如果希望此文件中列出的類和方法以不可預測的順序運行,請將 preserve-order 屬性設置為 false
測試方法,測試類和測試組
測試方法
測試方法用 @Test 注釋。除非在 testng.xml 中將 allow-return-values 設置為 true,否則將忽略使用 @Test 注釋恰好返回值的方法:
測試組
TestNG 允許執行復雜的測試方法分組。不僅可以聲明方法屬于組,還可以指定包含其他組的組。然后可以調用 TestNG 并要求包括一組特定的組(或正則表達式),同時排除另一組。這為分區測試提供了最大的靈活性,如果想要連續運行兩組不同的測試,則不需要重新編譯任何內容。
組在 testng.xml 文件中指定,可以在 < test > 或 < suite > 標記下找到。
例如,至少有兩類測試是很常見的
辦理登機手續的測試。應在提交新代碼之前運行這些測試。它們通常應該很快,并確保沒有基本功能被破壞。
功能測試。這些測試應涵蓋軟件的所有功能,并且每天至少運行一次,盡管理想情況下希望連續運行它們。
通常,簽入測試是功能測試的子集。TestNG 允許以非常直觀的方式使用測試組指定。例如,可以通過整個測試類屬于 “functest” 組來構建測試,另外還有一些方法屬于 “checkintest” 組:
public class Test1 { @Test(groups = { "functest", "checkintest" }) public void testMethod1() { } @Test(groups = {"functest", "checkintest"} ) public void testMethod2() { } @Test(groups = { "functest" }) public void testMethod3() { } }
TestNG 調用
將運行該類中的所有測試方法,而使用 checkintest 調用它將只運行 testMethod1() 和 testMethod2()。
這是另一個例子,這次使用正則表達式。假設某些測試方法不應該在 Linux 上運行,測試將如下所示
@Test public class Test1 { @Test(groups = { "windows.checkintest" }) public void testWindowsOnly() { } @Test(groups = {"linux.checkintest"} ) public void testLinuxOnly() { } @Test(groups = { "windows.functest" ) public void testWindowsToo() { } }
可以使用以下 testng.xml 僅啟動 Windows 方法:
注意:TestNG 使用正則表達式,而不是 wildmats
方法組
還可以排除或包含單個方法
這可以派上用來停用單個方法而不必重新編譯任何東西,但是不建議過多地使用這種技術,因為如果開始重構你的 Java 代碼(正則表達式中使用的正則表達式),它會使你的測試框架崩潰。標簽可能不再符合您的方法)。
群組
組還可以包括其他組。這些組稱為 “MetaGroups”。例如,您可能希望定義包含 “checkintest” 和 “functest” 的組 “all”。“functest” 本身將包含 “windows” 和 “linux” 組,而 “checkintest” 將只包含 ”windows“。以下是如何在屬性文件中定義它:
排除組
TestNG 允許包括組以及排除它們。
例如,由于最近的更改而暫時中斷測試通常很常見,而還沒有時間修復破損。但是,確實想要進行功能測試的干凈運行,因此需要停用這些測試,但請記住需要重新激活它們。
解決此問題的一種簡單方法是創建一個名為 “broken” 的組,并使這些測試方法屬于它。
例如,在上面的例子中,我知道 testMethod2() 現在已經壞了所以我想禁用它:
@Test(groups = {"checkintest", "broken"} ) public void testMethod2() { }
我現在需要做的就是從運行中排除這個組:
這樣將獲得一個干凈的測試運行,同時跟蹤哪些測試被破壞,需要稍后修復。
注意:還可以使用 @Test 和 @Before / After 注釋上的 “enabled” 屬性逐個禁用測試。
部分組
可以在類級別定義組,然后在方法級別添加組:
@Test(groups = { "checkin-test" }) public class All { @Test(groups = { "func-test" ) public void method1() { ... } public void method2() { ... } }
在這個類中,method2() 是 “checkin-test” 組的一部分,它在類級定義,而 method1() 屬于 “checkin-test” 和 “func-test”。
參數化
測試方法不必是無參數的。可以在每個測試方法上使用任意數量的參數,并指示 TestNG 使用 @Parameters 注釋傳遞正確的參數。
有兩種方法可以設置這些參數:
使用 testng.xml
以編程方式。
testng.xml 中的參數
如果對參數使用簡單值,則可以在 testng.xml 中指定它們 :
@Parameters({ "first-name" }) @Test public void testSingleString(String firstName) { System.out.println("Invoked testString " + firstName); assert "Cedric".equals(firstName); }
在此代碼中,我們指定Java方法的參數 firstName 應該接收名為 first-name 的 XML 參數的值。 此 XML 參數在 testng.xml 中 定義:
@Before / After 和 @Factory 注釋可以使用相同的技術:
@Parameters({ "datasource", "jdbcDriver" }) @BeforeMethod public void beforeTest(String ds, String driver) { m_dataSource = ...; // 查詢數據源值 m_jdbcDriver = driver; }
這次,兩個 Java 參數 ds 和驅動程序將分別接收賦予屬性 datasource 和 jdbc-driver 的值。
可以使用 Optional 注釋將參數聲明為可選:
@Parameters("db") @Test public void testNonExistentParameter(@Optional("mysql") String db) { ... }
如果在 testng.xml 文件中找不到名為 “db” 的參數,則測試方法將接收 @Optional 注釋中指定的默認值:“mysql” 。
在 @Parameters 可以被放置在下列位置:
在任何已經有 @Test,@Before / After 或 @Factory 注釋的方法上。
最多只有一個測試類的構造函數。在這種情況下,TestNG 將調用此特定構造函數,并在需要實例化測試類時將參數初始化為 testng.xml 中指定的值。此功能可用于將類中的字段初始化為測試方法隨后將使用的值。
注意:
XML參數按照與注釋中相同的順序映射到 Java 參數,如果數字不匹配,TestNG 將發出錯誤。
參數是作用域的。在 testng.xml 中,您可以在< suite >標記下或< test >下聲明它們 。如果兩個參數具有相同的名稱,則它是< test >中定義的具有優先權的參數。如果您需要指定適用于所有測試的參數并僅為某些測試覆蓋其值,這將非常方便。
使用 DataProviders 的參數
如果需要傳遞復雜參數或需要從 Java 創建的參數(復雜對象,從屬性文件或數據庫讀取的對象等等),則在 testng.xml 中指定參數可能不夠。在這種情況下,您可以使用數據提供程序提供測試所需的值。數據提供程序是類上的一個方法,它返回一組對象數組。此方法使用 @DataProvider 注釋:
//This method will provide data to any test method that declares that its Data Provider //is named "test1" @DataProvider(name = "test1") public Object[][] createData1() { return new Object[][] { { "Cedric", new Integer(36) }, { "Anne", new Integer(37)}, }; } //This test method declares that its data should be supplied by the Data Provider //named "test1" @Test(dataProvider = "test1") public void verifyData1(String n1, Integer n2) { System.out.println(n1 + " " + n2); }
將打印
Cedric 36 Anne 37
甲 @Test 方法指定了與數據提供數據提供程序屬性。此名稱必須對應于 使用匹配名稱的 @DataProvider(name =“…”)注釋的同一類上的方法。
默認情況下,將在當前測試類或其中一個基類中查找數據提供程序。如果要將數據提供程序放在不同的類中,則需要使用靜態方法或具有非 arg 構造函數的類,并指定可在 dataProviderClass 屬性中找到的類:
public class StaticProvider { @DataProvider(name = "create") public static Object[][] createData() { return new Object[][] { new Object[] { new Integer(42) } }; } } public class MyTest { @Test(dataProvider = "create", dataProviderClass = StaticProvider.class) public void test(Integer n) { // ... } }
數據提供者也支持注入。TestNG 將使用測試上下文進行注射。Data Provider方法可以返回以下兩種類型之一:
一組對象數組(Object [] []),其中第一個維度的大小是調用測試方法的次數,第二個維度大小包含必須與測試的參數類型兼容的對象數組方法。這是上述示例所示的情況。
一個迭代< Object [] [] > 。與Object [] []的唯一區別在于 Iterator 允許您懶惰地創建測試數據。TestNG 將調用迭代器,然后使用此迭代器返回的參數逐個調用測試方法。如果您有許多參數集要傳遞給方法,并且您不想預先創建所有參數集,則此功能特別有用。
以下是此功能的示例:
@DataProvider(name = "test1") public Iterator
如果您將 @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
數據提供程序可以與并行屬性并行運行:
@DataProvider(parallel = true) // ...
從 XML 文件運行的并行數據提供程序共享相同的線程池,默認情況下大小為 10。您可以在 XML 文件的< suite >標記中修改此值:
如果要在不同的線程池中運行幾個特定的 數據提供程序,則需要從其他XML文件運行它們。
依賴性
有時,您需要按特定順序調用測試方法。這里有一些例子:
在運行更多測試方法之前,確保已完成并成功執行一定數量的測試方法。
要初始化測試,同時希望這個初始化方法也是測試方法(使用 @Before / After 標記的方法不會成為最終報告的一部分)。
TestNG 允許您使用注釋或 XML 指定依賴項。
帶注釋的依賴關系
您可以使用屬性 dependsOnMethods 或 dependsOnGroups,對發現的@Test注解。
有兩種依賴關系:
硬依賴。您依賴的所有方法必須運行并成功運行。如果您的依賴項中至少發生一次故障,則不會在報告中調用并將其標記為 SKIP。
軟依賴。您將始終在您依賴的方法之后運行,即使其中一些方法失敗了。當您只是想確保您的測試方法按特定順序運行時,這很有用,但它們的成功并不真正取決于其他人的成功。通過在 @Test 注釋中添加 “alwaysRun = true” 來獲得軟依賴關系。
以下是硬依賴的示例:
@Test public void serverStartedOk() {} @Test(dependsOnMethods = { "serverStartedOk" }) public void method1() {}
在此示例中,method1() 聲明為依賴于方法 serverStartedOk() ,這保證始終首先調用 serverStartedOk() 。
您還可以擁有依賴于整個組的方法:
@Test(groups = { "init" }) public void serverStartedOk() {} @Test(groups = { "init" }) public void initEnvironment() {} @Test(dependsOnGroups = { "init.*" }) public void method1() {}
在此示例中,method1()聲明為依賴于與正則表達式“init。*”匹配的任何組,這保證了方法serverStartedOk() 和initEnvironment()將始終在method1()之前調用。
注意:如前所述,對于屬于同一組的方法,調用順序不保證在測試運行中是相同的。
如果依賴的方法失敗并且您對它有一個硬依賴( alwaysRun = false,這是默認值),依賴它的方法不會 標記為 FAIL 而是標記為 SKIP。跳過的方法將在最終報告中報告(在 HTML中顏色既不是紅色也不是綠色),這很重要,因為跳過的方法不一定是失敗的。
無論 dependsOnGroups 和 dependsOnMethods 接受正則表達式作為參數。對于 dependsOnMethods,如果您依賴于碰巧有多個重載版本的方法,則將調用所有重載的方法。如果您只想調用其中一個重載方法,則應使用 dependsOnGroups。
默認情況下,依賴方法按類分組。例如,如果方法b()依賴于方法a(),并且您有幾個包含這些方法的類的實例(因為數據提供程序的工廠),則調用順序如下:
a(1) a(2) b(2) b(2)
在所有實例調用其 a() 方法之前, TestNG 不會運行 b() 。
在某些情況下可能不希望出現這種情況,例如測試登錄和退出各個國家/地區的Web瀏覽器。在這種情況下,您需要以下訂購:
signIn("us") signOut("us") signIn("uk") signOut("uk")
對于此排序,可以逐個實例使用 XML 屬性。此屬性在 < suite > 或 < test > 上有效:
XML 中的依賴關系
可以在 testng.xml 文件中指定組依賴項。使用 < dependencies > 標記來實現此目的:
以上所述 < depends-on > 屬性包含一個以空格分隔的組列表。
工廠
工廠允許動態創建測試。
例如,假設要創建一個將多次訪問網站上的頁面的測試方法,并且希望使用不同的值調用它:
public class TestWebServer { @Test(parameters = { "number-of-times" }) public void accessPage(int numberOfTimes) { while (numberOfTimes-- > 0) { // access the web page } } }
這很快就無法管理,所以你應該使用工廠
public class WebTestFactory { @Factory public Object[] createInstances() { Object[] result = new Object[10]; for (int i = 0; i < 10; i++) { result[i] = new WebTest(i * 10); } return result; } }
現在新的測試類
public class WebTest { private int m_numberOfTimes; public WebTest(int numberOfTimes) { m_numberOfTimes = numberOfTimes; } @Test public void testServer() { for (int i = 0; i < m_numberOfTimes; i++) { // access the web page } } }
您的 testng.xml 只需要引用包含工廠方法的類,因為測試實例本身將在運行時創建
或者,如果以編程方式構建測試套件實例,則可以按照與測試相同的方式添加工廠
TestNG testNG = new TestNG(); testNG.setTestClasses(WebTestFactory.class); testNG.run();
工廠方法可以像 @Test 和 @Before / After 一樣接收參數,它必須返回 Object [] 。返回的對象可以是任何類(不一定是與工廠類相同的類),它們甚至不需要包含 TestNG 注釋(在這種情況下,它們將被 TestNG 忽略)。
工廠也可以與數據提供者一起使用,您可以通過將 @Factory 注釋放在常規方法或構造函數上來利用此功能。
以下是構造函數工廠的示例:
@Factory(dataProvider = "dp") public FactoryDataProviderSampleTest(int n) { super(n); } @DataProvider static public Object[][] dp() { return new Object[][] { new Object[] { 41 }, new Object[] { 42 }, }; }
該示例將使TestNG創建兩個測試類,使用值41調用構造函數,另一個調用42。
忽略測試
TestNG允許您忽略所有@Test方法:
一個類(或)
特定包(或)
一個包及其所有子包中
使用新注釋 @Ignore。
在方法級別使用 @Ignore 注釋在功能上等同于 @Test(enabled = false)。這是一個示例,顯示如何忽略類中的所有測試。
import org.testng.annotations.Ignore; import org.testng.annotations.Test; @Ignore public class TestcaseSample { @Test public void testMethod1() { } @Test public void testMethod2() { } }
該 @Ignore 注釋具有比個人更高的優先級 @Test 方法的注釋。當 @Ignore 放在一個類上時,該類中的所有測試都將被禁用。
要忽略特定包中的所有測試,只需創建 package-info.java 并將 @Ignore 注釋添加到其中。這是一個示例:
@Ignore package com.testng.master; import org.testng.annotations.Ignore;
這會導致 com.testng.master 包及其所有子包中的所有 @Test 方法都被忽略。
并行和超時
可以指示 TestNG 以各種方式在單獨的線程中運行測試。
并行套件
如果您運行多個套件文件(例如“ java org.testng.TestNG testng1.xml testng2.xml”)并且希望每個套件都在一個單獨的線程中運行,這將非常有用。您可以使用以下命令行標志來指定線程池的大小:
java org.testng.TestNG -suitethreadpoolsize 3 testng1.xml testng2.xml testng3.xml
相應的 ant 任務名稱是 suitethreadpoolsize。
并行測試,類和方法
在平行于 < suite > 屬性標簽可以采取以下值之一:
parallel =“methods”:TestNG將在不同的線程中運行所有測試方法。依賴方法也將在單獨的線程中運行,但它們將遵循您指定的順序。
parallel =“tests”:TestNG將在同一個線程中運行相同 < test > 標記中的所有方法,但每個< test > 標記將位于一個單獨的線程中。這允許您在同一個 < test > 中對所有非線程安全的類進行分組,并保證它們將在同一個線程中運行,同時利用 TestNG 使用盡可能多的線程來運行測試。
parallel =“classes”:TestNG 將在同一個線程中運行同一個類中的所有方法,但每個類將在一個單獨的線程中運行
parallel =“instances”:TestNG 將在同一個線程中運行同一實例中的所有方法,但兩個不同實例上的兩個方法將在不同的線程中運行。
此外,屬性 thread-count 允許指定應為此執行分配的線程數。
注意:@Test 屬性 timeOut 在并行和非并行模式下都有效。
您還可以指定應從不同的線程調用 @Test 方法。您可以使用 threadPoolSize 屬性來實現此結果:
@Test(threadPoolSize = 3, invocationCount = 10, timeOut = 10000) public void testServer() {
在此示例中,函數 testServer 將從三個不同的線程調用十次。此外,超時十秒可確保所有線程都不會永久阻塞此線程。
重新運行失敗的測試
每次測試在套件中失敗時,TestNG 都會在輸出目錄中創建一個名為 testng-failed.xml 的文件。此 XML 文件包含僅重新運行失敗的這些方法的必要信息,使您可以快速重現故障,而無需運行整個測試。因此,典型的會話將如下所示:
java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -d test-outputs testng.xml java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -d test-outputs test-outputs\testng-failed.xml
請注意,testng-failed.xml 將包含所有必需的依賴方法,以便您可以保證在沒有任何 SKIP 故障的情況下運行失敗的方法。
有時,您可能希望TestNG在失敗時自動重試測試。在這些情況下,您可以使用重試分析器。當您將重試分析器綁定到測試時,TestNG會自動調用重試分析器以確定TestNG是否可以再次重試測試用例,以嘗試查看現在剛剛失敗的測試是否通過。以下是使用重試分析器的方法:
構建org.testng.IRetryAnalyzer 接口的實現
將此實現綁定到 @Test 注釋,例如 @Test(retryAnalyzer = LocalRetry.class)
以下是重試分析器的示例實現,重試測試最多三次。
import org.testng.IRetryAnalyzer; import org.testng.ITestResult; public class MyRetry implements IRetryAnalyzer { private int retryCount = 0; private static final int maxRetryCount = 3; @Override public boolean retry(ITestResult result) { if (retryCount < maxRetryCount) { retryCount++; return true; } return false; } } import org.testng.Assert; import org.testng.annotations.Test; public class TestclassSample { @Test(retryAnalyzer = MyRetry.class) public void test2() { Assert.fail(); } }
YAML文件
TestNG 支持 YAML作為指定套件文件的替代方法。例如,以下 XML 文件:
這是它的YAML版本:
name: SingleSuite threadCount: 4 parameters: { n: 42 } tests: - name: Regression2 parameters: { count: 10 } excludedGroups: [ broken ] classes: - test.listeners.ResultEndMillisTest
這是 TestNG 自己的套件文件,以及它的 YAML 對應文件。
您可能會發現 YAML 文件格式更易于閱讀和維護。TestNG Eclipse 插件也可以識別 YAML 文件。
注意:
默認情況下,TestNG 不會將 YAML 相關庫引入您的類路徑。因此,根據您的構建系統(Gradle / Maven),您需要在構建文件中添加對 YAML 庫的顯式引用。
例如,如果使用的是 Maven,則需要在pom.xml文件中添加如下依賴項:
參考資料:
[1] https://testng.org/doc/index.html
Java 自動化測試
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。