0

我正在尝试运行以下 CucumberWithSerenity TestRunner 类:

import net.serenitybdd.cucumber.CucumberWithSerenity;
import cucumber.api.CucumberOptions;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import org.junit.runner.notification.Failure;

//@RunWith(Cucumber.class)
@RunWith(CucumberWithSerenity.class)
@CucumberOptions(format = {"pretty"}, monochrome=true)
public class TestRunner {

        public static void main(String[] args) throws Exception {
             System.out.println("TestRunner...");
        JUnitCore junit  = new org.junit.runner.JUnitCore() ;

        try {
            throw new Exception();
        } catch(Exception e) {
            // code to handle the exception
          Result result = junit.run(TestRunner.class);
          for (Failure failure : result.getFailures())
        {
                System.out.println(failure.toString());
        }
      }
    }
}

作为 java -jar App.jar ,上面的 main 是使用 gradle 进行 jar 化的。

但是,我收到以下错误:

initializationError(serenity.TestRunner): net/thucydides/core/guice/Injectors

没有使用 CucumberWithSerenity,我不确定应该如何进行初始化。

这个 main() 类背后的想法是制作一个包含所有 Serenity 测试的 jar 文件,并在任何地方运行它们。

这是 build.gradle

import groovy.io.FileType
import groovy.text.Template

apply plugin: 'groovy'
apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'TestRunner'

//jar {
//    manifest {
//        attributes 'Main-Class': 'cucumber.api.cli.Main'
//    }
//}

def cucumberVersion = "1.2.4"


buildscript {
        repositories { maven{ url "http://${nexus}/nexus/content/groups/public/"
                } }

        dependencies { classpath("net.serenity-bdd:serenity-gradle-plugin:1.0.56") }
}

repositories  {

              maven { url "http://${nexus}/nexus/content/groups/public/"
              }
       flatDir {
       dirs 'test/resources/libs'
   }

}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'net.serenity-bdd.aggregator'

configurations {
        //outdated dependency, use hamcrest-core:1.3
        testCompile.exclude group: 'org.hamcrest', module: 'hamcrest-all'
         cucumberRuntime {
        extendsFrom testRuntime
    }
        //cucumber
}

//build.dependsOn cucumber

dependencies {
        testCompile 'org.hamcrest:hamcrest-core:1.3'
        testCompile 'com.jayway.restassured:rest-assured:2.7.0'
        testCompile 'net.serenity-bdd:serenity-rest-assured:1.1.21'

        testCompile 'net.serenity-bdd:serenity-junit:1.1.21'
        testCompile 'net.serenity-bdd:serenity-core:1.1.21'
        testCompile 'net.serenity-bdd:serenity-cucumber:1.1.1'
        testCompile 'org.jbehave:jbehave-core:4.0.4'
        testCompile 'net.serenity-bdd:serenity-jbehave:1.1.0'
        testCompile 'de.codecentric:jbehave-junit-runner:1.1.0'
        testCompile 'junit:junit:4.2'
        testCompile 'cglib:cglib-nodep:3.2.0'

        testCompile 'org.assertj:assertj-core:3.1.0'
        testCompile 'org.slf4j:slf4j-simple:1.7.12'

        compile 'com.jayway.jsonpath:json-path:2.0.0'

        compile 'com.github.groovy-wslite:groovy-wslite:1.1.0'
        compile 'org.springframework:spring-web:3.2.8.RELEASE'

        testCompile 'org.apache.activemq:activemq-all:5.12.0'
        testCompile 'org.mongodb:mongo-java-driver:2.11.4'
        testCompile 'com.fasterxml.jackson.core:jackson-core:2.4.4'
        testCompile 'com.fasterxml.jackson.core:jackson-databind:2.4.4'

        testCompile "info.cukes:cucumber-junit:$cucumberVersion"
        testCompile "info.cukes:cucumber-groovy:$cucumberVersion"
        testCompile 'net.serenity-bdd:serenity-cucumber:1.0.17'

        compile files('src/test/libs/junit-4.2.jar')
        runtime files('src/test/libs/junit-4.2.jar')

        compile files('src/test/libs/hamcrest-core-1.3.jar')
        runtime files('src/test/libs/hamcrest-core-1.3.jar')


        compile files('src/test/libs/cucumber-junit-1.2.4.jar')
        runtime files('src/test/libs/cucumber-junit-1.2.4.jar')


        compile files('src/test/libs/cucumber-java-1.2.4.jar')
        runtime files('src/test/libs/cucumber-java-1.2.4.jar')

        compile files('src/test/libs/cucumber-core-1.2.4.jar')
        runtime files('src/test/libs/cucumber-core-1.2.4.jar')

        //compile files('src/test/libs/serenity-cucumber-1.0.2.jar')
        //runtime files('src/test/libs/serenity-cucumber-1.0.2.jar')

        compile files('src/test/libs/cucumber-jvm-deps-1.0.5.jar')
        runtime files('src/test/libs/cucumber-jvm-deps-1.0.5.jar')

        compile files('src/test/libs/gherkin-2.12.2.jar')
        runtime files('src/test/libs/gherkin-2.12.2.jar')

        compile files('src/test/libs/cucumber-reporting-2.0.0.jar')
        runtime files('src/test/libs/cucumber-reporting-2.0.0.jar')

        compile files('src/test/libs/thucydides-core-0.9.125.jar')
        runtime files('src/test/libs/thucydides-core-0.9.125.jar')
}

