一、testNG
1. testNG優勢
注解驅動: TestNG 使用注解來標識測試方法、測試類和配置方法,使得測試更具可讀性。
并行執行: TestNG 支持多線程并行執行測試,可以加速測試套件的執行。
豐富的配置: 可以通過 XML 配置文件來定義測試套件的執行順序、依賴關系等。
分組測試: 可以將測試方法分組,實現對特定測試分組的執行。
參數化測試: 可以使用 @Parameters 和@ DataProvider注解實現參數化測試
依賴管理: 可以通過 dependsOnMethods 或 dependsOnGroups 設置測試方法之間的依賴關系。
斷言靈活: TestNG 提供了豐富的斷言方法,用于驗證測試結果。
2. testNG常用注解
@Test:用于標識測試方法,執行單元測試。
@BeforeSuite:在測試套件之前執行。
@AfterSuite:在測試套件之后執行。
@BeforeTest:在測試類之前執行。
@AfterTest:在測試類之后執行。
@BeforeClass:在測試類中的所有測試方法之前執行。
@AfterClass:在測試類中的所有測試方法之后執行。
@BeforeMethod:在每個測試方法之前執行。
@AfterMethod:在每個測試方法之后執行。
@DataProvider:用于提供測試數據。
@Parameters:用于參數化測試。
@dependsOnMethods:設置測試方法的依賴關系。
package AI.Test.testNG;import org.testng.annotations.*;public class TestNGCheck {@BeforeSuitepublic void beforeSuite(){System.out.println("beforeSuite");}@BeforeTestpublic void beforeTest() {System.out.println("Before Test");}@BeforeClasspublic void beforeClass() {System.out.println("Before Class");}@BeforeMethodpublic void beforeMethod() {System.out.println("Before Method");}@Test(groups="Performance")public void testMethod1() {System.out.println("Test Method 1");}@AfterMethodpublic void afterMethod() {System.out.println("After Method");}@AfterClasspublic void afterClass() {System.out.println("After Class");}@AfterTestpublic void afterTest() {System.out.println("After Test");}@AfterSuitepublic void afterSuite() {System.out.println("After Suite");}}
3. testNG中@Test有哪些參數
1. 常用的:
groups: 用于將測試方法分組,可以在 XML 配置中選擇性地執行指定組的測試。
timeOut: 指定方法的超時時間,單位為毫秒。
alwaysRun: 如果設置為 true,則無論依賴的方法是否失敗,當前方法都會執行。
dependsOnMethods: 指定測試方法的依賴關系,被依賴的方法會在當前方法之前執行。
enabled: 控制測試方法是否啟用,設置為 false 則禁用該方法。
description: 提供關于測試方法的簡要描述。
invocationCount: 指定測試方法被調用的次數。2. 數據驅動,需要結合@DataProvider注解對應獲取參數的方法:
dataProvider: 指定使用哪個數據提供者來提供測試數據。
dataProviderClass: 指定數據提供者所在的類。3.并發:
invocationCount: 指定測試方法被調用的次數。
threadPoolSize: 指定線程池的大小,用于并行執行測試方法。
dataProviderThreadCount: 指定數據提供者線程的數量。
舉例:
@Test(groups="Performance")public void testMethod1() {System.out.println("Test Method 1");}@Test(priority=1)public void testMethod2() {System.out.println("Test Method 2");}@Test(dependsOnMethods = "testMethod4", alwaysRun = false)public void testMethod3(){System.out.println("Test Method 3");}@Test(timeOut = 3000)public void testMethod4() throws InterruptedException {Thread.sleep(4000);System.out.println("Test Method 4");}@Test(enabled = false, description = "用于測試enable注解")public void testMethod5() {System.out.println("Test Method 5");}
4.?在 TestNG 中實現參數化測試
以Yaml文件為例
創建一個Yaml文件testdata.yaml
testdata:- parameters: [2, 3, 5]- parameters: [10, 20, 30]
獲取測試數據及使用
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.yaml.snakeyaml.Yaml;import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;public class ParameterizedTest {@DataProvider(name = "testData")public Object[][] getYamlData() {List<Object[]> testData = new ArrayList<>();Yaml yaml = new Yaml();InputStream inputStream = getClass().getClassLoader().getResourceAsStream("testdata.yaml");Map<String, List<List<Integer>>> dataMap = yaml.load(inputStream);List<List<Integer>> parametersList = dataMap.get("testdata");for (List<Integer> parameters : parametersList) {testData.add(parameters.toArray());}return testData.toArray(new Object[testData.size()][]);}@Test(dataProvider = "testData")public void testParameterized(int param1, int param2, int param3) {System.out.println("Test with parameters: " + param1 + ", " + param2 + ", " + param3);// 執行測試邏輯,使用參數化數據進行測試}
}
5. 執行順序
TestNG 默認情況下會按照測試方法的名稱升序執行。
可以通過設置 priority 屬性來指定執行順序。
也可以使用dependsOnMethods
6. testNG斷言
assertEquals(expected, actual):
驗證兩個值是否相等。如果不相等,會拋出 AssertionError。assertNotEquals(expected, actual):
驗證兩個值是否不相等。如果相等,會拋出 AssertionError。assertTrue(condition):
驗證給定的條件是否為真。如果條件為假,會拋出 AssertionError。assertFalse(condition):
驗證給定的條件是否為假。如果條件為真,會拋出 AssertionError。assertNull(object):
驗證給定的對象是否為 null。如果對象不為 null,會拋出 AssertionError。assertNotNull(object):
驗證給定的對象是否不為 null。如果對象為 null,會拋出 AssertionError。assertSame(expected, actual):
驗證兩個引用是否指向同一個對象。如果不指向同一個對象,會拋出 AssertionError。assertNotSame(expected, actual):
驗證兩個引用是否指向不同的對象。如果指向同一個對象,會拋出 AssertionError。
二、Junit5
1. junit5的優勢
現代化的設計: JUnit 5 的架構更加模塊化和現代化,采用了模塊化體系結構,使得集成和擴展更加容易。它引入了 Jupiter(新的測試引擎)和 Vintage(支持 JUnit 4)兩個模塊,具有更好的靈活性。Lambda 表達式支持: JUnit 5 充分利用了 Java 8 的 Lambda 表達式特性,使測試代碼更加簡潔。TestNG 也支持 Lambda 表達式,但 JUnit 5 的設計更加貼合現代 Java 特性。參數化測試: JUnit 5 提供了內置的參數化測試功能,使用 @ParameterizedTest 注解,可以輕松地對測試方法使用不同的參數運行。動態測試: JUnit 5 引入了動態測試,允許在運行時生成和執行測試。使用 @TestFactory 注解,可以動態生成測試方法,以適應更加靈活的測試需求。擴展機制: JUnit 5 的擴展機制更加強大和靈活,使用 @ExtendWith 注解,可以輕松應用自定義擴展,甚至可以自定義擴展來修改測試運行時的行為。條件測試: JUnit 5 允許根據條件決定是否執行測試方法,使用 @EnabledOnOs、@DisabledIf 等注解,可以根據操作系統、環境變量等條件來控制測試執行。并行執行: TestNG 在并行執行方面有很強的功能,但 JUnit 5 也在逐步增強并行執行的支持,對于簡單的并行需求,JUnit 5 也可以勝任。靈活性: JUnit 5 允許更多的自定義配置,使得測試執行的控制更加靈活,可以根據不同的項目需求進行調整。
2. 常用注解
@Test: 用于標記測試方法。@DisplayName: 為測試方法或測試類指定一個可讀的名稱。@BeforeEach: 在每個測試方法之前執行的方法。@AfterEach: 在每個測試方法之后執行的方法。@BeforeAll: 在所有測試方法之前執行的方法,必須是靜態方法。@AfterAll: 在所有測試方法之后執行的方法,必須是靜態方法。@Disabled: 標記測試方法或測試類為禁用狀態。@ParameterizedTest: 用于參數化測試的注解。@RepeatedTest: 用于指定重復執行測試方法的次數。@Timeout: 用于設置測試方法執行的最大時間。時間是s@Tag: 為測試方法添加標簽,用于分組和過濾測試。@Nested: 用于嵌套測試類。@TestFactory: 用于動態測試,返回動態生成的測試方法。
package AI.Test.testNG;import org.junit.jupiter.api.*;public class Junit5TestCheck {@BeforeAllstatic void beforeAll() throws InterruptedException {System.out.println("Before All");Thread.sleep(3000);}@BeforeEachvoid beforeEach(){System.out.println("BeforeEach");}@Test@DisplayName("Junit5TestCheck test1")void test1(){System.out.println("test1");}@Test@RepeatedTest(2)@DisplayName("Junit5TestCheck test2")void test2(){System.out.println("test2");}@Test@Disabled@DisplayName("Junit5TestCheck test3")void test3(){System.out.println("test3");}@Test@Timeout(3)void test4() throws InterruptedException {Thread.sleep(4);System.out.println("test4");}@AfterEachvoid afterEach(){System.out.println("AfterEach");}@AfterAllstatic void afterAll(){System.out.println("After All");}}
3.?TestFactory使用示例
TestFactory其實就是參數化執行同一條用例
通常情況下,我們會使用 @ParameterizedTest
注解來參數化執行不同的測試用例,每次測試會使用不同的參數進行運行。而 @TestFactory
則是一種更為動態和靈活的方式,它允許你在運行時生成測試用例。
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;import java.util.stream.Stream;import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;public class DynamicTestExample {@TestFactoryStream<DynamicTest> dynamicTestFactory() {return Stream.of(dynamicTest("Test 1", () -> assertEquals(2, add(1, 1))),dynamicTest("Test 2", () -> assertEquals(4, add(2, 2))),dynamicTest("Test 3", () -> assertEquals(6, add(3, 3))));}int add(int a, int b) {return a + b;}
}
4.?ParameterizedTest
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.assertEquals;public class ParameterizedTestExample {@ParameterizedTest@CsvSource({"1, 2, 3", "0, 0, 0", "-1, -2, -3"})void testAddition(int a, int b, int result) {assertEquals(result, add(a, b));}int add(int a, int b) {return a + b;}
}