
com.automationrockstars.bmo.CucumberExecutor Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2015, 2016 Automation RockStars Ltd.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Apache License v2.0
* which accompanies this distribution, and is available at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Contributors:
* Automation RockStars - initial API and implementation
*******************************************************************************/
package com.automationrockstars.bmo;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.junit.runner.Description;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.ParentRunner;
import org.junit.runners.model.InitializationError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.automationrockstars.base.ConfigLoader;
import com.automationrockstars.bmo.junit.FakeTest;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import cucumber.api.CucumberOptions;
import cucumber.runtime.ClassFinder;
import cucumber.runtime.Runtime;
import cucumber.runtime.RuntimeOptions;
import cucumber.runtime.RuntimeOptionsFactory;
import cucumber.runtime.io.MultiLoader;
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.io.ResourceLoaderClassFinder;
import cucumber.runtime.junit.Assertions;
import cucumber.runtime.junit.FeatureRunner;
import cucumber.runtime.junit.JUnitOptions;
import cucumber.runtime.junit.JUnitReporter;
import cucumber.runtime.model.CucumberFeature;
public class CucumberExecutor extends ParentRunner {
private JUnitReporter jUnitReporter;
private final List children = new ArrayList();
private Runtime runtime;
private RuntimeOptions runtimeOptions;
/**
* Constructor called by JUnit.
*
* @param clazz the class with the @RunWith annotation.
* @throws java.io.IOException if there is a problem
* @throws org.junit.runners.model.InitializationError if there is another problem
*/
public CucumberExecutor(Class> clazz) throws InitializationError, IOException {
super(clazz);
Assertions.assertNoCucumberAnnotatedMethods(clazz);
ClassLoader classLoader = clazz.getClassLoader();
if (clazz.getAnnotation(CucumberOptions.class) == null) {
singleRunnerInit();
} else {
classInit(clazz);
}
ResourceLoader resourceLoader = new MultiLoader(classLoader);
runtime = createRuntime(resourceLoader, classLoader, runtimeOptions);
final List cucumberFeatures = runtimeOptions.cucumberFeatures(resourceLoader);
jUnitReporter = new JUnitReporter(runtimeOptions.reporter(classLoader), runtimeOptions.formatter(classLoader),
runtimeOptions.isStrict(),new JUnitOptions(Lists.newArrayList("--allow-started-ignored", "--filename-compatible-names")));
addChildren(cucumberFeatures);
}
private void classInit(Class> clazz) throws InitializationError, IOException {
RuntimeOptionsFactory runtimeOptionsFactory = new RuntimeOptionsFactory(clazz);
runtimeOptions = runtimeOptionsFactory.create();
}
/**
* Create the Runtime. Can be overridden to customize the runtime or
* backend.
*
* @param resourceLoader used to load resources
* @param classLoader used to load classes
* @param runtimeOptions configuration
* @return a new runtime
* @throws InitializationError if a JUnit error occurred
* @throws IOException if a class or resource could not be loaded
*/
protected Runtime createRuntime(ResourceLoader resourceLoader, ClassLoader classLoader,
RuntimeOptions runtimeOptions) throws InitializationError, IOException {
ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
return new Runtime(resourceLoader, classFinder, classLoader, runtimeOptions);
}
@Override
public List getChildren() {
return children;
}
@Override
protected Description describeChild(FeatureRunner child) {
return child.getDescription();
}
// private static final ExecutorService testRunners = Executors.newFixedThreadPool(ConfigLoader.config().getInt("parallel.runners",1));
// private static final LinkedBlockingQueue> featureRuns = Queues.newLinkedBlockingQueue();
@Override
protected void runChild(final FeatureRunner child, final RunNotifier notifier) {
// featureRuns.add(testRunners.submit(new Runnable() {
// @Override
// public void run() {
child.run(notifier);
// }
// }));
}
@Override
public void run(RunNotifier notifier) {
super.run(notifier);
// testRunners.shutdown();
// List errors = Lists.newArrayList();
// while (! featureRuns.isEmpty()){
// try {
// featureRuns.poll().get();
// } catch (InterruptedException | ExecutionException e) {
// errors.add(e);
// LOG.error("Error during execution",e);
// }
// }
// try {
// testRunners.awaitTermination(10, TimeUnit.MINUTES);
// } catch (InterruptedException e) {
// LOG.error("Error waiting for tests to complete",e);
// }
// LOG.warn("Errors during test execution {}",Joiner.on("\n").join(errors));
jUnitReporter.done();
jUnitReporter.close();
runtime.printSummary();
}
private void addChildren(List cucumberFeatures) throws InitializationError {
for (CucumberFeature cucumberFeature : cucumberFeatures) {
children.add(new FeatureRunner(cucumberFeature, runtime, jUnitReporter));
}
}
public String tags() {
return "";
}
public List glue() {
String defaultGlue = "stepDefinition/hiPlus,stepDefinition/common,";
if (features().contains("motor")) {
defaultGlue += "stepDefinition/motor";
} else {
defaultGlue += "stepDefinition/home,stepDefinition/mta";
}
LOG.info("Default glue is {}", defaultGlue);
return Splitter.on(",").splitToList(ConfigLoader.config().getString("bdd.glue", defaultGlue));
}
private String features;
private static final Logger LOG = LoggerFactory.getLogger(CucumberExecutor.class);
public String features() {
if (Strings.isNullOrEmpty(features)) {
try {
File featureDir = Paths.get(new File("").getAbsolutePath()).toFile();
String[] DEFAULT_STORY_EXTENTIONS = new String[]{"feature"};
String[] storyExtenstions = ConfigLoader.config().getStringArray("bdd.story.files");
storyExtenstions = (storyExtenstions == null || storyExtenstions.length == 0) ? DEFAULT_STORY_EXTENTIONS : storyExtenstions;
String[] argFilter = ConfigLoader.config().getStringArray("bdd.story.filter");
final String[] filter = (argFilter == null || argFilter.length == 0) ? new String[]{"home"} : argFilter;
LOG.info("Using filters {}", Arrays.toString(filter));
Collection allFeatures = FileUtils.listFiles(featureDir, storyExtenstions, true);
List result = Lists.newArrayList(Iterables.filter(Iterables.transform(allFeatures,
new Function() {
@Override
public String apply(File input) {
return input.getAbsolutePath();
}
}), new Predicate() {
@Override
public boolean apply(String input) {
boolean hasAll = true;
for (String partFilter : filter) {
hasAll = hasAll && input.contains(partFilter);
}
return hasAll && !input.contains("test-classes") && !input.contains("target") && input.contains("cucumber");
}
}));
features = common(result);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Cannot find features to execute. Please make sure cucumber folder contains files");
}
}
LOG.info("Executing stories {}", features);
Preconditions.checkArgument(!features.isEmpty(), "No story files has been found");
return features;
}
private void singleRunnerInit() {
List runtimeArgs = Lists.newArrayList("-p",
"html:target/cucumber", "-p", "json:target/features.json", "-p", "utilities.AllurePlugin",
"-m");
for (String gluePart : glue()) {
runtimeArgs.add("-g");
runtimeArgs.add(gluePart);
}
runtimeArgs.add(features());
runtimeOptions = new RuntimeOptions(runtimeArgs);
}
public static String common(String a, String b) {
List base = Lists.newArrayList();
List x = Splitter.onPattern("/|\\\\").splitToList(a);
List y = Splitter.onPattern("/|\\\\").splitToList(b);
for (int i = 0; i < x.size(); i++) {
if (x.get(i).equals(y.get(i))) {
base.add(x.get(i));
} else break;
}
return Joiner.on("/").join(base);
}
public static String common(List strings) {
Preconditions.checkArgument(strings.size() > 0, "Cannot compare nothing");
if (strings.size() == 1) return strings.get(0);
String base = strings.get(0);
for (int i = 1; i < strings.size(); i++) {
base = common(base, strings.get(i));
}
return base;
}
public CucumberExecutor() throws InitializationError, IOException {
this(FakeTest.class);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy