Как выполнить модульный тест параллелизма?

Негласно, lexical_cast делает это:

std::stringstream str;
str << myint;
std::string result;
str >> result;

, Если Вы не хотите "притягивать" повышение для этого, затем с помощью вышеупомянутого, хорошее решение.

44
задан stivlo 31 October 2011 в 12:23
поделиться

10 ответов

К сожалению, я не верю, что вы можете окончательно доказать, что ваш код является потокобезопасным, используя тестирование во время выполнения. Вы можете бросить столько потоков, сколько захотите, и это может / не может пройти в зависимости от расписания.

Возможно, вам стоит взглянуть на некоторые инструменты статического анализа, такие как PMD , которые могут определить, как вы используете синхронизацию, и выявить проблемы использования.

21
ответ дан 26 November 2019 в 22:14
поделиться

В вашем примере метод postMessage () синхронизирован , поэтому вы фактически не увидите каких-либо эффектов параллелизма в пределах одной виртуальной машины, но вы сможете оценить производительность синхронизированной версии.

Вам нужно будет запустить несколько копий тестовой программы одновременно на разных виртуальных машинах. Вы можете использовать

. Если вы не можете заставить свою тестовую среду сделать это, вы можете запустить несколько виртуальных машин самостоятельно. Работа с конструктором процессов - это боль с путями и прочим, но вот общий набросок:

Process running[] = new Process[5];
for (int i = 0; i < 5; i++) {
 ProcessBuilder b = new ProcessBuilder("java -cp " + getCP() + " MyTestRunner");
 running[i] = b.start();
}

for(int i = 0; i < 5; i++) {
 running[i].waitFor();
}

Я обычно делаю что-то подобное для простых многопоточных тестов, как и другие, тестирование не является доказательством правильности, но обычно встряхивает устранять глупые ошибки на практике. Это помогает проводить тестирование в течение длительного времени в самых разных условиях - иногда ошибки параллелизма требуют времени, чтобы проявиться в тесте.

public void testMesageBoard() {
 final MessageBoard b = new MessageBoard();

 int n = 5;
 Thread T[] = new Thread[n];
 for (int i = 0; i < n; i++) {
  T[i] = new Thread(new Runnable() {
   public void run() {
    for (int j = 0; j < maxIterations; j++) {
      Thread.sleep( random.nextInt(50) );
      b.postMessage(generateMessage(j));
      verifyContent(j); // put some assertions here
    }
   }
  });

  PerfTimer.start();
  for (Thread t : T) {
   t.start();
  }

  for (Thread t : T) {
   t.join();
  }
  PerfTimer.stop();
  log("took: " + PerfTimer.elapsed());
 }
}**strong text**
1
ответ дан 26 November 2019 в 22:14
поделиться

TestNG поддерживает тестирование параллелизма в Java. В этой статье описывается, как его можно использовать, и есть документация на сайте testng.

Не уверен, можно ли выполнить тот же тестовый прогон одновременно

0
ответ дан 26 November 2019 в 22:14
поделиться

Я бы рекомендовал использовать MultithreadedTC - Написано самим мастером параллелизма Биллом Пью Натом Айевах ). тестирование одновременных приложений. Это имеет метроном, который используется для обеспечить точный контроль над последовательностью действий в нескольких потоках.

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

16
ответ дан 26 November 2019 в 22:14
поделиться

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

Однако вы можете написать специализированное средство запуска тестов, которое порождает несколько параллельных потоков, а затем вызывает ваши аннотированные методы @Test.

9
ответ дан 26 November 2019 в 22:14
поделиться

В .NET есть такие инструменты, как TypeMock Racer или Microsoft CHESS , которые разработаны специально для параллельного тестирования модулей. Эти инструменты не только находят ошибки многопоточности, такие как взаимоблокировки, но также предоставляют набор чередований потоков, воспроизводящих ошибки.

Я полагаю, что в мире Java есть что-то подобное.

7
ответ дан 26 November 2019 в 22:14
поделиться

Тестирование ошибок параллелизма невозможно; вам не просто нужно проверять пары ввода / вывода, но вы должны проверять состояние в ситуациях, которые могут или не могут возникнуть во время ваших тестов. К сожалению, JUnit не оборудован для этого.

1
ответ дан 26 November 2019 в 22:14
поделиться

Лучшим подходом здесь является использование системных тестов, чтобы взорвать ваш код запросами, чтобы увидеть, не упадет ли он. Затем используйте модульный тест, чтобы проверить логическую правильность. Я бы подошел к этому путем создания прокси-сервера для асинхронного вызова и синхронного выполнения его при тестировании.

Однако, если вы хотите сделать это на уровне, отличном от полной установки и полной среды, вы можете сделать это в junit создав свой объект в отдельном потоке, а затем создайте множество потоков, которые запускают запросы к вашему объекту и блокируют основной поток до его завершения. При таком подходе тесты могут периодически выходить из строя, если вы не понимаете его правильно.

0
ответ дан 26 November 2019 в 22:14
поделиться

Попробуйте найти ActiveTestSuite, который поставляется с JUnit. Он может одновременно запускать несколько тестов JUnit:

public static Test suite()
{
    TestSuite suite = new ActiveTestSuite();
    suite.addTestSuite(PostMessageTest.class);
    suite.addTestSuite(PostMessageTest.class);
    suite.addTestSuite(PostMessageTest.class);
    suite.addTestSuite(PostMessageTest.class);
    suite.addTestSuite(PostMessageTest.class);
    return suite;
}

Вышеупомянутый тестовый класс JUnit будет запущен 5 раз в параллельном режиме. Если вам нужны вариации в тестах параллелизма, просто создайте другой класс.

2
ответ дан 26 November 2019 в 22:14
поделиться

Вы можете использовать библиотеку tempus-fugit для параллельного и многократного запуска тестовых методов для имитации среды типа нагрузочного тестирования. Хотя предыдущий комментарий указывает на то, что метод post синхронизирован и поэтому защищен, могут быть задействованы связанные члены или методы, которые сами по себе не защищены, поэтому возможно, что тест типа load / soak может поймать их. Я бы посоветовал вам настроить довольно грубый / сквозной тест, чтобы дать вам лучший шанс обнаружить любые лазейки.

См. раздел интеграции JUnit в документации.

BTW, я разработчик в указанном проекте :)

1
ответ дан 26 November 2019 в 22:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: