问题
I'd like to be able to log the spock feature names and clause labels when running some automated tests. This would help with debugging test issues when using a headless browser for automation, specifically phantomjs. Reason being, phantomjs does not always behave the same way as when using the chrome WebDriver. It would also be nice to have if this is even possible.
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"
...
}
For example, It would be cool if I could get the above sample spock feature method to log the labels like this.
Login logout test
Go to login page
Submit username and password
logout
Returned to login page
回答1:
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
回答2:
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)
}
}
回答3:
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"]
回答4:
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"
}
}
回答5:
You might want to have a look at the Spock Reports Extension
来源:https://stackoverflow.com/questions/38145712/is-it-possible-to-log-spock-feature-method-names-and-clause-labels