Бег
package com.thron.qa.tests
import org.scalatest.{FunSuite, ParallelTestExecution}
import org.scalatest.concurrent.Eventually
class ParallelRuntimeTest extends FunSuite with Eventually with ParallelTestExecution{
Vector.range(0,10).foreach(iteration => {
test ("test number n " + iteration.toString) {
succeed
}
})
}
я получаю создание теста во время выполнения: итерация по вектору строится на тестах, и каждый отдельный тест имеет статус успеха, как вы можете видеть в Идее

Теперь я хочу распараллелить эти тесты
обычно я использую .par для распараллеливания операций, поэтому код становится
Vector.range(0,10).par.foreach(iteration => {
test ("test number n " + iteration.toString) {
succeed
}
})
но в этом случае я получаю эту ошибку:
Исключение или ошибка привели к прерыванию выполнения: два потока попытались изменить внутренние данные FunSuite, которые должны быть изменены только потоком, создающим объект. Вероятно, это означает, что подкласс позволил ссылке this уйти во время построения, и какой-то другой поток попытался вызвать методы "testsFor" или "test" для объекта до того, как первый поток завершил свое построение. java.util.ConcurrentModificationException: два потока попытались изменить внутренние данные FunSuite, которые должны быть изменены только потоком, создающим объект. Вероятно, это означает, что подкласс позволил ссылке this уйти во время построения, и какой-то другой поток попытался вызвать методы "testsFor" или "test" для объекта до того, как первый поток завершил свое построение.
как создать тест во время выполнения и запустить его параллельно?
Благодарность
Ответ 1 · рейтинг 3 · Andrey Tyukin
Команда test не запускает никаких тестов. Он просто регистрирует тестовый пример, прикрепляя к нему строковое имя. Это не требует ресурсов и практически мгновенно. Поэтому нет необходимости регистрировать тестовые случаи параллельно. Как показывает ваше сообщение об ошибке, в любом случае невозможно зарегистрировать их параллельно.
Создавайте тесты последовательно, они будут запускаться параллельно автоматически:
import org.scalatest.{FunSuite, ParallelTestExecution}
import org.scalatest.concurrent.Eventually
class ParallelRuntimeTest
extends FunSuite
with Eventually
with ParallelTestExecution {
for (i <- (0 to 59)) {
test ("test number n " + i) {
Thread.sleep(1000)
succeed
}
}
}
Если вы протестируете его, вы заметите, что это занимает примерно 15 секунд вместо минуты (я думаю, это потому, что количество потоков по умолчанию, используемых для тестов, равно четырем, поэтому 60/4 = 15).
Ответ 2 · рейтинг 2 · KZapagol
Как упомянул @Andrey Tyukin, по умолчанию sbt выполняет все задачи параллельно и в той же JVM, что и сам sbt. Поскольку каждый тест сопоставляется с задачей, по умолчанию тесты также выполняются параллельно.
Мы можем отключить параллельное выполнение тестов для многопроектных сборок, как показано ниже.
parallelExecution in Test := false,
parallelExecution in IntegrationTest := false
Похоже, есть проблема с использованием ParallelTestExecution и "sbt test" -scalaTest 3.0.x (https://github.com/scalatest/scalest/issues/898). Однако обходной путь для этой проблемы находится в Overriding Distributor.
class Example extends FunSpec with ParallelTestExecution with StressTest {
describe("Example") {
for (i <- 1 to poolSize) {
it(s"test ${i} should run in parallel") {
info(s"example ${i} start")
Thread.sleep(5000)
info(s"example ${i} end")
}
}
}
}