task cucumber() {
    dependsOn assemble
    doLast {
        javaexec {
            main = "cucumber.api.cli.Main"
            classpath = configurations.cucumberRuntime
            args = ['--plugin', 'pretty', '--glue', 'src/test/java', 'src/test/resources', 'src/main/java']
            //classpath = configurations.cucumber

        }
    }
}


test{
        def fileMap = new TreeMap<String, File>();
        def redirectionMap = new TreeMap<String, String>();
        def blacklist = new ArrayList<String>();
        blacklist.add("net.thucydides.core.reflection.StackTraceAnalyser");


        onOutput { descriptor, event ->
                def messageBlacklisted = false;
                for(String blacklistedString : blacklist) {
                        if(event.message.contains(blacklistedString)){
                                messageBlacklisted=true;
                        }
                }

                //Gradle Test Executor 1
                def executor = descriptor;
                while(executor.getClassName() != null)
                {
                        executor = executor.getParent();
                }

                def originalKey = executor.getName();
                def key = originalKey;
                def redirectionMessages = [/TEST STARTED: (.*)$/];
                for(def regex : redirectionMessages)
                {
                        def result = (event.message =~ regex);
                        if(result.size()>=1)
                        {
                                def redirectedLocation = result[0][1];
                                redirectionMap.put(key, redirectedLocation);
                                logger.lifecycle("Redirecting "+key+"->"+redirectedLocation);
                        }
                }

                def depth = 0;
                while(redirectionMap.containsKey(key) && depth < 10)
                {
                        depth+1;
                        key = redirectionMap.get(key);
                }

                //key is still gradle test executor, may as well use something more useful
                if(key.equals(originalKey))
                {
                        key = descriptor.getClassName();
                }


                def streamName = key.replaceAll("[^a-zA-Z0-9\\._]+", "_");
                if(!messageBlacklisted) {
                        if(!fileMap.containsKey(streamName)) {
                                def outputFile = createSerenityLogFile(streamName+".txt");
                                fileMap.put(streamName, outputFile);
                        }
                        def resultingMessage = preprocessOutput(event.message)
                        fileMap.get(streamName) << resultingMessage;
                }
        }
}

public String preprocessOutput(String originalMessage)
{
        java.text.DateFormat dateFormat = new java.text.SimpleDateFormat("HH:mm:ss");
        String timestamp = dateFormat.format(new java.util.Date());
        String[] splitSegments = originalMessage.split("[\r\n]+");
        Collection<String> transformedSegments = splitSegments.collect{line->
                timestamp+"\t"+line+"\n";
        };
        String resultingMessage = transformedSegments.iterator().join("");
        return resultingMessage;
}

public File createSerenityLogFile(String fileName){
        def logFolder = new File(new File(project.rootDir, project.serenity.outputDirectory), "logs");
        createDirectory(logFolder);
        def outputFile = new File(logFolder, fileName);
        deleteFile(outputFile);
        createFile(outputFile);
        return outputFile;
}


