通过 IMethodInterceptor 监听器实现运行指定的组:
介绍一下 IMethodInterceptor:
先看一下这个接口源码返回什么类型:
/**
* This class is used to alter the list of test methods that TestNG is about to run.
*
* <p>
*
* An instance of this class will be invoked right before TestNG starts invoking test methods.
* Only methods that have no dependents and that don't depend on any other test methods will
* be passed in parameter. Implementers of this interface need to return a list of {@link IMethodInstance}
* that represents the list of test methods they want run. TestNG will run these methods in the
* same order found in the returned value.
*
* <p>
*
* Typically, the returned list will be just the methods passed in parameter but sorted
* differently, but it can actually have any size (it can be empty, it can be of the
* same size as the original list or it can contain more methods).
*
* <p>
*
* The {@link ITestContext} is passed in the <tt>intercept</tt> method so that implementers can set user values
* (using {@link ITestContext#setAttribute(String, Object)}), which they can then look up
* later while generating the reports.
*
* @author cbeust
*/
翻译源码(简单理一下):
重点:
1.将在 TestNG 开始调用测试方法之前调用该类的实例(不同于上一个监听器,这个监听器是在调用测试方法之前开始调用这个监听器(上一个监听器是在调用测试方法的时候调用))
2.在参数中传递。这个接口的实现者需要返回{@link IMethodInstance}列表,表示要运行的测试方法列表(测列表返回的是所有实质性的方法,非测试方法也返回)
3.通常,返回的列表将只是在参数中传递的方法
用法:此处只写了根据 groupName 来运行,可扩展其他的
实战:
理清楚逻辑:
1.想要使用该监听必须创建 class 实例化 IMethodInstance 接口(IMethodInstance 的父类是 ITestNGListener 接口)
2.重写该接口下面的方法
3.如图关系依赖:
4.再说一下上面的重点,这个方法返回的是一个 list 集合,调用类只执行 list 有的方法,如果没有即使用调用类方法用@Test方法标记也不执行
代码块:主要为了实现功能减去了很多
监听类
/*
* 根据组名来运行
* ITestContext代理对象没有用到,这个接口可以取执行结果的信息,跟上一个监听器可以结合使用从而生成更完美的报告
* 我这里写出来的只是个人想写的
* */
//继承接口重写方法
public class ListenerTwo implements IMethodInterceptor {
List<IMethodInstance> returnMethod = new ArrayList<IMethodInstance>();
@Override
public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
// TODO Auto-generated method stub\
// IMethodInstance 这个接口所返回的是所有测试方法或实例(所有方法都在里面)
// 将IMethodInstance对象的list 创建为迭代器
Iterator<IMethodInstance> tie = methods.iterator();
// 遍历
while (tie.hasNext()) {
IMethodInstance methon = tie.next();
// 带注释的TestNG方法
ITestNGMethod x = methon.getMethod();
// 判断这个方法时@注释描述的
if (x.isTest()) {
// 取出所有的groups遍历
for (String groupName : x.getGroups())
// 判断组名
if (groupName.contentEquals("haha")) {
// 如果正确添加到执行list(之所以说是执行list,因为这个list要被return,list里面有的元素才会被执行)
returnMethod.add(methon);
}
}
}
// return
return returnMethod;
}
}
执行类
@Listeners({ListenerTwo.class})
public class ListenerOne {
@BeforeTest
public void set() throws Exception {
System.out.println("@BeforeTest");
}
@Test(groups = "haha")
public void test() throws Exception {
System.out.println("@Test");
}
@AfterTest
public void down() throws Exception {
System.out.println("@AfterTest");
}
@Test(groups = "lalal")
public void gugu(){
System.out.println("111");
}
@Test(groups ={ "haha","lala"})
public void lili(){
System.out.println("@2222");
}
@Test
public void bilibilibili(){
System.out.println("@bilibilibili");
}
@Test(groups = "haha")
public void acfun(){
int a = 1/0;
System.out.println(a);
}
}
执行结果
---------------------------------------------------------------------------分割线-------------------------------------------------------------------------------------------
贴上官源码(根据本地电脑系统来运行方法:解释过来就是把系统名称赋值给组名,然后利用监听来控制组的运行)
注:此代码是需要配合上一篇监听文章一起使用
代码块:
1.事先定义好组名称
package listeners;
public class OSNames {
public static final String OS_WINDOWS = "OS_Windows";
public static final String OS_LINUX = "OS_Linux";
public static final String OS_UNKNOWN = "OS_Unknown";
}
2.重写 IMethodInterceptor 监听类
package listeners;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import org.testng.IMethodInstance;
import org.testng.IMethodInterceptor;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.annotations.Test;
public class OSFilter implements IMethodInterceptor {
public static int totalIgnored = 0;
public static int totalRun = 0;
public static int totalConfigured = 0;
private List<IMethodInstance> methodsToTest = null;
public boolean isQualified(ITestNGMethod iTestNGMethod) {
boolean isQualified = false;
Method m = iTestNGMethod.getConstructorOrMethod().getMethod();
Test testAnno = m.getAnnotation(Test.class);
String[] groups = testAnno.groups();
List<String> groupList = Arrays.asList(groups);
String osName = getCurrentOS();
if (groupList.contains(osName)) {
isQualified = true;
}
return isQualified;
}
private String getCurrentOS() {
String osname = System.getProperties().getProperty("os.name");
if (osname.startsWith("Windows")) {
return OSNames.OS_WINDOWS;
} else if (osname.equalsIgnoreCase("Linux")) {
return OSNames.OS_LINUX;
} else {
return OSNames.OS_UNKNOWN;
}
}
@Override
public List<IMethodInstance> intercept(List<IMethodInstance> methods,
ITestContext iTestContext) {
if (methodsToTest == null) {
SortedMap<String, IMethodInstance> sortedMap = new TreeMap<String, IMethodInstance>();
List<String> ignoredMethods = new ArrayList<String>();
for (Iterator<IMethodInstance> it = methods.iterator(); it
.hasNext();) {
IMethodInstance iMethodInstance = it.next();
ITestNGMethod m = iMethodInstance.getMethod();
String methodName = m.getConstructorOrMethod().getName();
String className = m.getTestClass().getRealClass().getName();
totalConfigured += 1;
if (isQualified(iMethodInstance.getMethod())) {
String sortKey = className + "_" + methodName;
sortedMap.put(sortKey, iMethodInstance);
totalRun += 1;
} else {
ignoredMethods.add(methodName + "(" + className + ")");
totalIgnored += 1;
}
}
List<IMethodInstance> rtMethods = new ArrayList<IMethodInstance>(
sortedMap.values());
ProgressTracker.totalRun = totalRun;
System.out.println("Ignored Test Methods: " + ignoredMethods);
methodsToTest = rtMethods;
}
return methodsToTest;
}
}
3.执行类
package tests;
import listeners.OSFilter;
import listeners.OSNames;
import listeners.ProgressTracker;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners({ OSFilter.class, ProgressTracker.class })
public class SampleTest {
@Test(groups = { OSNames.OS_LINUX })
public void test1() {
sleep(5000);
System.out.println(">>>test1");
}
@Test(groups = { OSNames.OS_LINUX, OSNames.OS_WINDOWS })
public void test2() {
sleep(3000);
System.out.println(">>>test2");
}
@Test(groups = { OSNames.OS_LINUX, OSNames.OS_WINDOWS })
public void test3() {
sleep(2000);
System.out.println(">>>test3");
}
@Test(groups = { OSNames.OS_WINDOWS })
public void test4() {
sleep(5000);
System.out.println(">>>test4");
}
@Test(groups = { OSNames.OS_WINDOWS })
public void test5() {
sleep(5000);
System.out.println(">>>test5");
}
private void sleep(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这样配合使用完美的监听就出来了
结语:小白踩坑记