xtext 参数化的 xtext runner
xtext parameterized xtext runner
目的: 运行 xtext/xtend 上下文中的参数化测试。
进度: 到目前为止,我已经实现了 运行,但它在 junit window.
中出现错误
问题:
两次测试的失败痕迹和结果都出现在最后一次测试中,如下图所示。
用红笔标记的第一个测试有点未解决,不包含任何失败痕迹。
这里是测试class:
@RunWith(typeof(Parameterized))
@InjectWith(SemanticAdaptationInjectorProvider)
@Parameterized.UseParametersRunnerFactory(XtextParametersRunnerFactory)
class CgCppAutoTest extends AbstractSemanticAdaptationTest {
new (List<File> files)
{
f = files;
}
@Inject extension ParseHelper<SemanticAdaptation>
@Inject extension ValidationTestHelper
@Parameters(name = "{index}")
def static Collection<Object[]> data() {
val files = new ArrayList<List<File>>();
listf("test_input", files);
val test = new ArrayList();
test.add(files.get(0));
return Arrays.asList(test.toArray(), test.toArray());
}
def static void listf(String directoryName, List<List<File>> files) {
...
}
var List<File> f;
@Test def allSemanticAdaptations() {
System.out.println("fail");
assertTrue(false);
}
}
ParameterizedXtext运行ner(灵感来自这里:https://www.eclipse.org/forums/index.php?t=msg&th=1075706&goto=1726802&):
class ParameterizedXtextRunner extends XtextRunner {
val Object[] parameters;
val String annotatedName;
new(TestWithParameters test) throws InitializationError {
super(test.testClass.javaClass)
parameters = test.parameters;
annotatedName = test.name;
}
override protected getName() {
return super.name + annotatedName;
}
override protected createTest() throws Exception {
val object = testClass.onlyConstructor.newInstance(parameters)
val injectorProvider = getOrCreateInjectorProvider
if (injectorProvider != null) {
val injector = injectorProvider.injector
if (injector != null)
injector.injectMembers(object)
}
return object;
}
override protected void validateConstructor(List<Throwable> errors) {
validateOnlyOneConstructor(errors)
}
最后是 XtextParameters运行nerFactory:
class XtextParametersRunnerFactory implements ParametersRunnerFactory {
override createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError {
new ParameterizedXtextRunner(test)
}
}
通过查看 XtextRunner class 它继承自 BlockJUnit4ClassRunner。
参数化不扩展这个跑步者,但是
父母亚军。但是,BlockJUnit4ClassRunner 也是如此
因此我们实现如下:
public class XtextParametersRunnerFactory implements ParametersRunnerFactory {
@Override
public Runner createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError {
return new XtextRunnerWithParameters(test);
}
}
并使用了 XtextRunner 中的代码并将其放入新的运行器中——还需要从 Xtext 中提取 InjectorProviders
public class XtextRunnerWithParameters extends BlockJUnit4ClassRunnerWithParameters {
public XtextRunnerWithParameters(TestWithParameters test) throws InitializationError {
super(test);
}
@Override
public Object createTest() throws Exception {
Object object = super.createTest();
IInjectorProvider injectorProvider = getOrCreateInjectorProvider();
if (injectorProvider != null) {
Injector injector = injectorProvider.getInjector();
if (injector != null)
injector.injectMembers(object);
}
return object;
}
@Override
protected Statement methodBlock(FrameworkMethod method) {
IInjectorProvider injectorProvider = getOrCreateInjectorProvider();
if (injectorProvider instanceof IRegistryConfigurator) {
final IRegistryConfigurator registryConfigurator = (IRegistryConfigurator) injectorProvider;
registryConfigurator.setupRegistry();
final Statement methodBlock = superMethodBlock(method);
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
methodBlock.evaluate();
} finally {
registryConfigurator.restoreRegistry();
}
}
};
}else{
return superMethodBlock(method);
}
}
protected Statement superMethodBlock(FrameworkMethod method) {
return super.methodBlock(method);
}
protected IInjectorProvider getOrCreateInjectorProvider() {
return InjectorProviders.getOrCreateInjectorProvider(getTestClass());
}
protected IInjectorProvider getInjectorProvider() {
return InjectorProviders.getInjectorProvider(getTestClass());
}
protected IInjectorProvider createInjectorProvider() {
return InjectorProviders.createInjectorProvider(getTestClass());
}
}
正在创建测试:
@RunWith(typeof(Parameterized))
@InjectWith(SemanticAdaptationInjectorProvider)
@Parameterized.UseParametersRunnerFactory(XtextParametersRunnerFactory)
class xxx
{
@Inject extension ParseHelper<SemanticAdaptation>
@Inject extension ValidationTestHelper
// Here goes standard parameterized stuff
}
由于 OSGi 导入包的限制和弃用,我使用这个采用的原始代码:
package de.uni_leipzig.pkr.handparser.tests.runners;
import org.eclipse.xtext.testing.IInjectorProvider;
import org.eclipse.xtext.testing.IRegistryConfigurator;
import org.eclipse.xtext.testing.XtextRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters;
import org.junit.runners.parameterized.TestWithParameters;
import com.google.inject.Injector;
public class XtextRunnerWithParameters extends BlockJUnit4ClassRunnerWithParameters {
public static class MyXtextRunner extends XtextRunner {
public MyXtextRunner(Class<?> testClass) throws InitializationError {
super(testClass);
}
public IInjectorProvider getOrCreateInjectorProvider() {
return super.getOrCreateInjectorProvider();
}
}
private MyXtextRunner xtextRunner;
public XtextRunnerWithParameters(TestWithParameters test) throws InitializationError {
super(test);
xtextRunner = new MyXtextRunner(test.getTestClass().getJavaClass());
}
@Override
public Object createTest() throws Exception {
Object object = super.createTest();
IInjectorProvider injectorProvider = xtextRunner.getOrCreateInjectorProvider();
if (injectorProvider != null) {
Injector injector = injectorProvider.getInjector();
if (injector != null)
injector.injectMembers(object);
}
return object;
}
@Override
protected Statement methodBlock(FrameworkMethod method) {
IInjectorProvider injectorProvider = xtextRunner.getOrCreateInjectorProvider();
if (injectorProvider instanceof IRegistryConfigurator) {
final IRegistryConfigurator registryConfigurator = (IRegistryConfigurator) injectorProvider;
registryConfigurator.setupRegistry();
final Statement methodBlock = superMethodBlock(method);
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
methodBlock.evaluate();
} finally {
registryConfigurator.restoreRegistry();
}
}
};
} else {
return superMethodBlock(method);
}
}
protected Statement superMethodBlock(FrameworkMethod method) {
return super.methodBlock(method);
}
}
目的: 运行 xtext/xtend 上下文中的参数化测试。
进度: 到目前为止,我已经实现了 运行,但它在 junit window.
中出现错误问题: 两次测试的失败痕迹和结果都出现在最后一次测试中,如下图所示。 用红笔标记的第一个测试有点未解决,不包含任何失败痕迹。
这里是测试class:
@RunWith(typeof(Parameterized))
@InjectWith(SemanticAdaptationInjectorProvider)
@Parameterized.UseParametersRunnerFactory(XtextParametersRunnerFactory)
class CgCppAutoTest extends AbstractSemanticAdaptationTest {
new (List<File> files)
{
f = files;
}
@Inject extension ParseHelper<SemanticAdaptation>
@Inject extension ValidationTestHelper
@Parameters(name = "{index}")
def static Collection<Object[]> data() {
val files = new ArrayList<List<File>>();
listf("test_input", files);
val test = new ArrayList();
test.add(files.get(0));
return Arrays.asList(test.toArray(), test.toArray());
}
def static void listf(String directoryName, List<List<File>> files) {
...
}
var List<File> f;
@Test def allSemanticAdaptations() {
System.out.println("fail");
assertTrue(false);
}
}
ParameterizedXtext运行ner(灵感来自这里:https://www.eclipse.org/forums/index.php?t=msg&th=1075706&goto=1726802&):
class ParameterizedXtextRunner extends XtextRunner {
val Object[] parameters;
val String annotatedName;
new(TestWithParameters test) throws InitializationError {
super(test.testClass.javaClass)
parameters = test.parameters;
annotatedName = test.name;
}
override protected getName() {
return super.name + annotatedName;
}
override protected createTest() throws Exception {
val object = testClass.onlyConstructor.newInstance(parameters)
val injectorProvider = getOrCreateInjectorProvider
if (injectorProvider != null) {
val injector = injectorProvider.injector
if (injector != null)
injector.injectMembers(object)
}
return object;
}
override protected void validateConstructor(List<Throwable> errors) {
validateOnlyOneConstructor(errors)
}
最后是 XtextParameters运行nerFactory:
class XtextParametersRunnerFactory implements ParametersRunnerFactory {
override createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError {
new ParameterizedXtextRunner(test)
}
}
通过查看 XtextRunner class 它继承自 BlockJUnit4ClassRunner。 参数化不扩展这个跑步者,但是 父母亚军。但是,BlockJUnit4ClassRunner 也是如此 因此我们实现如下:
public class XtextParametersRunnerFactory implements ParametersRunnerFactory {
@Override
public Runner createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError {
return new XtextRunnerWithParameters(test);
}
}
并使用了 XtextRunner 中的代码并将其放入新的运行器中——还需要从 Xtext 中提取 InjectorProviders
public class XtextRunnerWithParameters extends BlockJUnit4ClassRunnerWithParameters {
public XtextRunnerWithParameters(TestWithParameters test) throws InitializationError {
super(test);
}
@Override
public Object createTest() throws Exception {
Object object = super.createTest();
IInjectorProvider injectorProvider = getOrCreateInjectorProvider();
if (injectorProvider != null) {
Injector injector = injectorProvider.getInjector();
if (injector != null)
injector.injectMembers(object);
}
return object;
}
@Override
protected Statement methodBlock(FrameworkMethod method) {
IInjectorProvider injectorProvider = getOrCreateInjectorProvider();
if (injectorProvider instanceof IRegistryConfigurator) {
final IRegistryConfigurator registryConfigurator = (IRegistryConfigurator) injectorProvider;
registryConfigurator.setupRegistry();
final Statement methodBlock = superMethodBlock(method);
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
methodBlock.evaluate();
} finally {
registryConfigurator.restoreRegistry();
}
}
};
}else{
return superMethodBlock(method);
}
}
protected Statement superMethodBlock(FrameworkMethod method) {
return super.methodBlock(method);
}
protected IInjectorProvider getOrCreateInjectorProvider() {
return InjectorProviders.getOrCreateInjectorProvider(getTestClass());
}
protected IInjectorProvider getInjectorProvider() {
return InjectorProviders.getInjectorProvider(getTestClass());
}
protected IInjectorProvider createInjectorProvider() {
return InjectorProviders.createInjectorProvider(getTestClass());
}
}
正在创建测试:
@RunWith(typeof(Parameterized))
@InjectWith(SemanticAdaptationInjectorProvider)
@Parameterized.UseParametersRunnerFactory(XtextParametersRunnerFactory)
class xxx
{
@Inject extension ParseHelper<SemanticAdaptation>
@Inject extension ValidationTestHelper
// Here goes standard parameterized stuff
}
由于 OSGi 导入包的限制和弃用,我使用这个采用的原始代码:
package de.uni_leipzig.pkr.handparser.tests.runners;
import org.eclipse.xtext.testing.IInjectorProvider;
import org.eclipse.xtext.testing.IRegistryConfigurator;
import org.eclipse.xtext.testing.XtextRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters;
import org.junit.runners.parameterized.TestWithParameters;
import com.google.inject.Injector;
public class XtextRunnerWithParameters extends BlockJUnit4ClassRunnerWithParameters {
public static class MyXtextRunner extends XtextRunner {
public MyXtextRunner(Class<?> testClass) throws InitializationError {
super(testClass);
}
public IInjectorProvider getOrCreateInjectorProvider() {
return super.getOrCreateInjectorProvider();
}
}
private MyXtextRunner xtextRunner;
public XtextRunnerWithParameters(TestWithParameters test) throws InitializationError {
super(test);
xtextRunner = new MyXtextRunner(test.getTestClass().getJavaClass());
}
@Override
public Object createTest() throws Exception {
Object object = super.createTest();
IInjectorProvider injectorProvider = xtextRunner.getOrCreateInjectorProvider();
if (injectorProvider != null) {
Injector injector = injectorProvider.getInjector();
if (injector != null)
injector.injectMembers(object);
}
return object;
}
@Override
protected Statement methodBlock(FrameworkMethod method) {
IInjectorProvider injectorProvider = xtextRunner.getOrCreateInjectorProvider();
if (injectorProvider instanceof IRegistryConfigurator) {
final IRegistryConfigurator registryConfigurator = (IRegistryConfigurator) injectorProvider;
registryConfigurator.setupRegistry();
final Statement methodBlock = superMethodBlock(method);
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
methodBlock.evaluate();
} finally {
registryConfigurator.restoreRegistry();
}
}
};
} else {
return superMethodBlock(method);
}
}
protected Statement superMethodBlock(FrameworkMethod method) {
return super.methodBlock(method);
}
}