【问题标题】:Is it possible to log spock feature method names and clause labels?是否可以记录 spock 功能方法名称和子句标签?
【发布时间】:2016-07-01 12:40:25
【问题描述】:

我希望能够在运行一些自动化测试时记录 spock 功能名称和子句标签。这将有助于在使用无头浏览器进行自动化时调试测试问题,特别是 phantomjs。原因是,phantomjs 的行为方式并不总是与使用 chrome WebDriver 时相同。如果这是可能的,那也很好。

def "Login logout test"(){
    given: "Go to login page"
        ...

    when: "Submit username and password"
        ...
    then: "Dashboard page displayed"
        ...

    when: "logout"
        ...
    then: "Returned to login page"
        ...
}

例如,如果我能获得上述示例 spock 特征方法来记录这样的标签,那就太酷了。

Login logout test
Go to login page
Submit username and password
logout
Returned to login page

【问题讨论】:

    标签: spock geb


    【解决方案1】:

    第一步:创建一个你自己的spock扩展类

    package com.example.spock.exetension;
    public class MySpockExtension implements IGlobalExtension {
        @Override
        public void start() {
        }
    
        @Override
        public void visitSpec(SpecInfo spec) {
            spec.addListener(new MyCustomSpockRunListener());
        }
    
        @Override
        public void stop() {
    
        }
    }
    

    第二步:创建一个可以监听 spock 运行的 RunListener

    package com.example.spock.exetension;
    public class MyCustomSpockRunListener extends AbstractRunListener {
    
        private boolean specFailed;
        private boolean featureFailed;
           @Override
        public void beforeSpec(SpecInfo spec) {
            // TODO Auto-generated method stub
            specFailed = false;
        }
        @Override
        public void beforeFeature(FeatureInfo feature) {
            // TODO Auto-generated method stub
            featureFailed = false;
        }
        @Override
        public void beforeIteration(IterationInfo iteration) {
    
        }
        @Override
        public void afterIteration(IterationInfo iteration) {
        }
        @Override
        public void afterFeature(FeatureInfo feature) {
            // TODO Auto-generated method stub
            for ( BlockInfo block : feature.getBlocks() ) {
                System.out.println(block.getKind().name() + " : " + block.getTexts() ); 
            }
        }
        @Override
        public void afterSpec(SpecInfo spec) {
            // TODO Auto-generated method stub
            System.out.println(spec.getName() + " : STATUS : " + specFailed != null ? "failure":"success");
    
        }
        @Override
        public void error(ErrorInfo error) {
            specFailed = true;
            FeatureInfo feature = error.getMethod().getFeature();
            if (feature != null) {
                featureFailed = true;
                System.out.println(error.getMethod().getName() + " : " + error.getException());
            }else {
            }
        }
        @Override
        public void specSkipped(SpecInfo spec) {
        }
        @Override
        public void featureSkipped(FeatureInfo feature) {
        }
    }
    

    第三步:注册你的新Spock扩展

    • 在您的类路径或资源路径中创建以下文件夹结构META-INF/services/org.spockframework.runtime.extension.IGlobalExtension
    • 将此作为文件com.example.spock.exetension.MySpockExtension 的内容

    第 4 步: 运行您的 spock 测试,您应该会看到类似这样的输出。

    given: "Go to login page"
    when: "Submit username and password"
    then: "Dashboard page displayed"
    when: "logout"
    then: "Returned to login page"
    Login logout test : STATUS : success
    

    【讨论】:

    • 哇,谢谢。我需要导入什么才能使用“ETESpockRunListener.class”?
    • 该语句可以删除。仍应按预期工作。我编辑了答案以删除该声明并消除任何混淆
    • 对不起,这对我来说有点高级。我是将这些类添加到 spock jar 中还是可以将它们保留在我的项目中?
    • 您可以将它们保留在您的项目中。将这些与您的测试用例源代码一起创建。
    【解决方案2】:

    您可以通过以下方式获取每个特征方法的名称:

    import spock.lang.Specification
    import org.junit.Rule
    import org.junit.rules.TestName
    import org.slf4j.Logger
    import org.slf4j.LoggerFactory
    
    class MySpec extends Specification{
        private static Logger logger = LoggerFactory.getLogger(ClassName.class)
        @Rule TestName testName = new TestName()
    
        void setup(){
           def featureMethodName = testName.methodName
           logger.info("feature method : " + featureMethodName)
        }
    }
    

    【讨论】:

      【解决方案3】:

      PiggyBacking on @Raghu Kirans 回答,我必须做更多的工作才能让它按照我想要的数据驱动测试方式运行。在 RunListener 的 BeforeIteration 方法中,我执行了以下操作:

      @Override
      public void beforeIteration(IterationInfo iteration) {
          Optional.of(iteration)
                  .map(feature -> iteration.getFeature())
                  .map(FeatureInfo::getBlocks)
                  .ifPresent( blocks -> blocks.forEach(
                          blockInfo -> log.info(blockInfo.getKind().name() + " : " + blockInfo.getTexts())));
      }
      

      这只是在每次迭代之前打印出所有内容。另请注意,BlockInfo 对象上的 getKind().name() 不会打印出我们测试中 spock 块的给定、何时、然后,而是打印出 SETUP、WHEN、THEN 和 WHERE。 getTexts() 将打印出块的组合文本。

      例子:

      给定:“我醒了” 和:“我喝了一杯咖啡”

      将显示为

      SETUP : [“我醒了”,“我喝了一杯咖啡”]

      【讨论】:

        【解决方案4】:

        经过不断的搜索,我找到了这个solution 用于获取测试名称。但似乎在“何时”和“那么”标签上找不到任何东西。暂时没问题。

        import org.junit.Rule
        import org.junit.rules.TestName
        
        class MySpec extends Specification {
         @Rule TestName name = new TestName()
        
         def "some test"() {
            expect: name.methodName == "some test"
         }
        }
        

        【讨论】:

          【解决方案5】:

          您可能想看看Spock Reports Extension

          【讨论】:

          • 这正是我正在寻找的。利用所有定义的方法标签(给定、何时等)提供可读的报告。只需要添加到依赖中,并自动输出报告到'build'目录。
          猜你喜欢
          • 2017-10-01
          • 1970-01-01
          • 2017-01-22
          • 1970-01-01
          • 2011-12-21
          • 2022-08-25
          • 1970-01-01
          • 2012-10-19
          • 1970-01-01
          相关资源
          最近更新 更多