# Многопоточность

Довольно часто есть необходимость запускть тесты в несколько потоков для снижения времени выполнения тестов.

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();
  }
}
```

Свойства:

* threadPoolSize определяет максимальное количество потоков используемое для тестов;
* singleThreaded если установлен в true все тесты будут запущены в одном потоке;
* invocationCount определяет количество запусков теста;
* invocationTimeOut определяет общее время всех запусков теста, после которого тест считается провалившемся.

Первый тест будет время от времени проваливаться с 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://comaqa.gitbook.io/java-automation/yunit-testirovanie/junit-vs-testng.-primery-testov/mnogopotochnost.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
