You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JUnit 5 Jupiter中运行JBehave测试?

JBehave在JUnit 5环境中的迁移方案

好消息是JBehave完全可以在JUnit 5环境中运行!虽然官方目前还没有提供原生的JUnit 5扩展,但我们可以绕开原来JUnit 4的@RunWith机制,让JUnit 5直接托管JBehave的执行逻辑,具体操作如下:

核心思路

原来的JUnit 4通过@RunWith(AnnotatedEmbedderRunner.class)让JUnit托管JBehave的执行流程,而JUnit 5没有对应的扩展支持。我们的解决办法是:把JBehave的故事执行逻辑封装到一个JUnit 5的@Test方法中,让JUnit 5识别这个测试方法,内部手动启动JBehave的Embedder来运行所有故事。

调整测试类代码

下面是修改后的JBehaveTest类,我标注了关键的修改点:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.jbehave.core.Embeddable;
import org.jbehave.core.Embedder;
import org.jbehave.core.configuration.MostUsefulConfiguration;
import org.jbehave.core.io.CodeLocations;
import org.jbehave.core.io.StoryFinder;
import org.jbehave.core.reporters.DetailedStepReporter;
import org.jbehave.core.reporters.Format;
import org.jbehave.core.reporters.StoryReporterBuilder;
import org.jbehave.core.steps.InstanceStepsFactory;
import org.jbehave.core.steps.Steps;
import org.jbehave.core.reporters.DotStoryReporter;
import org.testfx.api.FxToolkit;
import javafx.stage.Stage;

import java.io.File;
import java.util.Collections;
import java.util.Locale;
import java.util.concurrent.TimeoutException;

public class JBehaveTest implements Embeddable {
    private Embedder embedder;
    private DotStoryReporter dot = new DotStoryReporter();
    private Stage primaryStage;

    // 替换JUnit 4的@Before为JUnit 5的@BeforeEach
    @BeforeEach
    public void createStage() throws TimeoutException {
        Locale locale = new Locale("fa", "IR");
        Locale.setDefault(locale);
        primaryStage = FxToolkit.registerPrimaryStage();
    }

    // JUnit 5识别的唯一测试方法,内部触发所有JBehave故事执行
    @Test
    public void runJBehaveStories() throws Throwable {
        initEmbedder();
        // 运行所有匹配的.story文件
        embedder.runStoriesAsPaths(new StoryFinder().findPaths(
                "src/test/resources",
                Collections.singletonList("**/*.story"),
                Collections.emptyList()
        ));
        // 验证执行结果,让JUnit 5感知故事执行的成败
        if (!embedder.getEmbedderControls().isIgnoreFailureInStories()) {
            org.junit.jupiter.api.Assertions.assertTrue(
                    embedder.getFailureCount() == 0,
                    "JBehave故事执行失败,失败数量: " + embedder.getFailureCount()
            );
        }
    }

    // 手动初始化Embedder和配置,替代原来@UsingEmbedder的作用
    private void initEmbedder() {
        embedder = new Embedder();
        MostUsefulConfiguration configuration = new MostUsefulConfiguration();
        Steps steps = new Steps();

        // 配置报告生成逻辑,和原来保持一致
        configuration.useStoryReporterBuilder(
                new StoryReporterBuilder()
                        .withCodeLocation(CodeLocations.codeLocationFromClass(JBehaveTest.class))
                        .withDefaultFormats()
                        .withReporters(dot, new MyStoryReporter(new File("test"), steps))
                        .withFormats(Format.HTML, Format.TXT)
                        .withFailureTrace(true)
                        .withFailureTraceCompression(false)
        );
        configuration.useStepdocReporter(new DetailedStepReporter());

        // 绑定Steps类和配置
        embedder.useStepsFactory(new InstanceStepsFactory(configuration, steps));
        embedder.useConfiguration(configuration);

        // 手动设置原来@UsingEmbedder中的参数
        embedder.embedderControls()
                .useVerboseFailures(true)
                .doIgnoreFailureInStories(false)
                .doGenerateViewAfterStories(true);
    }

    @Override
    public void useEmbedder(Embedder embedder) {
        this.embedder = embedder;
    }
}

调整Gradle依赖

原来的de.codecentric:jbehave-junit-runner是JUnit 4专属的运行器,现在可以移除了,其他依赖保持不变即可:

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.2.0'
testImplementation 'org.mockito:mockito-core:2.18.3'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.2.0'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.2.0'
testImplementation 'org.testfx:testfx-core:4.0.+'
testImplementation 'org.testfx:testfx-junit5:4.0.+'
testImplementation 'org.jbehave:jbehave-core:4.3.2'
// 移除JUnit 4的JBehave运行器
// testCompile 'de.codecentric:jbehave-junit-runner:1.2.0'

关键注意事项

  • 确保StoryFinder的路径参数和你的项目结构匹配,避免找不到故事文件
  • 如果有自定义的Steps类,要在InstanceStepsFactory的构造参数中添加进去(比如new InstanceStepsFactory(configuration, steps, customStep1, customStep2))
  • JBehave的报告生成逻辑不受影响,依然会按照配置输出HTML、TXT等格式的报告

内容的提问来源于stack exchange,提问作者M. le Rutte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:04:59