testNG的使用
1.testNG的注解与属性
@BeforeSuite:在该套件的所有的测试都运行在注解方法之前,仅运行一次 @AfterSuite:在该套件的所有的测试都运行在注解方法之后,仅运行一次
@BeforeClass:在调用当前类的第一个测试方法之前运行,注解方法仅运行一次 @AfterClass:在调用当前类的第一个测试方法之后运行,注解方法仅运行一次
@BeforeTest:注解方法将在属于<test>标签的类的所有测试方法运行之前运行 @AfterTest:注解方法将在属于<test>标签的类的所有测试方法运行之后运行
@BeforeMethod:注解方法将在每个测试方法之前运行 @AfterMethod:注解方法将在每个测试方法之后运行
@Test:将类和方法标记为测试的一部分
@DataProvider 标记一种方法来提供测试方法的数据,注解方法必须返回一个Object[][],其中每个Object[]可以被分配给测试方法的参数列表。要从该DataProver接收数据的@Test方法,就需要使用与此注解名称相等的dataProvider名称
dataProvider 选定传入参数的构造器
enabled: 默认为true,如果指定为false,则表示不执行该测试方法
groups:指定该测试方法所属的组,可以指定多个组,以逗号隔开
invocationCount:指测试方法需要被调用的次数
priority:测试方法优先级设置,数值越低,优先级越高
下面举例:
package testng; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterSuite; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeSuite; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; public class Annotations { @BeforeSuite public void beforeSuite() { System.out.println("beforeSuite......."); } @BeforeMethod public void beforeMethod() { System.out.println("beforeMethod......."); } @BeforeClass public void beforeClass() { System.out.println("beforeClass......."); } @BeforeTest public void beforeTest() { System.out.println("beforeTest......."); } @Test public void test1() { System.out.println("这是第一个测试......"); Assert.assertEquals(add(1,1), 2); } @Test public void test2() { System.out.println("这是第二个测试......"); } @AfterTest public void afterTest() { System.out.println("afterTest......"); } @AfterClass public void afterClass() { System.out.println("afterClass......"); } @AfterMethod public void afterMethod() { System.out.println("afterMethod......"); } @AfterSuite public void afterSuite() { System.out.println("afterSuite......"); } public int add(int i,int j){ return i+j; } }
结果输出如下:
beforeSuite.......
beforeTest.......
beforeClass.......
beforeMethod.......
这是第一个测试......
afterMethod......
beforeMethod.......
这是第二个测试......
afterMethod......
afterClass......
afterTest......
PASSED: test1
PASSED: test2
===============================================
Default test
Tests run: 2, Failures: 0, Skips: 0
===============================================
afterSuite......
===============================================
Default suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
[TestNG] Time taken by org.testng.reporters.jq.Main@156643d4: 24 ms
[TestNG] Time taken by org.testng.reporters.EmailableReporter2@7d6f77cc: 5 ms
[TestNG] Time taken by org.testng.reporters.XMLReporter@5d22bbb7: 6 ms
[TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@1c4af82c: 23 ms
[TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 1 ms
[TestNG] Time taken by org.testng.reporters.JUnitReportReporter@69222c14: 2 ms
2.套件测试
测试套件是用来串联测试用例脚本的,可以通过灵活配置来执行想要执行的测试用例脚本,通俗的讲,就是将一个或者多个测试用例(测试类)放在一起运行,也称为套件测试
目前文件结构如下:
在testng文件夹下创建第一个类,类名为TestSuiteDemo1,
具体代码如下:
package testng; import org.testng.annotations.Test; import org.testng.annotations.BeforeClass; import org.testng.annotations.AfterClass; public class TestSuiteDemo1 { @Test public void f() { System.out.println("this is TestSuiteDemo1 testcase"); } @BeforeClass public void beforeClass() { System.out.println("this is beforeClass"); } @AfterClass public void afterClass() { System.out.println("this is afterClass"); } }
在testng文件夹下创建第二个类,类名为TestSuiteDemo2具体代码如下:
package testng; import org.testng.annotations.Test; import org.testng.annotations.BeforeClass; import org.testng.annotations.AfterClass; public class TestSuiteDemo2 { @Test public void f() { System.out.println("this is TestSuiteDemo1 testcase"); } @BeforeClass public void beforeClass() { System.out.println("this is beforeClass"); } @AfterClass public void afterClass() { System.out.println("this is afterClass"); } }
然后右键工程>>TestNG>>Convert to TestNG 生成一个testng.xml文件,具体代码如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Suite" verbose="1" parallel="false" thread-count="1"> <test name="Test"> <classes> <!-- 套件测试类示例代码1 --> <class name="testng.TestSuiteDemo1"/> <!-- 套件测试类示例代码2 --> <class name="testng.TestSuiteDemo2"/> </classes> </test> <!-- Test --> </suite> <!-- Suite -->
代码解析:suit为根节点且只能有一个,name属性为必需属性,verbose的意思是在控制台中如何输出,一般值为1,不写也可以,parallel的意思是使用多线程编程,通过thread-count属性可以设置线程数
直接运行这个xml文件,会运行class为testng.TestSuiteDemo1和testng.TestSuiteDemo2中的所有测试方法,运行结果如下:
[TestNG] Running:
F:\auto_ceshi\javaProject\src\testng\testng.xml
this is beforeClass
this is TestSuiteDemo1 testcase
this is afterClass
this is beforeClass
this is TestSuiteDemo1 testcase
this is afterClass
===============================================
Suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
3.忽略测试
有时我们编写的测试用例脚本未开发完全,不具备执行测试的条件,就需要等功能健壮或则脚本开发完成之后再去执行测试,这是就可以使用注解@Test(enabled=false)禁用不想执行的测试用例
创建一个名为TestIgnore的类,具体代码如下:
package testng; import org.testng.annotations.Test; public class TestIgnore { //忽略测试 默认enable=true @Test public void test1() { System.out.println("这条测试用例会被执行"); } @Test(enabled=false) public void test2() { System.out.println("enbaled=true时,这条测试用例会被执行"); } @Test(enabled=true) public void test3() { System.out.println("这条测试用例会被执行"); } }
输出结果如下:
这条测试用例会被执行
这条测试用例会被执行
PASSED: test1
PASSED: test3
4.分组测试
创建一个名为TestGroup的类,具体代码如下:
package testng; import org.testng.annotations.Test; public class TestGroup { //分组测试 @Test(groups="group1") public void test1() { System.out.println("我是第一组读者"); } @Test(groups="group3") public void test2() { System.out.println("我是第三组读者"); } @Test(groups="group3") public void test3() { System.out.println("我是第三组读者"); } @Test(groups="group1") public void test4() { System.out.println("我是第一组读者"); } @Test(groups="group1") public void test5() { System.out.println("我是第一组读者"); } @Test(groups="group1") public void test6() { System.out.println("我是第一组读者"); } }
testng.xml文件中添加如下代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" verbose="1" parallel="false" thread-count="1">
<test name="Test">
<groups>
<run>
<!-- 只包含一组 -->
<include name="group1"></include>
<!-- 除了三组 -->
<exclude name="group3"></exclude>
</run>
</groups>
<classes>
<!-- 分组测试 -->
<class name="testng.TestGroup"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
代码解析:
groups标签是分组,run标签是执行,include标签是包含,exclude标签是不包含
输出结果如下:
我是第一组读者
我是第一组读者
我是第一组读者
我是第一组读者
5.异常测试
异常测试是在单元测试中一个非常重要的环节,即全路径的覆盖测试,用于验证程序的健壮性和可靠性,比如接口测试中传入某些不合法的参数,程序就会抛出异常,在程序中我们期望得到某种类型的异常的时候,就需要用到异常测试,通过@Test(expected=""Expection.class)来指定必须抛出某种类型的异常,如果没有抛出异常,测试就会失败
package testng; import org.testng.annotations.Test; public class TestException { @Test(expectedExceptions=NullPointerException.class) public void f() { throw new NullPointerException(); } }
6.依赖测试
有时需要测试方法按照特定的顺序被调用,这个时候需要使用@Test注解的dependsOnMethod参数来指定所依赖的方法
创建一个测试类,名为TestDependsOnGroups,具体代码如下:
public class TestDependsOnGroups { //依赖测试示例 在test1执行前先执行test2和test3 @Test(dependsOnMethods={"test2","test3"}) public void test1() { System.out.println("test1执行了"); } @Test public void test2() { System.out.println("test2执行了"); } @Test public void test3() { System.out.println("test3执行了"); } }
运行结果如下:
test2执行了
test3执行了
test1执行了
PASSED: test2
PASSED: test3
PASSED: test1
7.参数话测试
TestN中常用的有@Parameters 和DataProvider两种注解
第一种@Parameter
创建一个测试类,名为TestParam,代码如下
package testng; import org.testng.annotations.Parameters; import org.testng.annotations.Test; public class TestParam { @Parameters({"username","password"}) @Test public void f(String username,String password) { System.out.println(username+"t"+password); } }
然后在testng.xml文件中添加下面代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" verbose="1" parallel="false" thread-count="1">
<test name="Test">
<parameter name="username" value="dandan"></parameter>
<parameter name="password" value="12345678"></parameter>
<classes>
<class name="testng.TestParam"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
运行结果如下:
dandant12345678
第二种 @DataProvider
创建一个类,名为TestLogin,具体代码如下:
package testng; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class TestLogin { @Test(dataProvider="testlogin") public void testlogin(String username,String password) { System.out.println("用户名为"+username+" "+"密码为"+password); } @DataProvider(name="testlogin") public Object[][] testlogin(){ return new Object[][]{ {"","12345678"},{"dandan",""},{"dandan","12345678"} }; } }
输出结果为:
用户名为 密码为12345678
用户名为dandan 密码为
用户名为dandan 密码为12345678
PASSED: testlogin("", "12345678")
PASSED: testlogin("dandan", "")
PASSED: testlogin("dandan", "12345678")
8.testNG的断言
TestNg断言分为两种:硬断言和软断言
1)硬断言
Assert类为硬断言,特点是如果脚本运行断言失败,就马上停止运行,后面的代码将不被执行
关于硬断言常用的方法总结:
assertTrue: 判断是否为true
assertFalse:判断是否为false
assertSame:判断引用的地址是否相同
assertNotSame:判断引用的地址是否不同
assertNull:判断是否为空
assertNotNull:判断是否部位空
assertEqualsNoOrder: 判断忽略顺序是否相等
代码如下:
import org.testng.Assert;
import org.testng.annotations.Test;
public class TestAssert {
@Test
public void test1(){
Assert.assertEquals(4, 2*2);
System.out.println("这个会被执行");
Assert.assertEquals(5, 1+9);
System.out.println("这个不会被执行");
}
}
运行结果如下:
这个会被执行
FAILED: test1
java.lang.AssertionError: expected [10] but found [5]
at org.testng.Assert.fail(Assert.java:94)
at org.testng.Assert.failNotEquals(Assert.java:496)
at org.testng.Assert.assertEquals(Assert.java:125)
at org.testng.Assert.assertEquals(Assert.java:372)
at org.testng.Assert.assertEquals(Assert.java:382)
at testng20210715.TestAssert.test1(TestAssert.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:816)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1124)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:774)
at org.testng.TestRunner.run(TestRunner.java:624)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:359)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312)
at org.testng.SuiteRunner.run(SuiteRunner.java:261)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1191)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1116)
at org.testng.TestNG.run(TestNG.java:1024)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:112)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:205)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:176)
===============================================
Default test
Tests run: 1, Failures: 1, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 1, Failures: 1, Skips: 0
===============================================
2)软断言
SoftAssert类为软断言,特点是如果运行断言失败,不会停止运行,会继续执行这个断言后面的语句
使用说明:assertAll() 一定要放在该测试类的最后一个断言后面,软断言的类叫SoftAssert.java,这个类必须要创建实例对象才能调用相关实例方法进行软断言
代码如下:
package testng20210715; import org.testng.annotations.Test; import org.testng.asserts.SoftAssert; public class TestSoftAssert { @Test public void f() { SoftAssert softassert=new SoftAssert(); System.out.println("这句会被执行"); softassert.assertEquals(4, 5); System.out.println("我是观望,这句还会不会被执行"); //这句必须放在最后,后面的语句将不在被执行 softassert.assertAll(); System.out.println("这句不会被执行"); } }
运行结果如下:
这句会被执行
我是观望,这句还会不会被执行
FAILED: f
java.lang.AssertionError: The following asserts failed:
expected [5] but found [4]
at org.testng.asserts.SoftAssert.assertAll(SoftAssert.java:43)
at testng20210715.TestSoftAssert.f(TestSoftAssert.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:816)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1124)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:774)
at org.testng.TestRunner.run(TestRunner.java:624)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:359)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312)
at org.testng.SuiteRunner.run(SuiteRunner.java:261)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1191)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1116)
at org.testng.TestNG.run(TestNG.java:1024)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:112)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:205)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:176)
===============================================
Default test
Tests run: 1, Failures: 1, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 1, Failures: 1, Skips: 0
===============================================