Using the suggestion given by Marcus:
Step1: Create your custom MultiLoader class:
package cucumber.runtime.io;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
public class CustomMultiLoader implements ResourceLoader {
public static final String CLASSPATH_SCHEME = "classpath*:";
public static final String CLASSPATH_SCHEME_TO_REPLACE = "classpath:";
private final ClasspathResourceLoader classpath;
private final FileResourceLoader fs;
public CustomMultiLoader(ClassLoader classLoader) {
classpath = new ClasspathResourceLoader(classLoader);
fs = new FileResourceLoader();
}
@Override
public Iterable<Resource> resources(String path, String suffix) {
if (isClasspathPath(path)) {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
String locationPattern = path.replace(CLASSPATH_SCHEME_TO_REPLACE, CLASSPATH_SCHEME) + "/**/*" + suffix;
org.springframework.core.io.Resource[] resources;
try {
resources = resolver.getResources(locationPattern);
} catch (IOException e) {
resources = null;
e.printStackTrace();
}
return convertToCucumberIterator(resources);
} else {
return fs.resources(path, suffix);
}
}
private Iterable<Resource> convertToCucumberIterator(org.springframework.core.io.Resource[] resources) {
List<Resource> results = new ArrayList<Resource>();
for (org.springframework.core.io.Resource resource : resources) {
results.add(new ResourceAdapter(resource));
}
return results;
}
public static String packageName(String gluePath) {
if (isClasspathPath(gluePath)) {
gluePath = stripClasspathPrefix(gluePath);
}
return gluePath.replace('/', '.').replace('\', '.');
}
private static boolean isClasspathPath(String path) {
if (path.startsWith(CLASSPATH_SCHEME_TO_REPLACE)) {
path = path.replace(CLASSPATH_SCHEME_TO_REPLACE, CLASSPATH_SCHEME);
}
return path.startsWith(CLASSPATH_SCHEME);
}
private static String stripClasspathPrefix(String path) {
if (path.startsWith(CLASSPATH_SCHEME_TO_REPLACE)) {
path = path.replace(CLASSPATH_SCHEME_TO_REPLACE, CLASSPATH_SCHEME);
}
return path.substring(CLASSPATH_SCHEME.length());
}
}
Step2: Create an adapter between org.springframework.core.io.Resource and cucumber.runtime.io.Resource:
package cucumber.runtime.io;
import java.io.IOException;
import java.io.InputStream;
public class ResourceAdapter implements Resource {
org.springframework.core.io.Resource springResource;
public ResourceAdapter(org.springframework.core.io.Resource springResource) {
this.springResource = springResource;
}
public String getPath() {
try {
return springResource.getFile().getPath();
} catch (IOException e) {
try {
return springResource.getURL().toString();
} catch (IOException e1) {
e1.printStackTrace();
return "";
}
}
}
public String getAbsolutePath() {
try {
return springResource.getFile().getAbsolutePath();
} catch (IOException e) {
return null;
}
}
public InputStream getInputStream() throws IOException {
return this.springResource.getInputStream();
}
public String getClassName(String extension) {
String path = this.getPath();
if (path.startsWith("jar:")) {
path = path.substring(path.lastIndexOf("!") + 2);
return path.substring(0, path.length() - extension.length()).replace('/', '.');
} else {
path = path.substring(path.lastIndexOf("classes") + 8);
return path.substring(0, path.length() - extension.length()).replace('\', '.');
}
}
}
Step3: Create your custom main class that uses your CustomMultiLoader:
package cucumber.runtime.io;
import static java.util.Arrays.asList;
import java.io.IOException;
import java.util.ArrayList;
import cucumber.runtime.ClassFinder;
import cucumber.runtime.Runtime;
import cucumber.runtime.RuntimeOptions;
public class CucumberStaticRunner {
public static void startTests(String[] argv) throws Throwable {
byte exitstatus = run(argv, Thread.currentThread().getContextClassLoader());
System.exit(exitstatus);
}
public static byte run(String[] argv, ClassLoader classLoader) throws IOException {
RuntimeOptions runtimeOptions = new RuntimeOptions(new ArrayList<String>(asList(argv)));
ResourceLoader resourceLoader = new CustomMultiLoader(classLoader);
ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
Runtime runtime = new Runtime(resourceLoader, classFinder, classLoader, runtimeOptions);
runtime.run();
return runtime.exitStatus();
}
}
Step4: Call your custom main class instead of cucumber.api.cli.Main.main:
String[] cucumberOptions = { "--glue", "my.test.pack", "--no-dry-run", "--monochrome", "classpath:features" };
CucumberStaticRunner.startTests(cucumberOptions);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…