Довольно часто есть необходимость запускть тесты в несколько потоков для снижения времени выполнения тестов.
TestNG
public class ConcurrencyTest extends Assert {
private Map<String, String> data;
@BeforeClass
void setUp() throws Exception {
data = new HashMap<String, String>();
}
@AfterClass
void tearDown() throws Exception {
data = null;
}
@Test(threadPoolSize = 30, invocationCount = 100, invocationTimeOut = 10000)
public void testMapOperations() throws Exception {
data.put("1", "111");
data.put("2", "111");
data.put("3", "111");
data.put("4", "111");
data.put("5", "111");
data.put("6", "111");
data.put("7", "111");
for (Map.Entry<String, String> entry : data.entrySet()) {
System.out.println(entry);
}
data.clear();
}
@Test(singleThreaded = true, invocationCount = 100, invocationTimeOut = 10000)
public void testMapOperationsSafe() throws Exception {
data.put("1", "111");
data.put("2", "111");
data.put("3", "111");
data.put("4", "111");
data.put("5", "111");
data.put("6", "111");
data.put("7", "111");
for (Map.Entry<String, String> entry : data.entrySet()) {
System.out.println(entry);
}
data.clear();
}
}
Свойства:
Первый тест будет время от времени проваливаться с ConcurrentModificationException, так как будет запускаться из разных потоков, второй — нет, так как все тесты будут запущены последовательно из одного потока.
Еще можно установить параметр parallel у дата провайдера в true, тогда тесты для каждого набора данных будут запущены паралельно, в отдельном потоке:
public class ConcurrencyTest extends Assert {
// some staff here
@DataProvider(parallel = true)
public Object[][] concurrencyData() {
return new Object[][] {
{"1", "2"},
{"3", "4"},
{"5", "6"},
{"7", "8"},
{"9", "10"},
{"11", "12"},
{"13", "14"},
{"15", "16"},
{"17", "18"},
{"19", "20"},
};
}
@Test(dataProvider = "concurrencyData")
public void testParallelData(String first, String second) {
final Thread thread = Thread.currentThread();
System.out.printf("#%d %s: %s : %s", thread.getId(), thread.getName(), first, second);
System.out.println();
}
}
JUnit В JUnit сконфигурировать параллельный запуск тестов можно с помощью ParallelComputer класса:
public class ParallelComputerTest {
@Test
public void test() {
Class[] cls={ParallelTest1.class,ParallelTest2.class };
//Parallel among classes
JUnitCore.runClasses(ParallelComputer.classes(), cls);
//Parallel among methods in a class
JUnitCore.runClasses(ParallelComputer.methods(), cls);
//Parallel all methods in all classes
JUnitCore.runClasses(new ParallelComputer(true, true), cls);
}
public static class ParallelTest1 {
@Test
public void a(){}
@Test
public void b(){}
}
public static class ParallelTest2 {
@Test
public void a(){}
@Test
public void b(){}
}
}
Параллельный запуск тестов - это очень полезная опция. Однако чаще всего лучще ее использовать из билд инструмента.
Задание 1. Для TestNG напишите тест с ожидаением внутри 3 сек, сконфигурируйте на запуск 3 раза. Попробуйте запустить его в одном потоке, а затем в 3. Сраните время выполнения.
Задание 2. Сделайте тоже самое для JUnit.