TestNG(一)
一、TestNG是什么?
TestNG是一个开源的单元测试框架,灵感来源于JUnit和NUnit。
1. 注解 2. 参数化测试 3. 支持依赖测试方法 4. 支持组概念 5. 支持多线程测试 6. 灵活的配置
二、TestNG怎么运行?
1. 通过TestNG配置文件 2. 直接运行有@Test标签的java文件 3. 命令行
三、TestNG的注解
⼀个suite(套件) 由⼀个或多个测试组成。
⼀个test(测试) 由⼀个或多个类组成。
⼀个class(类) 由⼀个或多个⽅法组成。
@BeforeSuite/@AfterSuite:被注释⽅法将在某个测试套件运⾏前/某个测试套件所有测试⽅法运⾏后执⾏ @BeforeTest/@AfterTest:被注释⽅法将在测试运⾏前/某个测试所有测试⽅法运⾏后执⾏ @BeforeClass/@AfterClass:被注释⽅法将在当前类的第⼀个测试⽅法调⽤前/当前类所有测试⽅法运⾏后运⾏ @BeforeMethod/@AfterMethod:被注释⽅法将在每⼀个测试⽅法调⽤前/后运⾏ @BeforeSuite/@AfterSuite/@BeforeTest/@AfterTest可以对不同的测试类⽣效,其他注解只在本类范围内⽣效
执行顺序:
@BeforeSuite->@BeforeTest->@BeforeClass->
{@BeforeMethod->@Test->@AfterMethod}
->@AfterClass->@AfterTest->@AfterSuite
其中{}内的与多少个@Test,就循环执⾏多少次
举个栗子:
//Java文件: public class TestAnnotation1 { @BeforeSuite public void beforeSuite() { System.out.println("===Suite执⾏之前操作===="); } @AfterSuite public void afterSuite() { System.out.println("===Suite执⾏之后操作=="); } @BeforeTest public void beforeTest() { System.out.println("***TestAnnotation1--Test执⾏之前操作"); } @AfterTest public void afterTest() { System.out.println("===TestAnnotation1--Test执⾏之后操作"); } @BeforeClass public void beforeClass() { System.out.println("****TestAnnotation1--Class执⾏之前操作*"); } @AfterClass public void afterClass() { System.out.println("===TestAnnotation1--Class执⾏之后操作=="); } @BeforeMethod public void beforeMethod() { System.out.println("***TestAnnotation1--Method执⾏之前操作"); } @AfterMethod public void afterMethod() { System.out.println("===TestAnnotation1--Method执⾏之后操作="); } @Test public void test(){} } //testng.xml文件 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="TestSuite"> <test name="Test1"> <classes> <class name="com.test.testng.TestAnnotation1"/> </classes> </test> </suite>
四、TestNG的参数化
public class SimpleTest {
@BeforeClass
public void BeforeClass() {
System.out.println("Before Class");
}
@BeforeMethod
public void BeforeMethod() {
System.out.println("Before Method");
}
@Test
public void testAdd() {
Integer sum1 = MathSolution.Add(1, 2);
assertThat("Add 1 + 2 结果错误", sum1, equalTo(3));
}
@Test
public void testAdd2() {
Integer sum2 = MathSolution.Add(null, null);
assertThat("Add null + null 结果错误", sum2, equalTo(null));
}
@Test
public void testAdd3() {
Integer sum3 = MathSolution.Add(Integer.MAX_VALUE,
Integer.MAX_VALUE);
assertThat("Too Big", sum3, equalTo(null));
}
}
这段代码有啥缺点?
被测试数据散落在程序中,维护性差、可读性差、case构造起来繁琐
那我们怎么办呢?当然是参数化了。
TestNG参数化有几种方式:
1.使用@DataProvider
2.xml配置文件
@DataProvider:标记⼀个⽅法⽤于为测试⽅法提供数据。 被注释的⽅法必须返回Object[][](Iterator<Object[]>), 其中每个Object[]可以指派为这个测试⽅法的参数列表。 从DataProvider接收数据,@Test⽅法需要指定dataProvider属性。
//DataProvider栗子 public class DataProviderTest { @BeforeClass public void BeforeClass() { System.out.println("Before Class"); } @BeforeMethod public void BeforeMethod() { System.out.println("Before Method"); } @DataProvider public Object[][] paramData() { return new Object[][] { {"Add 1 + 2", 1, 2, 3}, {"Add null + null", null, null, null}, {"Add Big", Integer.MAX_VALUE, Integer.MAX_VALUE, null} }; } //指定使用哪个DataProvider @Test(dataProvider="paramData") public void testDataProvider(String caseDetail, Integer num1, Integer num2, Integer expect) { Integer sum = MathSolution.Add(num1, num2); assertThat(caseDetail, expect, equalTo(sum)); } }
参数化之后代码是不是看起来更加简洁了?我们也可以用文件做为数据源,DB做为数据源。不妨自己动手实验一番吧~
如果再做一个数据源适配器,是不是就更好了?
xml提供参数,在xml中定义parameter,Java文件中使用@Parameter注解来引用参数。下面来看断代码。
//Java文件,引用参数sql public class ConfDataProviderTest { private String sql; @Parameters({"sql"}) @BeforeClass public void beforeClass(String sql) { this.sql = sql; } @DataProvider public Iterator<Object[]> confData() throws ClassNotFoundException, SQLException { DataProvider_byDB dataProvider_byDB = new DataProvider_byDB("127.0.0.1", "5002", "test_testng", "testng", "testng", sql); return dataProvider_byDB.getDBData(); } @Test(dataProvider = "confData") public void testDBDataProvider(Map<String, String> data) { Integer num1 = (data.get("num1") == null) ? null : Integer.valueOf(data.get("num1")); Integer num2 = (data.get("num2") == null) ? null : Integer.valueOf(data.get("num2")); Integer expect = (data.get("expect") == null) ? null : Integer.valueOf(data.get("expect")); String caseDetail = data.get("case_detail").toString(); Integer sum = MathSolution.Add(num1, num2); assertThat(caseDetail, expect, equalTo(sum)); } } //xml文件,提供参数sql <test name="Test3"> <parameter name="sql" value="select * from dataprovider where project_name='Test_TestNG'"/> <classes> <class name="com.test.testng.Lesson2DataProvider.DataProviderTest"/> <class name="com.test.testng.Lesson2DataProvider.DBDataProviderTest"/> <class name="com.test.testng.Lesson2DataProvider.ExcelDataProviderTest"/> <class name="com.test.testng.Lesson2DataProvider.ConfDataProviderTest"/> </classes> </test>
介绍完@DataProvider注解,不得不提一下另一个跟他很相似的注解@Factory
@Factory是用来创建一个测试类的多个实例,每个实例的属性不同,以执行不同的测试。
@Factory与@DataProvider有啥区别呢?
- DataProvider:为测试用例提供参数,有多少组参数就会执行多少次用例,因此它是一个让测试类实例的某个方法执行多次,但每次执行都使用同一个实例。
- Factory:创建一个测试类的多个实例,每个实例中的所有测试用例都会被执行,因此它是一个测试类被执行多次,每次执行采用的是不同实例。
看个栗子,@Factory:
public class Test1 { private int count; public Test1(int count) { this.count = count; } //两个不同实例 @Test public void test() { System.out.println("Test1-不同实例地址-" + this); for (int i = 0; i < count; i++) { System.out.println("Test1-test-" + i); } } } //Factory public class FactoryTest { @Factory public Object[] factoryTest1() { return new Object[]{new Test1(1), new Test1(2)}; } }
执行结果如下,可以看到是两个不同的实例:
再看一个DataProvider的栗子:
public class Test2 { @DataProvider public Object[][] getData() { return new Object[][]{ {1}, {2} }; } //两个相同实例 @Test(dataProvider = "getData") public void test(int count) { System.out.println("Test2-相同实例地址-" + this); for (int i = 0; i < count; i++) { System.out.println("Test2-test-" + i); } } }
执行结果如下,可以看到是两个相同的地址:
声明 欢迎转载,但请保留文章原始出处:) 博客园:https://www.cnblogs.com/chenxiaomeng/
如出现转载未声明 将追究法律责任~谢谢合作