参数化测试本身是不支持多线程测试的,对于一些测试结果没有依赖的测试来说,单线程的测试执行效率相当低下。
通过在测试用例中添加线程租,开启多个线程同时执行测试用例,并且在线程租中线程都执行完的时候结束测试,来达到优化测试效率的目的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| package org.huyp;
import java.util.Arrays; import java.util.Collection; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor;
import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class) public class ThreadParameterizeTest {
private static ThreadPoolExecutor POOL; private final static String[][] params = { { "A", "A" }, { "B", "B" }, { "C", "C" } }; private String expected; private String target;
@BeforeClass public static void beforeClass() { System.out.println("---- start test ----"); POOL = (ThreadPoolExecutor) Executors.newFixedThreadPool(params.length); }
@AfterClass public static void afterClass() { try { while (POOL.getActiveCount() > 0) { Thread.sleep(1000); } } catch (InterruptedException e) { } finally { POOL.shutdown(); System.out.println("---- end test ----"); } }
public ThreadParameterizeTest(String expected, String target) { this.expected = expected; this.target = target; }
@Parameters public static Collection<String[]> initParams() { return Arrays.asList(params); }
@Test public void test() { POOL.submit(new Runnable() { @Override public void run() { System.out.println(expected + ": " + target); Assert.assertEquals(expected, target); } }); } }
|
注意
这个类与普通参数化测试类多了几个不同的地方:
在类里面多了一个静态的线程池;
在@BeforeClass
里面初始化了这个线程池;
在@AfterClass
里面监听线程池活动的线程数:
1 2 3
| while (POOL.getActiveCount() > 0) { Thread.sleep(1000); }
|
在没有活动的线程时关闭线程池:
在@Test
方法里面创建线程,并用线程池进行管理,而具体的逻辑处理在run()
方法里面。