【问题标题】:Geb : execute common code just before cleanup of every test caseGeb:在清理每个测试用例之前执行通用代码
【发布时间】:2021-09-03 07:05:36
【问题描述】:

对于每个失败的测试用例,我们都有一个通用的屏幕截图捕获功能,使用 AbstractRunListner 实现,如下所示:

public class FailureListener extends AbstarctRunLister {
....
   @Overrides
   public void error(ErrorInfo errorInfo){
       ...
       //Logic to capture screenshots
   }
}

当测试用例没有清理块或清理方法时,这非常有效。

但是我们使用了清理块,它会在失败的情况下刷新或关闭任何屏幕,以使测试中的应用程序为下一次测试执行做好准备。因此,清理块屏幕截图未捕获测试用例失败的正确屏幕,而是在执行清理后捕获屏幕,这将关闭发生故障的屏幕。

def 'do some operation on screen'(){
   given:
       //Go to that screen
   when:
       //perform some operation
   then:
       //assert the action
    cleanup:
       //close any unwanted screen to make the application ready for the next test execution
}

那么我们可以做些什么来解决这个问题?因为我尝试了 AbstractRunListener 的多种方法,但它们都没有帮助,因为这些方法要么在测试用例之前执行,要么在清理之后执行,但这里我们需要一种方法或方式,它可以在清理之前但在块执行之后执行逻辑。

【问题讨论】:

  • 为什么在cleanup 块中关闭屏幕以准备下一次测试?这不是setup 的工作吗?不知道为什么你需要关闭屏幕... ????
  • 您能否解释一下为什么 (a) 您在失败时手动截屏而不是扩展 GebReportingSpec,它会自动执行以及为什么 (b) 您将 cleanup: 块分散到所有功能方法中除了 GebReportingSpec 已经为您做的事情之外,只需在基类中定义一个 cleanup() 方法来做任何事情?
  • 感谢您的重播。我知道 cleanup() 方法,但我们有测试特定配置,一旦测试执行完成,我们想要重置,所以我添加了一个清理块。
  • GebReportingSpec 也在清理块/方法执行之后执行,我们想在清理块/方法执行之前截取实际失败屏幕的屏幕截图。
  • 无法挂钩在 cleanup 块之前执行的某些内容,因此您必须在 cleanup 块中手动截取屏幕截图。

标签: selenium groovy spock geb


【解决方案1】:

如果您使用 IMethodInterceptor 并将其注册为全局扩展 (IGlobalExtension) 中的所有规范中的所有迭代而不是 IRunListener,您可能会实现您所追求的目标。您的拦截器会将对 IMethodInvocation.proceed() 的调用包装在 try/catch 中,并在抛出异常并重新抛出捕获的异常时进行错误报告。在您可能希望查看的所有迭代中注册拦截器

  • SpecInfo.getAllFeatures()
  • FeatureInfo.addIterationInterceptor()

【讨论】:

  • 嗨@erdi,感谢您的回答。我已经尝试过您的解决方案,但也没有用:` public class GlobalSpecExtension extends AbstractGlobalExtension{ public void visitSpec(SpecInfo spec) { spec.getAllFeatures().forEach({ feature -> feature.addIterationInterceptor(new IMethodInterceptor() { void intercept( IMethodInvocation invocation) throws Throwable { try{ invocation.proceed() } catch(Throwable te){ //截图逻辑 throw te; } } }) }); } }
【解决方案2】:

@erdi 的答案是最好的解决方案,但作为一种解决方法,您可以将清理语句包装在一个闭包中,然后在规范级别的清理方法中调用该闭包。例如:

class SampleSpec extends YourBaseSpec {
    
    Closure cleanup

    def cleanup() {
      cleanup?.call()
    }

    def "testing cleanup"() {
      [blocks...]

      cleanup:
      cleanup = { statements like refresh(), etc }  
    }
}

我相信这会产生您想要的结果,报告规范将在执行刷新页面的清理方法之前截取屏幕截图,并导致隐藏/清除任何失败原因

【讨论】:

    猜你喜欢
    • 2017-04-30
    • 1970-01-01
    • 2013-09-08
    • 2013-10-13
    • 2021-11-15
    • 2014-05-02
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多