Java 应用'@规则';每次'@测试';在每个'@在'之后;少年
我有一个测试套件,我在Java 应用'@规则';每次'@测试';在每个'@在'之后;少年,java,selenium,webdriver,junit4,junit-rule,Java,Selenium,Webdriver,Junit4,Junit Rule,我有一个测试套件,我在@After中注销系统,并在@AfterClass中关闭浏览器。我正在尝试使用@Rule为每个测试方法使用Selenium拍摄失败的测试屏幕截图。我手动检查了@Rule只在@Test之前和@after之前运行,但我想在@Test之后和@after之前设置它。我找不到简单的解决办法。任何帮助都将不胜感激 public class MorgatgeCalculatorTest { @Before public void before(){ System.out.pr
@After
中注销系统,并在@AfterClass
中关闭浏览器。我正在尝试使用@Rule
为每个测试方法使用Selenium拍摄失败的测试屏幕截图。我手动检查了@Rule
只在@Test
之前和@after
之前运行,但我想在@Test
之后和@after之前设置它。我找不到简单的解决办法。任何帮助都将不胜感激
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;
}
}
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);
}
}
}
我得到的结果是
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是@before/@after。然后应用@规则
做你想做的事的一个快速方法是完全避免@After。可以创建一个规则,以便在方法失败时截图,然后在代码完成后执行您的规则。它不像@After那么漂亮,但它确实有效。(我还实现了TestRule,因为MethodRule已经贬值)
规则的所有工作都在一个语句中完成。org.junit.runners.model.Statement是一个表示代码包的类。因此,这里apply方法接收您正在放置外壳的代码包。Apply返回语句,该语句执行您提供给它的代码包,并用try/catch语句包围它以捕获方法失败
此方法的输出为:
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
希望这有帮助 我提到我只想在测试失败时拍摄屏幕截图。不是每个测试都适用:DFunny。我只对订单感兴趣,所以实际上你的问题就是我的答案:)@GáborLipták:)我很高兴@GáborLipták实际上显示的顺序是不正确的,因为它只在实例化规则时显示,而不是在应用规则时显示。正确的测试在规则中根本没有构造函数,而是在调用前后调用arg0.evaluate()
日志记录。这将表明该规则在
/@之前
@之后运行,就像JUnit.Troy的JavaDoc中也提到的一样,感谢您的评论。从您的解决方案中得到了提示。我建议在输出中添加@After
方法,这样它就会可见,baseStatement.evaluate()实际上会使@Before
,然后是test method,然后是@After
运行。
public class ScreenshotTestRule implements MethodRule {
public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
statement.evaluate();
} catch (Throwable t) {
captureScreenshot(frameworkMethod.getName());
throw t; // rethrow to allow the failure to be reported to JUnit
} finally {
tearDown();
}
}
public void tearDown() {
//logout to the system;
}
public void captureScreenshot(String fileName) {
try {
new File("target/surefire-reports/screenshot").mkdirs(); // Insure directory is there
FileOutputStream out = new FileOutputStream("target/surefire-reports/screenshot/screenshot-" + fileName + ".png");
out.write(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES));
out.close();
} catch (Exception e) {
// No need to crash the tests if the screenshot fails
}
}
};
}
}