如何在启用并行运行时配置测试场景优先启动以缩短总耗时?
如何在并行测试中优先执行长耗时用例
针对你提到的场景(10个并发槽位、2个20分钟用例+10个10分钟用例),让长耗时用例优先启动确实能把总耗时从30分钟压缩到20分钟,以下是主流测试框架的具体实现方案:
JUnit 5 实现
通过自定义测试排序器给长耗时用例设置优先级:
- 定义标记长耗时用例的注解:
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LongRunning {}
- 实现自定义排序器,让带
@LongRunning的用例排在前面:
import org.junit.jupiter.api.MethodDescriptor; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.MethodOrdererContext; public class PriorityOrderer implements MethodOrderer { @Override public void orderMethods(MethodOrdererContext context) { context.getMethodDescriptors().sort((md1, md2) -> { boolean isLong1 = md1.getMethod().isAnnotationPresent(LongRunning.class); boolean isLong2 = md2.getMethod().isAnnotationPresent(LongRunning.class); // 带注解的用例优先排序 return Boolean.compare(isLong2, isLong1); }); } }
- 在测试类上指定排序器,并标记长耗时用例:
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; @TestMethodOrder(PriorityOrderer.class) public class TestSuite { @LongRunning @Test void longTest1() throws InterruptedException { Thread.sleep(1200000); // 模拟20分钟耗时 } @LongRunning @Test void longTest2() throws InterruptedException { Thread.sleep(1200000); } @Test void shortTest1() throws InterruptedException { Thread.sleep(600000); // 模拟10分钟耗时 } // 剩余9个短耗时用例同理 }
- 在
junit-platform.properties中开启并行配置:
junit.jupiter.execution.parallel.enabled = true junit.jupiter.execution.parallel.config.strategy = fixed junit.jupiter.execution.parallel.config.fixed.parallelism = 10
Pytest 实现
借助pytest-ordering标记优先级,配合pytest-xdist实现并行:
- 安装依赖:
pip install pytest-ordering pytest-xdist
- 给测试用例标记执行顺序,长耗时用例标记更小的order值:
import pytest import time @pytest.mark.order(1) def test_long_running_1(): time.sleep(1200) # 模拟20分钟耗时 @pytest.mark.order(2) def test_long_running_2(): time.sleep(1200) @pytest.mark.order(3) def test_short_running_1(): time.sleep(600) # 模拟10分钟耗时 # 剩余9个短耗时用例标记order从4到12
- 启动并行测试:
pytest -n 10
pytest-xdist会优先调度order值更小的用例,确保长耗时用例先占据并发槽位。
TestNG 实现
利用TestNG的priority属性控制执行顺序,同时配置并行:
- 在测试方法中设置优先级,数值越小优先级越高:
import org.testng.annotations.Test; public class ParallelTests { @Test(priority = 1) public void longTest1() throws InterruptedException { Thread.sleep(1200000); } @Test(priority = 1) public void longTest2() throws InterruptedException { Thread.sleep(1200000); } @Test(priority = 2) public void shortTest1() throws InterruptedException { Thread.sleep(600000); } // 剩余9个短耗时用例设置priority=2 }
- 在
testng.xml中配置并行参数:
<suite name="ParallelTestSuite" parallel="methods" thread-count="10"> <test name="AllTests"> <classes> <class name="com.example.ParallelTests"/> </classes> </test> </suite>
TestNG会优先分配线程给priority值小的方法,保证长耗时用例先启动。
无框架依赖的通用方案
如果你的测试运行器不支持内置排序,可以用脚本提前生成排序后的测试用例列表,再启动并行测试。比如用Python脚本生成pytest执行清单:
import os # 定义长、短耗时测试用例路径 long_tests = ["tests/test_long_1.py", "tests/test_long_2.py"] short_tests = [f"tests/test_short_{i}.py" for i in range(1, 11)] # 合并列表,长耗时用例在前 test_execution_order = long_tests + short_tests # 构建并行测试命令并执行 cmd = f"pytest -n 10 {' '.join(test_execution_order)}" os.system(cmd)
内容的提问来源于stack exchange,提问作者karthik inamanamelluri
相关产品推荐
相关产品推荐

