01 TestNG更适合测试人员使用
TestNG适合测试人员的原因:
1,比junit涵盖功能更全面的测试框架
2,Junit更适合隔离性比较强的单元测试
3,TestNG更适合复杂的集成测试
02 TestNG实战在idea中创建module
步骤:
- 拉取git上的目录下来,在idea打开
- 创建一个module,maven的项目文件
03 注解实战@Test标签
使用过程中,@Test在alt+enter安装的时候总是出现下面的问题。其实在安装跳出的弹窗,选择安装对应的插件到所在项目的目录下就行了
然后安装就没问题了
04 注解实战BeforeMethod和AfterMethod
BeforeMethod是方法之前运行的,AfterMethod是方法之后运行的。而且这两个在每个方法运行之前之后都会运行一次
05 注解实战BeforeClass和AfterClass
BeforeClass和AfterClass的应用场景:类运行前注册对象,静态方法,变量赋值等
06 注解实战BeforeSuite和AfterSuite
BeforeSuite是在BeforeClass前运行的,
AfterSuite是在AfterClass后运行的
应用场景:suite可以包含多个class,类应该属于某个测试套件之下
03-06实例演示
package com.course.testng;
import org.testng.annotations.*;
public class BasicAnnotation {
//最基本的注解,用来把方法标记为测试的一部分
@Test
public void testCase1(){
System.out.println("testCase-1这是Testcase1的测试");
}
@Test
public void testCase2(){
System.out.println("testCase-2这是Testcase1的测试");
}
@BeforeMethod
public void beforeMethod(){
System.out.println("beforeMethod-这是在测试方法之前运行的");
}
@AfterMethod
public void afterMethod(){
System.out.println("afterMethod-这是在测试方法之后运行的");
}
@BeforeClass
public void beforeClass(){
System.out.println("beforeClass-这是在类运行之前运行的");
}
@AfterClass
public void afterClass(){
System.out.println("afterClass-这是在类运行之后运行的");
}
@BeforeSuite
public void beforeSuite(){
System.out.println("BeforeSuite-测试套件");
}
@AfterSuite
public void afterSuite(){
System.out.println("afterSuite-测试套件");
}
}
执行结果
BeforeSuite-测试套件
beforeClass-这是在类运行之前运行的
beforeMethod-这是在测试方法之前运行的
testCase-1这是Testcase1的测试
afterMethod-这是在测试方法之后运行的
beforeMethod-这是在测试方法之前运行的
testCase-2这是Testcase1的测试
afterMethod-这是在测试方法之后运行的
afterClass-这是在类运行之后运行的
afterSuite-测试套件
===============================================
Default Suite
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
===============================================
Process finished with exit code 0
07 套件测试
suite.xml
<?xml version="1.0" encoding="UTF-8" ?>
<suite name="test">
<test name="login">
<classes>
<class name="com.course.testng.suite.SuiteConfig"></class>
<class name="com.course.testng.suite.LoginTest"></class>
</classes>
</test>
<test name="pay">
<classes>
<class name="com.course.testng.suite.SuiteConfig"></class>
<class name="com.course.testng.suite.PayTest"></class>
</classes>
</test>
</suite>
SuiteConfig.java (共有的套件文件)
package com.course.testng.suite;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
//写测试套件之前要执行方法(共有的)
public class SuiteConfig {
@BeforeSuite
public void beforeSuite(){
System.out.println("beforeSuite运行了");
}
@AfterSuite
public void afterSuite(){
System.out.println("afterSuite运行了");
}
@BeforeTest
public void beforeTest(){
System.out.println("beforeTest开始运行了");
}
@AfterTest
public void afterTest(){
System.out.println("afterTest开始运行了");
}
}
LoginTest.Java (逻辑控制的类-写测试主要的@Test标签下包含的方法)
package com.course.testng.suite;
import org.testng.annotations.Test;
//逻辑控制的类-写测试主要的@Test标签下包含的方法
public class LoginTest {
@Test
public void loginSuccess(){
System.out.println("淘宝登录成功");
}
}
PayTest.java
package com.course.testng.suite;
import org.testng.annotations.Test;
public class PayTest {
@Test
public void paySuccess(){
System.out.println("支付宝支付成功");
}
}
运行效果
beforeSuite运行了
beforeTest开始运行了
淘宝登录成功
afterTest开始运行了
beforeTest开始运行了
支付宝支付成功
afterTest开始运行了
afterSuite运行了
===============================================
test
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
===============================================
08 忽略测试
enabled = false 不被执行
@Test(enabled = false)
package com.course.testng;
import org.testng.annotations.Test;
public class IgnoreTest {
@Test
public void ignore1(){
System.out.println("ignore1被执行了!!");
}
//enabled = false 不被执行
@Test(enabled = false)
public void ignore2(){
System.out.println("ignore2被执行了!!");
}
}
09 组测试中的方法分组测试
貌似testNG 7.0版本后组就有问题,要换版本,到时候在重新看看。
https://coding.imooc.com/learn/questiondetail/8QVD563JGKZXN4Ez.html (已经解决)
package com.course.testng.groups;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
public class GroupsOnMethod {
@Test(groups = "server")
public void test1(){
System.out.println("这是服务端组测试方法11111");
}
@Test(groups = "server")
public void test2(){
System.out.println("这是服务端组测试方法22222");
}
@Test(groups = "client")
public void test3(){
System.out.println("这是客户端组测试方法33333");
}
@Test(groups = "client")
public void test4(){
System.out.println("这是客户端组测试方法44444");
}
@BeforeGroups("server")
public void beforeGroupsOnServer(){
System.out.println("这是服务端组运行之前要运行的方法...");
}
@AfterGroups("server")
public void afterGroupsOnServer(){
System.out.println("这是服务端组运行之后要运行的方法!!!");
}
@BeforeGroups("client")
public void beforeGroupsOnClient(){
System.out.println("这是客户端组运行之前要运行的方法...");
}
@AfterGroups("client")
public void afterGroupsOnClient(){
System.out.println("这是客户端组运行之后要运行的方法!!!");
}
}
目前我的testNG是7.1版本
所以运行的结果是:【后面回来再重新检查下,改下版本运行看看了】
这是服务端组测试方法11111
这是服务端组测试方法22222
这是客户端组测试方法33333
这是客户端组测试方法44444
===============================================
Default Suite
Total tests run: 4, Passes: 4, Failures: 0, Skips: 0
===============================================
原先自动安装了依赖包。
只要将maven安装依赖包的仓库将…\apache-maven-3.6.3\repository\org\testng 目录删除,然后pom.xml上输入要安装的版本。
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.10</version>
</dependency>
</dependencies>
之后再clean一下
10 组测试中的类分组测试
目录
GroupsOnClass1.java
package com.course.testng.groups;
import org.testng.annotations.Test;
@Test(groups = "stu")
public class GroupsOnClass1 {
public void stu1(){
System.out.println("这个是GroupsOnClass1的stu1111正在运行.....");
}
public void stu2(){
System.out.println("这个是GroupsOnClass1的stu2222正在运行.....");
}
}
GtoupsOnClass2.java
package com.course.testng.groups;
import org.testng.annotations.Test;
@Test(groups = "stu")
public class GtoupsOnClass2 {
public void stu1(){
System.out.println("这个是GroupsOnClass222的stu1111正在运行~~~~~");
}
public void stu2(){
System.out.println("这个是GroupsOnClass22222的stu2222正在运行~~~~~");
}
}
GtoupsOnClass3.java
package com.course.testng.groups;
import org.testng.annotations.Test;
@Test(groups = "teacher")
public class GtoupsOnClass3 {
public void teacher1(){
System.out.println("这个是GroupsOnClass333的teacher1正在运行!!!!!");
}
public void teacher2(){
System.out.println("这个是GroupsOnClass222的teacher2正在运行!!!!!");
}
}
groupsOnClass.xml
<?xml version="1.0" encoding="UTF-8" ?>
<suite name="suitename">
<!-- 运行全部的 -->
<test name="runAll">
<classes>
<class name="com.course.testng.groups.GroupsOnClass1"/>
<class name="com.course.testng.groups.GtoupsOnClass2"/>
<class name="com.course.testng.groups.GtoupsOnClass3"/>
</classes>
</test>
<!-- 只是运行学生的-->
<test name="runStu">
<groups>
<run>
<include name="stu"/>
</run>
</groups>
<classes>
<class name="com.course.testng.groups.GroupsOnClass1"/>
<class name="com.course.testng.groups.GtoupsOnClass2"/>
<class name="com.course.testng.groups.GtoupsOnClass3"/>
</classes>
</test>
</suite>
11 异常测试
什么时候会用到异常测试?
在我们期望结果为一个异常的时候。比如:我们传入了某些不合法的参数,程序抛出了异常
也就是我们的预期结果就是这个异常
package com.course.testng;
import org.testng.annotations.Test;
/*
异常测试
*/
public class ExpectExction {
//这是一个失败的异常测试
@Test(expectedExceptions = RuntimeException.class)
public void runTimeExceptionFailed() {
System.out.println("这是一个失败的异常测试");
}
//这是一个成功的异常测试
@Test(expectedExceptions = RuntimeException.class)
public void runTimeExceptionSuccess() {
System.out.println(" 这是一个成功的异常测试 ");
throw new RuntimeException();
}
}
12 依赖测试
依赖测试出现的场景:
例如:test2方法依赖test1方法 应用标签:@Test(dependsOnMethods={“test1”})
如果test1失败了,则test2方法则被忽略
package com.course.testng.groups;
import org.testng.annotations.Test;
public class DependTest {
@Test
public void test1(){
System.out.println("test 1 runnnnn");
}
//test1成功,则执行test2就都执行
@Test(dependsOnMethods = {"test1"})
public void test2(){
System.out.println("test 2 runnnnn");
}
@Test
public void test3(){
System.out.println("test 3 runnnnn");
throw new RuntimeException();
}
//test3执行失败,则执行test4不执行,被忽略掉
//场景,例如要先登录才能进行下一步操作的时候,可以用到这种场景
@Test(dependsOnMethods = {"test3"})
public void test4(){
System.out.println("test 4 runnnnn");
}
}
13 参数化测试-xml文件参数化
Java文件—-ParameterTest.java
package com.course.testng.parameter;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class ParameterTest {
@Test
@Parameters({"name","age"})
public void paramTest1(String name,int age){
System.out.println("name="+name+",age="+age);
}
}
xml文件—-Paramter.xml
<?xml version="1.0" encoding="UTF-8" ?>
<suite name="parameter">
<test name="param">
<classes>
<parameter name="name" value="江zhuoh"/>
<parameter name="age" value="26"/>
<class name="com.course.testng.parameter.ParameterTest"/>
</classes>
</test>
</suite>
14 参数化测试-DataProvider参数化
第一种:
DataProviderTest.java
package com.course.testng.parameter;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class DataProviderTest {
// data和下面的name对应的值一样
@Test(dataProvider = "data")
public void testProvider(String name,int age){
System.out.println("name="+name+",age="+age);
}
// data和上面的dataProvider对应的值一样
@DataProvider(name="data")
public Object[][] providerData(){
Object[][] o=new Object[][]{
{"张三",10},
{"汪三",20},
{"李三",30}
};
return o;
}
}
name=张三,age=10
name=汪三,age=20
name=李三,age=30
===============================================
Default Suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================
第二种:通过方法名进行参数传递
package com.course.testng.parameter;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import java.lang.reflect.Method;
public class DataProviderTest {
// data和下面的name对应的值一样
@Test(dataProvider = "data")
public void testProvider(String name, int age) {
System.out.println("name=" + name + ",age=" + age);
}
// data和上面的dataProvider对应的值一样
@DataProvider(name = "data")
public Object[][] providerData() {
Object[][] o = new Object[][]{
{"张三", 10},
{"汪三", 20},
{"李三", 30}
};
return o;
}
// 另一种操作
@Test(dataProvider = "methodData")
public void test1(String name, int age) {
System.out.println("test111的方法:name=" + name + ",age=" + age);
}
@Test(dataProvider = "methodData")
public void test2(String name, int age) {
System.out.println("test222的方法,name=" + name + ",age=" + age);
}
//method写的目的:会自动将方法名,也就是test1和test2传进来
// 使用的包是:import java.lang.reflect.Method;
@DataProvider(name = "methodData")
public Object[][] methodDataTest(Method method) {
Object[][] result = null;
if (method.getName().equals("test1")) {
result = new Object[][]{
{"张四", 10},
{"汪四", 20},
{"李四", 30}
};
} else if (method.getName().equals("test2")) {
result = new Object[][]{
{"王老五", 10},
{"王老七", 20},
};
};
return result;
}
}
15 多线程测试-注解方式实现
如果我们设置多个线程池,就可以有不同的id号啦(但是多线程的执行顺序我们无法控制)
package com.course.testng.multiThread;
import org.testng.annotations.Test;
//通过注解来实现
public class multiThreadOnAnnotion {
// 如果我们设置多个线程池,就可以有不同的id号啦(但是多线程的执行顺序我们无法控制)
@Test(invocationCount = 10,threadPoolSize = 3)
public void test(){
System.out.println(1);
// 必须是f printf
System.out.printf("Thread ID : %s%n",Thread.currentThread().getId());
}
}
# 运行结果
1
1
Thread ID : 11
1
Thread ID : 12
Thread ID : 13
1
Thread ID : 11
1
Thread ID : 13
1
Thread ID : 12
1
Thread ID : 12
1
Thread ID : 11
1
Thread ID : 12
1
Thread ID : 13
===============================================
Default Suite
Total tests run: 10, Failures: 0, Skips: 0
===============================================
16 多线程测试-xml文件实现
classs级别可以看看老师的代码实现
parallel ="methods" 表示级别是方法级别-
thread-count="2" 代表了最大并发线程数
methods级别:所有用例都能在不同的线程下去执行(一般配置这个)
tests级别:
1)相同的test tag( 就是底下的demo2啦 <test name="demo2" >只能在相同的线程池去执行
2)不同的test tag可以在不同的线程池去执行(底下的一个叫thread,一个叫demo2,正好符合不同的test tage)
classs级别:
1)相同的class tag下的用例只能在同一个线程下执行
2)不同的class tag下的用例可以在多个线程下执行
thread-count:最大并发线程数
java
package com.course.testng.multiThread;
import org.testng.annotations.Test;
public class multiThreadOnXml {
@Test
public void test1(){
System.out.printf("Thread ID: %s%n",Thread.currentThread().getId());
}
@Test
public void test2(){
System.out.printf("Thread ID: %s%n",Thread.currentThread().getId());
}
@Test
public void test3(){
System.out.printf("Thread ID: %s%n",Thread.currentThread().getId());
}
}
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--
parallel ="methods" 表示级别是方法级别-
thread-count="2" 代表了最大并发线程数
methods级别:所有用例都能在不同的线程下去执行(一般配置这个)
tests级别:
1)相同的test tag( 就是底下的demo2啦 <test name="demo2" >只能在相同的线程池去执行
2)不同的test tag可以在不同的线程池去执行(底下的一个叫thread,一个叫demo2,正好符合不同的test tage)
classs级别:
1)相同的class tag下的用例只能在同一个线程下执行
2)不同的class tag下的用例可以在多个线程下执行
thread-count:最大并发线程数
-->
<suite name ="thread" parallel ="classs" thread-count="3">
<test name="demo1">
<classes>
<class name="com.course.testng.multiThread.multiThreadOnXml"/>
</classes>
</test>
</suite>
17 超时测试
package com.course.testng;
import org.testng.annotations.Test;
public class TimeOutTest {
@Test(timeOut = 3000) //单位 毫秒
public void testSuccess() throws InterruptedException{
Thread.sleep(2000);
}
@Test(timeOut = 1000) //单位 毫秒
public void testFailed() throws InterruptedException{
Thread.sleep(2000);
}
}