通过 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();
        }
    }
}

这样配合使用完美的监听就出来了
结语:小白踩坑记


↙↙↙阅读原文可查看相关链接,并与作者交流