今天主要介绍的是 IInvokedMethodListener 监听器
一:理清楚思路
1.这个监听器主要是用来干什么的
看看官方 api 的注释是怎么样写的:/ * ** TestNG 调用方法前后调用的侦听器。此侦听器仅用于配置和测试方法。 /

理解:通过上图可以看出,我们要实现这个接口必须重写这两个方法,而且这两个方法分别在调用类方法的前后分别执行,这个接口仅用配置(不能改变调用类的实际功能),和测试方法(即将执行的方法)

2.用途根据官方翻译过来就是优化监听结果的,在控制台输出

二:实战
1.: 通过上图我们可以看到需要重写的两个方法分别传入了两个 “参数”(注:此参数并不是调用方法的参数,这个两个是代理对象,给这个即将要被重写的方法提供使用的 api,一张图就明白了他们的关系

2.: 通过资料去查看两个代理对象的 api(api 如何查看如何使用我就不一一说了 --- 淫家也是小白啦)
3.:代码

重点来了:楼楼只教大家如何运用这个东西,随便举例一个监听的例子,里面还有很多东西都是可以拓展的,希望大家忽视这个结果是否美丑,因为这个不是重点

监听类

/*
 * 不知道写啥,加一点控制台的输出吧
 * */

//继承接口重写方法
public class ListenerTwo implements IInvokedMethodListener {

    // 在调用类测试方法之前运行的方法
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        // 获取调用类测试方法
        ITestNGMethod itestMethod = method.getTestMethod();
        // 取到方法名
        String testMethodName = itestMethod.getMethodName();
        // 取到简单类名**也可以取复杂的代包名的那种getname
        String testClassName = itestMethod.getRealClass().getSimpleName();
              //判断是否是测试方法,这里返回的是带@Test注释的话就是true 反之false
        if (method.isTestMethod()) {
            // =itestMethod.getInstance();
            System.out.println("\n"+"[开始case:]" +"方法名:"+ testMethodName + "    (所属类:" + testClassName + ")");
        } else{
            System.out.println("[非@Test注释方法:]"+testMethodName + "    (所属类:" + testClassName + ")");
        }
    }

    // 在调用类测试方法之后运行的方法
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
                           //根据代理对象ItestResuit可以获取到调用类方法运行的状态返回是int类型,因为如下:
                           //下面代理接口给出来的值匹配就行了
                          /**
                            // Test status
                                  int CREATED = -1;
                                   int SUCCESS = 1;
                                  int FAILURE = 2;
                                  int SKIP = 3;
                                  int SUCCESS_PERCENTAGE_FAILURE = 4;
                                  int STARTED= 16;
                        */        
            int status = testResult.getStatus();
            String statuText;
            switch (status) {
            case -1:
                statuText = "CREATED";
                break;
            case 1:
                statuText = "SUCCESS";
                break;
            case 2:
                statuText = "CREATED";
                break;
            case 3:
                statuText = "SKIP";
                break;
            case 4:
                statuText = "SUCCESS_PERCENTAGE_FAILURE";
                break;
            case 16:
                statuText = "STARTED";
                break;
            default:
                statuText = "Unknow";
            }
            System.out.println("[结果:]" + statuText + "\n");

        }
    }
}

测试类

@Listeners({ListenerTwo.class})
public class ListenerOne {

    @BeforeTest
    public void set() throws Exception {
        System.out.println("BeforeTest");
    }

    @Test
    public void test() throws Exception {
        System.out.println("@Test");
    }

    @AfterTest
    public void down() throws Exception {
        System.out.println("@AfterTest");
    }

}

输出结果:

最后再给大家官网写非常好可直接 copy 的监听类(注这个监听类 IInvokedMethodListener 是跟另一个监听类 IMethodInterceptor 结合使用的,不然控制台的输出会乱掉,如果你有心,请关注下一篇文章根据 groups 来运行 case 的监听类:IMethodInterceptor)

package listeners;

import java.util.Calendar;

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.IInvokedMethodListener2;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;

public class ProgressTracker implements IInvokedMethodListener {

    private long startTime = 0;
    private int totalExecuted = 0;
    public static int totalRun = 0;

    @Override
    public void afterInvocation(IInvokedMethod invokedMethod,
            ITestResult testResult) {
        if (invokedMethod.isTestMethod()) {
            ITestNGMethod m = invokedMethod.getTestMethod();
            String methodName = m.getConstructorOrMethod().getName();
            String className = m.getTestClass().getRealClass().getSimpleName();

            int status = testResult.getStatus();
            String statusText = "Unknown";
            switch (status) {
            case ITestResult.FAILURE:
                statusText = "Failed";
                break;
            case ITestResult.SUCCESS:
                statusText = "Passed";
                break;
            case ITestResult.SKIP:
                statusText = "Skipped";
                break;
            }

            long elapsedTime = (Calendar.getInstance().getTimeInMillis() - startTime) / 1000;
            int remainingTestCount = totalRun - totalExecuted;
            long remainingTime = (elapsedTime / totalExecuted)
                    * remainingTestCount;
            System.out.println("[Progress]"
                    + formPercentageStr(totalExecuted, totalRun) + " ("
                    + totalExecuted + "/" + totalRun + ") " + ", Elapsed:"
                    + formTimeStr(elapsedTime) + ", Estimated Time Remaining:"
                    + formTimeStr(remainingTime));

            System.out.println("[End] " + methodName + "(" + className + "): "
                    + statusText + "\n");

        }
    }

    @Override
    public void beforeInvocation(IInvokedMethod invokedMethod, ITestResult arg1) {
        if (invokedMethod.isTestMethod()) {
            ITestNGMethod m = invokedMethod.getTestMethod();
            String methodName = m.getConstructorOrMethod().getName();
            String className = m.getTestClass().getRealClass().getSimpleName();
            System.out
                    .println("[Begin] " + methodName + "(" + className + ") ");
            if (startTime == 0) {
                startTime = Calendar.getInstance().getTimeInMillis();
            }
            totalExecuted += 1;
        }
    }

    private String formPercentageStr(long executedTestCount, long totalTestCount) {
        return Math.round((double) executedTestCount * 100
                / (double) totalTestCount)
                + "%";
    }

    private String formTimeStr(long valueInSeconds) {
        long hours = valueInSeconds / 3600;
        valueInSeconds = valueInSeconds % 3600;

        long minutes = valueInSeconds / 60;
        valueInSeconds = valueInSeconds % 60;

        return toTwoDigitsStr(hours) + ":" + toTwoDigitsStr(minutes) + ":"
                + toTwoDigitsStr(valueInSeconds);
    }

    private String toTwoDigitsStr(long value) {
        if (value < 10) {
            return "0" + value;
        } else {
            return String.valueOf(value);
        }
    }
}


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