zoukankan      html  css  js  c++  java
  • Junit4 基于 custom Rule retry

    从testwather看自定义rule:

    原理:实现一个statement,分别在指定位置回调对应的方法(start,success,fail,finish)

    public abstract class TestWatcher implements TestRule {
          public Statement apply(final Statement base, final Description description) {
             return new Statement() {
                 @Override
                public void evaluate() throws Throwable {
                   starting(description);
                    try {
                        base.evaluate();
                        succeeded(description);
                   } catch (AssumptionViolatedException e) {
                       throw e;
                   } catch (Throwable t) {
                       failed(t, description);
                       throw t;
                   } finally {
                       finished(description);
                   }
                }
            };
         }

     返回看statement是怎么生成的

    protected Statement methodBlock(FrameworkMethod method) {  
        Object test;  
        try {  
            test = new ReflectiveCallable() {  
                @Override  
                protected Object runReflectiveCall() throws Throwable {  
                    return createTest();  
                }  
            }.run();  
        } catch (Throwable e) {  
            return new Fail(e);  
        }  
      
        Statement statement = methodInvoker(method, test);  
        statement = possiblyExpectingExceptions(method, test, statement);  
        statement = withPotentialTimeout(method, test, statement);  
        statement = withBefores(method, test, statement);  
        statement = withAfters(method, test, statement);  
        statement = withRules(method, test, statement);  
        return statement;  
    }  

    在JUnit执行每个测试方法之前,methodBlock方法都会被调用,用于把该测试包装成一个Statement。Statement代表一个具体的动作,例如测试方法的执行,Before方法的执行或者Rule的调用,类似于J2EE中的Filter,Statement也使用了责任链模式,将Statement层层包裹,就能形成一个完整的测试,JUnit最后会执行这个Statement。从上面代码可以看到,有以下内容被包装进Statement中:

        1)测试方法的执行;

        2)异常测试,对应于@Test(expected=XXX.class);

        3)超时测试,对应与@Test(timeout=XXX);

        4)Before方法,对应于@Before注解的方法;

        5)After方法,对应于@After注解的方法;

        6)Rule的执行。

    Junit4 基于自定义Rule的失败重试方案

    自定义的也一样,也是实现statement。操作statement,在失败的时候再重跑一遍

    testcase class中添加

    @Rule
        public MethodNameExample methodNameExample = new MethodNameExample();

    具体实现:

    public class MethodNameExample implements TestRule {
        @Override
        public Statement apply(final Statement base, final Description description) {
            return new Statement() {
                @Override
                public void evaluate() throws Throwable {
                    try {
                        base.evaluate();  //这其实就是运行测试方法
                        AutoLog.logs.clear();
                    } catch (Throwable throwable) {
                        throwable.printStackTrace();
                        AutoLog.I("当异常的时候发起第二次运行");
                        base.evaluate();
                    }

    第二种Junit运行下面的RunListener :

    public static void main(String[] args) 
    { 
    JUnitCore runner = new JUnitCore(); 
    //Adding listener here 
    runner.addListener(new ExecutionListener()); 
    runner.run(TestFeatureOne.class); 
    } 
    }

    RunListener 在onfailed的时候再运行一次test

    public class ExecutionListener extends RunListener 
    { 
    /** 
    * Called before any tests have been run. 
    * */ 
    public void testRunStarted(Description description) throws java.lang.Exception 
    { 
    System.out.println("Number of testcases to execute : " + description.testCount()); 
    } 
    
    /** 
    * Called when all tests have finished 
    * */ 
    public void testRunFinished(Result result) throws java.lang.Exception 
    { 
    System.out.println("Number of testcases executed : " + result.getRunCount()); 
    } 
    
    /** 
    * Called when an atomic test is about to be started. 
    * */ 
    public void testStarted(Description description) throws java.lang.Exception 
    { 
    System.out.println("Starting execution of test case : "+ description.getMethodName()); 
    } 
    
    /** 
    * Called when an atomic test has finished, whether the test succeeds or fails. 
    * */ 
    public void testFinished(Description description) throws java.lang.Exception 
    { 
    System.out.println("Finished execution of test case : "+ description.getMethodName()); 
    } 
    
    /** 
    * Called when an atomic test fails. 
    * */ 
    public void testFailure(Failure failure) throws java.lang.Exception 
    { 
    System.out.println(
    "Execution of test case failed : "+ failure.getMessage());
    TestListenert tt=new TestListenert();
    
    
    TestResult ttt=new TestResult();
    
    
    ttt.addListener(tt);
    
    
    num++;
    
    
    test.run(ttt);
    
    } 
    
    /** 
    * Called when a test will not be run, generally because a test method is annotated with Ignore. 
    * */ 
    public void testIgnored(Description description) throws java.lang.Exception 
    { 
    System.out.println("Execution of test case ignored : "+ description.getMethodName()); 
    } 
  • 相关阅读:
    Node.js REPL(交互式解释器)
    Node.js NPM 使用介绍
    Node.js 创建第一个应用
    Node.js 安装配置
    Node.js 教程
    Go语言-通道类型
    golang 线程与通道
    Go 语言 goto 语句
    Go 语言指向指针的指针
    session效率
  • 原文地址:https://www.cnblogs.com/season-xie/p/6337706.html
Copyright © 2011-2022 走看看