Cucumber UndefinedStepException when 运行 tests with external runner based on JUnit5 platform

Cucumber UndefinedStepException when running tests with external runner based on JUnit5 platform

我已经围绕 JUnit5 平台编写了一个非常简单的包装器来 运行 由我的外部逻辑过滤的测试(它提供路径、packageIds、filterFilePath - 这些处理被代码示例中的常量值替换为简化代码片段)。

包装器的主要逻辑如下所示:

public static void main(String[] args) throws JsonProcessingException {
    String path = "D:\repo\cucumber-java-skeleton\build\libs";
    String[] packageIds = "io.cucumber.skeleton".split(",");
    String filterFilePath = "D:\repo\testrunner\Tests\Data\DummyDataProject\Java\DummyJavaFilter.json";// contains JSON serialized list of correct test IDs

    ClassLoader contextLoader = TestsLoader.GetLoader(path);
    Thread.currentThread().setContextClassLoader(contextLoader);
    final Launcher launcher = LauncherFactory.create();

    List<TestResult> results = new ArrayList<TestResult>();
    launcher.execute(getFilteredTestPlan(launcher, filterFilePath),
            new TestRunnerExecutionListener(results));
    ObjectMapper mapper = new ObjectMapper();
    final String jsonResult = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(results);
    System.out.print("-==TEST RESULTS START==-");
    System.out.print(jsonResult);
    System.out.print("-==TEST RESULTS END==-");
    }
}

此方法 returns TestPlan 过滤为我要执行的 ID(此逻辑工作正常且符合预期)

static TestPlan getFilteredTestPlan(Launcher launcher, String filterFilePath) {
    String json = new String(Files.readAllBytes(Paths.get(filterFilePath)));
    
    ObjectMapper mapper = new ObjectMapper();
    List<String> testIds = mapper.readValue(json, new TypeReference<List<String>>() {});

    LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
            .selectors(testIds.stream().map(id -> selectUniqueId(id)).toArray(UniqueIdSelector[]::new))
            .filters(includeClassNamePatterns(".*")).build();
    return launcher.discover(request);
}

所以问题是,当 运行 将此代码放在一个完美而简单的解决方案上时,例如 @M.P 提供的 this one。 Korstanje 在 gradle.build 依赖项部分添加了一些内容:

    testImplementation 'io.cucumber:cucumber-junit-platform-engine:' + cucumberVersion

对于 junit 平台集成,以及用于构建具有可发现测试的适当 jar 包的这些:

jar {
  from configurations.testCompileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
  from sourceSets.test.output
}

解决方案本身 运行 在添加步骤定义并按预期 运行 测试(使用默认 gradle 测试任务)时非常流畅。但是当 运行ning 使用上面提供的代码时 - 它无法找到步骤定义并且失败 io.cucumber.junit.platform.engine.UndefinedStepException 即使存在步骤。将胶水 属性 添加到 @CucumberOptions 也不能解决问题(尽管甚至不需要,因为步骤定义在同一个包中)。

因此,几天来我已经花了很多时间挖掘所有可用的资源,但没有任何运气,我们将不胜感激任何帮助。

我删除了所有错误处理和处理与问题无关的测试发现的部分,来自此代码作为输入的测试 ID 已正确验证。

更新: 当我将步骤定义添加到 class 包含在包含执行程序逻辑的同一包中时,它成功地发现了它,即使胶水设置指向一个完全不同的包,似乎这些注释被忽略了,因为代码即使完全删除这些注释,上面也会发现测试:

@RunWith(Cucumber.class)
@CucumberOptions(plugin = { "pretty" }, glue = "io.cucumber.skeleton")

.

所以经过一些实验,我想出了一个可以解决问题的肮脏黑客:

System.setProperty("cucumber.glue", String.join(",", packageIds));//packageIds has to contain all Step Definitions pacakges

这添加了稍后由 this code as in this 处理的系统 属性 文档说明它要么获取属性文件(我没能将其添加到 Jar 文件中,因为我是新手Java 和 Jar 包装细节)或读取我添加的 JVM 中的系统属性。一个更成功的解决方案是从包含测试的目标包中获取这些属性,如果没有过多的搜索和一些相当大量的反射使用,我也未能做到这一点。理想的解决方案是 Cucumber Runner 和 Junit 平台之间的适当集成,该平台尚未到位或者我以某种方式错过了它。任何更好的回复将不胜感激,并将标记为正确答案。