Is it possible to log spock feature method names and clause labels?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-04 08:30:55

Step1: Create a Your own spock extension Class

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() {

    }
}

Step2: Create a RunListener that can listen to a spock run

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) {
    }
}

Step3: Register your new Spock extension

  • In your classpath or resource path create a below folder structure META-INF/services/org.spockframework.runtime.extension.IGlobalExtension
  • Have this as the content of file com.example.spock.exetension.MySpockExtension

Step4: Run your spock test and you should see output something like this.

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

You can get the name of every feature method by following :

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)
    }
}

PiggyBacking on @Raghu Kirans answer, I had to do a little bit more to get this to run the way that I wanted with Data Driven tests. In the BeforeIteration method of your RunListener I did the following:

@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())));
}

This simply prints out everything prior to each iteration. Also note that getKind().name() on the BlockInfo object does not print out the given, when, then of the spock block in our test but instead prints out SETUP, WHEN, THEN and WHERE instead. getTexts() will print out the combined texts of the block.

Example:

given: "I wake up" and: "I drink a cup of coffee"

Will be displayed as

SETUP : ["I wake up", "I drink a cup of coffee"]

WontonJon

After continuously searching I found this solution for getting the test name. But can't seem to find anything on the 'when' and 'then' labels. This is okay for now.

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"
 }
}

You might want to have a look at the Spock Reports Extension

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!