tasks.test.doFirst {
        logging.captureStandardOutput LogLevel.INFO
        logger.lifecycle("Transfering gradle properties to system properties...");

        systemProperty 'cucumber.options', System.getProperty('cucumber.options', '')
        if(project.hasProperty("firefox.profile.path"))
                systemProperty 'firefox.profile.path', project.getProperty('firefox.profile.path')


        setSystemProperty "webdriver.base.url", "http://${ftWebHost}:8080"

        if(project.hasProperty("ftWebHost")){
                systemProperty "restassured.base.url", project.getProperty("ftWebHost")
        }
        //This will set the webdriver url and the restAssured url
        systemProperty "restassured.base.url", "${ftWebHost}"
        setSystemProperty "webdriver.base.url", "http://${ftWebHost}:8080"
        setSystemProperty "jmsBrokerURL", "tcp://${ftWebHost}:61616"
        if (project.hasProperty("apiDebugOutput")) {
                systemProperty "debug.api.testing", "${apiDebugOutput}"
        }

        if(project.hasProperty("ftWebPort")){
                systemProperty "restassured.base.port", "${ftWebPort}"
        }

        if(project.hasProperty("ftWebSecure")){
                systemProperty "restassured.secure.connection", "${ftWebSecure}"
        }

        if(project.hasProperty("payURL"))
                setSystemProperty "pay.url", "${payURL}"
        systemProperty "pay.url", "${payURL}"

        if(project.hasProperty("formTHost") && project.hasProperty("internalAppFTHost")) {
                setSystemProperty "external.host", "${formI90FTHost}/efile/login"
                systemProperty "external.host", "${formTHost}/file/login"
                setSystemProperty "internal.host", "${internalAppFTHost}/InternalApp/login"
                systemProperty "internal.host", "${internalAppFTHost}/InternalApp/login"
        }
        if(project.hasProperty("ftWebPort") && project.hasProperty("formI90FTHost") && project.hasProperty("internalAppFTHost")) {
                setSystemProperty "external.host", "${formI90FTHost}:${ftWebPort}/efile/login"
                systemProperty "external.host", "${formI90FTHost}:${ftWebPort}/efile/login"
                setSystemProperty "internal.host", "${internalAppFTHost}:${ftWebPort}/InternalApp/login"
                systemProperty "internal.host", "${internalAppFTHost}:${ftWebPort}/InternalApp/login"
        }

        println "Overriding serenity properties for child jvms based on system properties (takes precedence over serenity.properties)..."
        net.thucydides.core.util.SystemEnvironmentVariables environmentVariables = new net.thucydides.core.util.SystemEnvironmentVariables();
        Map<String, net.thucydides.core.ThucydidesSystemProperty> propertyNameMap = new TreeMap<String, net.thucydides.core.ThucydidesSystemPrope
rty>();


        for(net.thucydides.core.ThucydidesSystemProperty property : net.thucydides.core.ThucydidesSystemProperty.values()) {
                String key = property.getPropertyName().replaceAll("thucydides.","serenity.");//withSerenityPrefix() method
                propertyNameMap.put(key, property);
        }

        for(String key : propertyNameMap.keySet()){
                net.thucydides.core.ThucydidesSystemProperty property = propertyNameMap.get(key);
                if(property.isDefinedIn(environmentVariables)) {
                        String value = property.from(environmentVariables);
                        println "(O)${key}=${value}"
                        systemProperty key, value
                }
                else {
                        println "( )${key}"
                }
        }

        if(project.hasProperty("maxParallelForks")) {
                int forks = project.getProperty("maxParallelForks") as int;
                println "Running up to ${forks} test suites in parallel";
                maxParallelForks = forks;
        }
}

public void setSystemProperty(String key, String value){
        System.setProperty(key, value);
        println "Set system property "+key+"="+value;
}

task cucumberMonkey(dependsOn: 'compileTestJava', type:JavaExec){
        doFirst{
                println("Executing cucumber monkey");
                classpath = sourceSets.main.output + sourceSets.test.output + sourceSets.main.runtimeClasspath + sourceSets.test.runtimeClasspath
                main = 'gov.dhs.uscis.elis2.serenity.utils.cucumbermonkey.CucumberMonkeyRunner'
                standardOutput = new FileOutputStream(createSerenityLogFile("CucumberMonkey.txt"));
        }
}

task generateCucumberTestSuites (dependsOn: 'processTestResources') {
        File root = buildFile.getParentFile();//assumes build.gradle is in root directory
        File featureTemplatePath = new File(root, "FeatureFile.template");
        File cucumberTemplatePath = new File(root, "CucumberTestSuite.template");
        File featureDirectory = new File(root, "src/test/resources/features/");
        File outputFeatureDirectory = new File(root, "src/test/resources/autogenerated/");
        File testSuitePath = new File(root,"src/test/java/serenity/")

        String testSuitePackage = "serenity"
        String[] glue = ["serenity.parallel"]
        String testSuiteRegex = /CucumberTestSuite\d+.java/
        String featureTestRegex = /.*\.feature/

        Template cucumberTemplate = readTemplate(cucumberTemplatePath);
        Template featureTemplate  = readTemplate(featureTemplatePath);


        def featureProp = "";
        if(project.hasProperty("features")) {
                featureProp = features;
        }
       featureProp = featureProp.split(",");

        Set<File> matchedFeatures = filterMatchedFeatures(matchFiles(featureDirectory, featureTestRegex, true), featureProp)
        generateCucumberTestSuites(cucumberTemplate, featureTemplate, matchedFeatures, testSuitePath, testSuitePackage, glue, outputFeatureDirect
ory, testSuiteRegex);
}

