Maven3.8中-T线程数与forkCount在suitesAndClasses模式的并行规则
多模块Maven下
mvn test -T 5与指定Surefire配置的并行执行逻辑 当前使用的Surefire插件配置如下:
<configuration> <forkCount>2</forkCount> <reuseForks>true</reuseForks> <perCoreThreadCount>false</perCoreThreadCount> <parallel>suitesAndClasses</parallel> </configuration>
执行命令为mvn test -T 5,对应版本为Maven 3.8.4、Surefire 3.0.0-M6,整体并行逻辑分为完全独立、互不感知的两层调度:
- 第一层是Maven核心的模块级并行:
-T 5表示最多同时调度5个无依赖关系的模块执行构建流程(含test阶段) - 第二层是每个模块独立启动的Surefire插件实例内部的测试并行,每个实例的配置互不影响,不会跨模块共用fork进程
无测试套件场景的执行表现
你猜测的「fork1运行模块1的5个测试类、fork2同时运行模块2的5个测试类」不会是固定调度结果,实际逻辑是:
- 只要模块间无依赖关系,就会被Maven并行拉起test阶段,每个被拉起的模块都会独立启动2个固定的Surefire fork进程(因为
perCoreThreadCount=false,fork数固定为2,不随CPU核心数调整) - 无测试套件时,
parallel=suitesAndClasses配置会退化为测试类级并行,每个模块的2个fork会共同消费当前模块的所有测试类,fork内部多线程并行执行分配到的测试类 - 不存在跨模块调度测试类的逻辑:如果同时有2个模块被Maven调度执行,总共有4个测试fork在运行;如果同时有3个模块被调度,总fork数会达到6个,
-T 5只控制模块并发数,不限制fork总数量 reuseForks=true会让fork执行完分配的测试类后不销毁,持续等待新任务直到当前模块所有测试跑完,不会频繁创建销毁进程
存在测试套件场景的执行表现
parallel=suitesAndClasses的语义是套件、测试类两个层级同时并行,调度规则如下:
- Surefire启动后会先扫描当前模块所有测试套件、未被任何套件引用的独立测试类,把两类对象统一作为顶层调度单元
- 2个fork会优先抢占分配顶层调度单元:
- 测试套件被分配到某个fork后,会在fork内部拉起多线程,并行执行套件下绑定的所有测试类。你猜测的「fork1运行模块1的suite1、内部并行跑5个测试类,fork2运行模块2的套件、内部并行跑对应测试类」是符合实际表现的,只要两个模块同时被Maven调度、两个套件同时被分配到对应fork就会出现这个情况
- 未归属任何套件的独立测试类,和测试套件是同优先级的调度单元,会在任务队列中和套件一起抢占空闲fork资源,被分配到fork后同样并行执行,不会被特殊处理,也不会延后到所有套件跑完再执行
- 举个实际调度例子:某模块有1个绑定3个测试类的suite1,外加2个独立测试类,可能出现的调度是fork1拿到suite1,内部并行跑3个绑定的测试类;fork2先拿到2个独立测试类并行执行,等fork2跑完独立类后如果fork1还没跑完suite1,会等待fork1释放任务,再分配后续待执行的单元。
内容的提问来源于stack exchange,提问作者tuk
相关产品推荐
相关产品推荐

