TestNG 是一个功能强大的 Java 测试框架,具有灵活的注解体系、测试方法分组、并行执行、依赖测试、异常测试等功能。它支持创建更高级的自动化测试解决方案。下面将详细介绍 TestNG 的基本语法和注解的用法。
1. TestNG 注解
TestNG 通过注解来定义测试流程,每个注解有不同的用途和执行顺序。以下是常见的 TestNG 注解:
@Test
:标记一个方法为测试方法。@BeforeSuite
:在测试套件中的所有测试方法之前执行。@AfterSuite
:在测试套件中的所有测试方法之后执行。@BeforeTest
:在每个测试之前执行(用于@Test
标注的方法之前)。@AfterTest
:在每个测试之后执行。@BeforeClass
:在当前类的第一个测试方法之前执行。@AfterClass
:在当前类的所有测试方法之后执行。@BeforeMethod
:在每个测试方法执行之前执行。@AfterMethod
:在每个测试方法执行之后执行。
注解的执行顺序
TestNG 注解的执行顺序如下:
@BeforeSuite
@BeforeTest
@BeforeClass
@BeforeMethod
@Test
@AfterMethod
@AfterClass
@AfterTest
@AfterSuite
2. 基本示例
2.1 简单的测试类
javaimport org.testng.annotations.Test;
public class BasicTest {
@Test
public void testMethod() {
System.out.println("Test method is running");
}
}
2.2 使用 @BeforeMethod
和 @AfterMethod
java
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
public class MethodTest {
@BeforeMethod
public void setUp() {
System.out.println("Setup before each test");
}
@Test
public void testMethod1() {
System.out.println("Running test method 1");
}
@Test
public void testMethod2() {
System.out.println("Running test method 2");
}
@AfterMethod
public void tearDown() {
System.out.println("Teardown after each test");
}
}
输出顺序为:
sqlSetup before each test
Running test method 1
Teardown after each test
Setup before each test
Running test method 2
Teardown after each test
3. 高级功能
3.1 依赖测试
你可以使用 dependsOnMethods
来设置方法依赖关系。某些测试方法只在依赖的方法成功时才会执行。
import org.testng.annotations.Test;
public class DependencyTest {
@Test
public void setup() {
System.out.println("Setup method");
}
@Test(dependsOnMethods = {"setup"})
public void dependentTest() {
System.out.println("This test depends on setup");
}
}
3.2 分组测试
可以使用 groups
参数将测试方法进行分组,然后执行特定组的测试。
import org.testng.annotations.Test;
public class GroupTest {
@Test(groups = {"sanity"})
public void sanityTest() {
System.out.println("Sanity test");
}
@Test(groups = {"regression"})
public void regressionTest() {
System.out.println("Regression test");
}
@Test(groups = {"sanity", "regression"})
public void bothTest() {
System.out.println("Sanity and regression test");
}
}
3.3 参数化测试
TestNG 支持通过 XML 或 @DataProvider
传递参数到测试方法中。
通过 XML 参数化
javaimport org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class ParamTest {
@Test
@Parameters({"username", "password"})
public void loginTest(String username, String password) {
System.out.println("Username: " + username);
System.out.println("Password: " + password);
}
}
通过 @DataProvider
参数化
java
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DataProviderTest {
@DataProvider(name = "loginData")
public Object[][] dataProviderMethod() {
return new Object[][] { { "user1", "pass1" }, { "user2", "pass2" } };
}
@Test(dataProvider = "loginData")
public void loginTest(String username, String password) {
System.out.println("Username: " + username);
System.out.println("Password: " + password);
}
}
3.4 忽略测试
使用 @Test(enabled = false)
来忽略某个测试方法。
@Test(enabled = false)
public void ignoredTest() {
// This test will be ignored
}
3.5 超时测试
使用 @Test(timeOut = 1000)
来设置测试方法的最大执行时间(以毫秒为单位)。如果超过该时间,测试将失败。
@Test(timeOut = 1000)
public void timeoutTest() throws InterruptedException {
Thread.sleep(1500); // This will cause the test to fail
}
3.6 异常测试
可以通过 expectedExceptions
来测试某个方法是否抛出指定异常。
@Test(expectedExceptions = ArithmeticException.class)
public void exceptionTest() {
int result = 1 / 0; // This will throw ArithmeticException
}
4. TestNG XML 配置文件
TestNG 的强大之处在于其 XML 配置文件的灵活性,你可以在 testng.xml
文件中定义测试类、分组、并行执行等。
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="TestSuite" parallel="methods" thread-count="2">
<test name="SampleTest">
<classes>
<class name="com.example.BasicTest"/>
<class name="com.example.GroupTest"/>
</classes>
</test>
</suite>
5. 并行执行
通过在 testng.xml
中设置 parallel
属性,你可以并行执行测试方法、类或测试套件。可以指定 methods
、classes
或 tests
。
<suite name="ParallelSuite" parallel="methods" thread-count="3">
<test name="Test1">
<classes>
<class name="com.example.ParallelTest"/>
</classes>
</test>
</suite>
在代码中还可以使用 @Test(threadPoolSize = 3)
来并行执行测试方法。