Apply #39;@Rule#39; after each #39;@Test#39; and before each #39;@After#39; in JUnit(在 JUnit 中的每个“@Test之后和每个“@After之前应用“@Rule)
问题描述
我有一个测试套件,我在 @After 中退出系统并在 @AfterClass 中关闭浏览器.我正在尝试使用 @Rule 为每种测试方法使用 Selenium 获取失败的测试屏幕截图.我手动检查了 @Rule 仅在每个 @Before 之前运行,但我想在 @Test 之后和 @After 之前设置它代码>.我找不到简单的解决方案.任何帮助将不胜感激.
I have a test suite where I am logging out of the system in @After and closing the browser in @AfterClass. I am trying to use @Rule to take failed test screenshot using Selenium for every test method. I checked manually that @Rule only runs before every @Before but I want to set it up after @Test and before @After. I couldn't find out simple solution. Any help will be appreciated. 
public class MorgatgeCalculatorTest  {
@Before
public void before(){
    System.out.println("I am before");
}
@BeforeClass
public static void beforeclass(){
    System.out.println("I am beforeclass");
}
@Test
    public void test(){
        System.out.println("I am Test");
    }
@Test
public void test2(){
    System.out.println("I am Test2");
}
@After
    public void after(){
        System.out.println("I am after");
    }
@AfterClass
        public static  void afterclass(){
            System.out.println("I am afterclass");
}
@Rule
ExpensiveExternalResource ExpensiveExternalResource = new ExpensiveExternalResource();
static class ExpensiveExternalResource implements MethodRule  {
    public ExpensiveExternalResource(){
        System.out.println("I am rule");
    }
    @Override
    public Statement apply(Statement arg0, FrameworkMethod arg1, Object arg2) {
        // TODO Auto-generated method stub
        return null;
    }    
}               
我得到的输出是
I am beforeclass
I am rule
I am before
I am Test
I am after
I am rule
I am before
I am Test2
I am after
I am afterclass
推荐答案
由于规则的设置方式,您不能在@before 之后或@after 之前设置规则.您可以将规则想象成您放在测试方法上的 shell.第一个shell 是@before/@after.此后应用@rules.
Because of the way that rules are set up, you can't have a rule that comes after @before or before @after. You can think of rules like shells that you put on the test method. The first shell to go on is @before/@after. Thereafter the @rules are applied.
做你想做的事的一个快速方法是完全避免@After.可以创建一个规则,以便在方法失败时截取屏幕截图,然后在代码之后执行您的.它不像@After 那样漂亮,但它确实有效.(我也实现了 TestRule 因为 MethodRule 已被贬值).
A quick way to do what you want to do is to avoid @After altogether. A rule can be created so that it will take a screenshot if a method fails and then execute yours after the code. It isn't quite as pretty as @After, but it works. (also I implemented TestRule because MethodRule has been depreciated).
public class MortgageCalculatorTest  {
    @Before
    public void before(){
        System.out.println("I am before");
    }
    @BeforeClass
    public static void beforeclass(){
        System.out.println("I am beforeclass");
    }
    @Test
    public void test(){
        System.out.println("I am a Test");
    }
    @Test
    public void test2(){
        System.out.println("I am a Failed Test");
        fail();
    }
    @AfterClass
            public static  void afterclass(){
                System.out.println("I am afterclass");
    }
    @Rule
    public ExpensiveExternalResource ExpensiveExternalResource = new ExpensiveExternalResource();
    public static class ExpensiveExternalResource implements TestRule  {
      //  public ExpensiveExternalResource(){}
        public class ExpansiveExternalResourceStatement extends Statement{
            private Statement baseStatement;
            public ExpansiveExternalResourceStatement(Statement b){
                baseStatement = b;
            }
            @Override
            public void evaluate() throws Throwable {
                try{
                    baseStatement.evaluate();
                }catch(Error e){
                    System.out.println("I take a Screenshot");
                    throw e;   
                }finally{
                    after();
                }
            }
            //Put your after code in this method!
            public void after(){
                System.out.println("I am after");
            }
        }
        public Statement apply(Statement base, Description description) {
            return new ExpansiveExternalResourceStatement(base);
        }
    }
}
规则的所有工作都在一个语句中完成.org.junit.runners.model.Statement 是一个代表代码包的类.所以这里的 apply 方法接收到你放置一个 shell 的代码包.Apply 返回执行您提供的代码包的语句,并用 try/catch 语句包围它以捕获方法失败.
All the work of the rule is done in a statement. A org.junit.runners.model.Statement is a class that represents a bundle of code. So here the apply method receives the bundle of code that you are putting a shell around. Apply returns your statement that executes the bundle of code that you gave it and surrounds it with a try/catch statement to catch the method failures.
这个方法的输出是:
I am beforeclass
I am before
I am a Test
I am after
I am before
I am a Failed Test
I take a Screenshot
I am after
I am afterclass
希望这会有所帮助!
这篇关于在 JUnit 中的每个“@Test"之后和每个“@After"之前应用“@Rule"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在 JUnit 中的每个“@Test"之后和每个“@After"之前应用“@Rule"
				
        
 
            
        基础教程推荐
- 验证是否调用了所有 getter 方法 2022-01-01
 - Java 实例变量在两个语句中声明和初始化 2022-01-01
 - 大摇大摆的枚举 2022-01-01
 - 在 Java 中创建日期的正确方法是什么? 2022-01-01
 - 如何在 JFrame 中覆盖 windowsClosing 事件 2022-01-01
 - Java Swing计时器未清除 2022-01-01
 - 从 python 访问 JVM 2022-01-01
 - 多个组件的复杂布局 2022-01-01
 - 不推荐使用 Api 注释的描述 2022-01-01
 - 如何在 Spring @Value 注解中正确指定默认值? 2022-01-01
 
    	
    	
    	
    	
    	
    	
    	
    	
						
						
						
						
						
				
				
				
				