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

如何在JUnit5测试发现时排除所有子包?

如何用JUnit Launcher运行指定包测试并排除所有子包

方案一:用PackageNameFilter.includePackageNames精准匹配

selectPackage默认会扫描目标包及其所有子包,搭配includePackageNames指定精确包名,就能只保留目标包下的测试类,自动排除所有子包。

代码示例:

import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage;
import static org.junit.platform.engine.discovery.PackageNameFilter.includePackageNames;

Launcher launcher = LauncherFactory.create();
launcher.execute(request()
    .selectors(selectPackage("com.somewhere"))
    .filters(includePackageNames("com.somewhere"))
    .build());

原理:selectPackage("com.somewhere")负责扫出该包及所有子包的测试类,includePackageNames("com.somewhere")则会过滤掉所有包名不等于com.somewhere的测试类,子包下的测试自然被排除在外。

方案二:自定义DiscoveryFilter(更灵活)

如果需要更复杂的匹配逻辑,可以自己实现DiscoveryFilter,判断测试类的包是否严格等于目标包:

import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage;

import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.discovery.DiscoveryFilter;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherFactory;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;

Launcher launcher = LauncherFactory.create();
launcher.execute(LauncherDiscoveryRequestBuilder.request()
    .selectors(selectPackage("com.somewhere"))
    .filters(new DiscoveryFilter<TestDescriptor>() {
        @Override
        public boolean apply(TestDescriptor descriptor) {
            // 仅保留包名严格为com.somewhere的测试类
            return descriptor.getSource()
                .filter(source -> source instanceof org.junit.platform.engine.support.descriptor.ClassSource)
                .map(source -> ((org.junit.platform.engine.support.descriptor.ClassSource) source).getClassName())
                .map(className -> className.substring(0, className.lastIndexOf('.')))
                .filter(packageName -> packageName.equals("com.somewhere"))
                .isPresent();
        }
    })
    .build());

为什么通配符方式没用?

你之前试的excludePackageNames("com.somewhere.*")无效,是因为JUnit的PackageNameFilter不支持*这类通配符语法。它的匹配逻辑是基于精确包名或层级关系的,要排除子包只能逐个指定精确名称,没法用通配符批量匹配。

关于TestExecutionListener的方案

如果上面的方案都不符合需求,用TestExecutionListener过滤确实可行,但这种方式是先扫描出所有测试类再过滤,不如在发现阶段用DiscoveryFilter高效——后者在扫描时就直接排除了不需要的测试,减少后续处理开销。

内容的提问来源于stack exchange,提问作者Ellen Spertus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:22:35