public Set<File> filterMatchedFeatures(Set<File> files, String[] features) {
        if(features.length == 0)
                return files;

        Set<File> matchedFiles = new TreeSet<File>();
        for(File f : files) {
                for(String feature : features) {
                        if(f.getName().contains(feature.trim())) {
                                matchedFiles.add(f);
                                break;
                        }
                }
        }
        return matchedFiles;
}

public groovy.text.Template readTemplate(File file) {
        String rawTemplate = file.getText('UTF-8')
        return new groovy.text.SimpleTemplateEngine().createTemplate(rawTemplate);
}

public void writeTemplate(Template template, def templateBinding, File outputFile) {
        logger.lifecycle("Writing templated file ${outputFile}")
        def templatedResult = template.make(templateBinding).toString()
        outputFile << templatedResult;
}

public Set<File> matchFiles(File directory, String matcher, boolean recursive){
        Set<File> matchingFiles = new TreeSet<String>();
        Closure match = {
                if(it.name.matches(matcher)) {
                        matchingFiles.add(it);
                }
        }
        if(recursive) {
                directory.eachFileRecurse(FileType.FILES, match);
        }
        else {
                directory.eachFile(FileType.FILES,match);
        }
        return matchingFiles;
}

public void scorchDirectory(File directory) {
        deleteDirectory(directory);
        createDirectory(directory);
}

public void scrubDirectory(File directory, String pattern){
        directory.eachFile(FileType.FILES) {
                if(it.name.matches(pattern)){
                        deleteFile(it);
                }
        }
}

public void createDirectory(File f){
        if(!f.exists()) {
                logger.lifecycle("Creating ${f}")
                f.mkdirs();
        }
}

public void createFile(File f){
        if(!f.exists()) {
                logger.lifecycle("Creating ${f}")
                f.createNewFile();
        }
}

public void copyFile(File original, File newFile) {
        logger.lifecycle("Copying ${original} to ${newFile}.")
        newFile.bytes = original.bytes
}

public void deleteDirectory(File f){
        if(f.exists()) {
                logger.lifecycle("Deleting ${f}")
                f.deleteDir();
        }
}

public void deleteFile(File f){
        if(f.exists()) {
                logger.lifecycle("Deleting ${f}")
                f.delete();
        }
}

public void generateCucumberTestSuites(Template cucumberTemplate, Template featureTemplate, Set<File> featureFiles, File testSuiteFolder, String
testSuitePackage, String[] glue, File outputFeatureFolder, String pattern) {
        scrubDirectory(testSuiteFolder, pattern);
        scorchDirectory(outputFeatureFolder);

        int count = 0;
        for(File featureFile : featureFiles) {
                File featureDirectory = new File(outputFeatureFolder, "feature${count}")
                createDirectory(featureDirectory);
                File newFeatureFile = new File(featureDirectory, featureFile.getName())

                def featureTemplateBinding = [
                        "GENERATED_DATE":new Date().toString(),
                        "FEATURE_FILE_CONTENT":featureFile.getText("UTF-8")
                ]

                writeTemplate(featureTemplate, featureTemplateBinding, newFeatureFile);
                String generatedDate = new Date().toString();
                String packageName = testSuitePackage;
                String featureDirectoryString = featureDirectory.getCanonicalPath().replace("\\", "/")
                String testSuiteName = "CucumberTestSuite${count}"
                String joinedGlue = glue.collect{"\""+it+"\""}.join(",");

                def cucumberTemplateBinding = [
                        "GENERATED_DATE":generatedDate,
                        "PACKAGE_NAME":packageName,
                        "FEATURE_DIRECTORY":featureDirectoryString,
                        "TEST_SUITE_NAME":testSuiteName,
                        "GLUE":joinedGlue
                ]

                String testSuiteFileName = "${testSuiteName}.java";
                if(!testSuiteFileName.matches(pattern)) {
                        throw new Exception("Generated file name ${testSuiteFileName} does not match regex ${pattern}");
                }

                writeTemplate(cucumberTemplate, cucumberTemplateBinding, new File(testSuiteFolder, testSuiteFileName))
                count++;
        }
}

task uberJar(type: Jar,dependsOn:[':compileJava',':compileGroovy']) {
    zip64 true
    from files(sourceSets.main.output.classesDir)
    from configurations.runtime.asFileTree.files.collect { zipTree(it) }
    with jar

    manifest {
        attributes 'Main-Class': mainClassName
    }
}

gradle.startParameter.continueOnFailure = true
4

1 回答 1

0

您需要添加保存功能文件的位置,例如:@CucumberOptions(format = {"pretty"}, monochrome=true, features = { "src/test/resources/features/" } )。格式选项也已折旧,请尝试plugin。还要添加胶水的位置(步骤定义)

于 2016-05-03T12:03:44.077 回答