Отключить параллельные тесты JUnit — проблема с классом BeforeClass, AfterClass

#java #junit

#java #junit

Вопрос:

Я получил два тестовых класса: A и B. Основная проблема заключается в том, что JUnit вводит @BeforeClass из B перед выполнением @AfterClass из A.

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

Пример:

 public class A {
 @AfterClass
 public static void clearDb(){
  try{
  ...
  EntityManager em = ..
  em.getTransaction().begin();
  em.createQuery("DELETE FROM ClassName").executeUpdate();
  em.getTransaction().commit();
  }catch(...){...}
 }
 @Test
 public test(){
 ...
 }
}

public class B {
 @BeforeClass
 public static void clearDb(){
  try{
  ...
  EntityManager em = ..
  em.getTransaction().begin();
  em.clear();
  em.persist(...)
  em.getTransaction().commit();
  }catch(...){...}
 }
 @Test
 public test(){
 ...
 }
}
  

Подключение: jdbc: h2: mem:test; DB_CLOSE_DELAY= -1

Мой вопрос: есть ли способ заставить JUnit обрабатывать как единый поток или подождать, пока другой класс действительно очистит свой материал.

Комментарии:

1. Вероятно, одним из способов было бы иметь внешний флаг, который @AfterClass метод изменяет после того, как он сделал все необходимое, и @BeforeClass метод должен ждать, пока этот флаг не будет установлен.

2. Распараллеливание основано на том, как вы выполняете свои тесты. Используете ли вы Maven (безошибочно) или что-то еще?

3. Я думаю, что по умолчанию JUnit запускает тесты в одном потоке. Какой бегун вы используете?

4. Я использую простой JUnit в проекте maven. Если я запускаю его с помощью maven test, все в порядке, но средство проверки запускает его как тесты JUnit…

Ответ №1:

Вы изучали использование аннотации правила JUnit?

Вы можете создать абстрактный класс, который обрабатывает состояние базы данных

 import org.junit.Rule;
import org.junit.rules.ExternalResource;

public abstract class AbstractTest {

    public Object dbConnection;

    @Rule
    public ExternalResource resource = new ExternalResource() {
        @Override
        protected void before() {
            System.out.println("Setting up resource");
            // set up dbConnection
        }
        @Override
        protected void after() {
            System.out.println("Cleaning up resource");
            // clean db dbConnection
        }
   };

   public Object getDbConnection() {
        return dbConnection;
   }
 }
  

Тогда ваши тесты расширят ваш абстрактный класс

 import org.junit.Assert;
import org.junit.Test;

public class SampleTest extends AbstractTest {

    @Test
    public void firstTest() {

        Object connection = getDbConnection();
        // interact with db using the provided connection
        System.out.println("do work 1");
    }

    @Test
    public void secondTest() {

        Object connection = getDbConnection();
        System.out.println("do work 2");
    }
}
  

Комментарии:

1. Я позабочусь об этом решении, но, я думаю, вы неправильно поняли мой вопрос. Проблема в том, что у меня разные классы тестов, а не две разные функции, известные как @ Tests. Как я вижу, вы нашли решение другой проблемы. Основная проблема заключается в том, что многопоточный запуск запускает @ BeforeClass второго теста до того, как @ AfterClass первого мог быть завершен.

Ответ №2:

Старая проблема, но если кому-то это нужно:

Как мне сообщили из многих мест, невозможно гарантировать более позднее.@BeforeClass и ранее.Порядок методов @AfterClass. Окончательное решение заключалось в том, что я использовал разные базы данных H2.