2011-08-09 3 views
3

Что мне нужно знать для написания модульных тестов, которые все получают доступ к базе данных (через JPA + Hibernate), чтобы они могли запускаться параллельно? Мы начали использовать функцию тестирования параллельного модуля mavens, и тест на тестирование завершился неудачно, что не происходит, когда они запускаются в одном потоке.Как написать тесты Junit против JPA, которые можно запускать параллельно?

Я приведу краткий пример того, как мы пишем наши тесты прямо сейчас. Мы установили EntityManager и другие классы в @Before, начните транзакцию и, наконец, вставьте тестовые данные, которые требуются всем нашим тестам в классе (в тестовом режиме создаются тестовые данные). @After тест выполняется, мы все отбрасываем, вызывая Transaction.rollback(); и null все переменные-члены. Мы запускаем все модульные тесты против hsqldb в памяти.

public class TestLogEntryDAO { 
    private EntityManager em; 
    private LogEntryDAO dao; 

    @Before 
    public void before() { 
     em = Persistence.createEntityManagerFactory("junit") 
      .createEntityManager(); 
     dao = new DAOFactory<LogEntryDAO>(LogEntryDAO.class).newInstance(em, 
      Mockito.mock(ILogger.class)); 

     em.getTransaction().begin(); 

     RecordDAO recordDAO = new DAOFactory<RecordDAO>(RecordDAO.class) 
      .newInstance(em, Mockito.mock(ILogger.class)); 
     recordDAO.setLogEntryDAO(dao); 
     createTestData(); // Is this ok? 
    } 

    @After 
    public void after() { 
     em.getTransaction().rollback(); 
     em = null; 
     dao = null; 
    } 

    @Test 
    public void testSomething() { 
     // ... 
    } 
} 

Заранее благодарен!

+1

Попробуйте сохранить каждый 'EntityManager' в' ThreadLocal', чтобы вы могли не переопределять экземпляры диспетчера сущностей, когда вы не хотите, чтобы они были переопределены. – Jeremy

ответ

1

Предостережение: Я не пытался это сделать. Это одно из моих нереализованных улучшений в моем текущем наборе тестов.


Параллельные испытания с участием JPA обречены на неудачу, если один или несколько из следующих условий:

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

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

Наборы данных, специфичные для тестирования, могут быть загружены из набора файлов (например, с использованием DbUnit) или из набора данных в памяти (подготовленного с использованием настраиваемой фабрики тестов), при этом каждый параллельный тест полагается на другой элемент в комплекте. Совершенно очевидно, что любые общие данные не должны подвергаться мутации, иначе вы закончите свертывание транзакций (если оптимистическая блокировка на месте), или ваши тесты просто потерпят неудачу.

Кроме того, данные, которые могут быть изменены через тесты, не должны делиться между тестами. Это легко достижимо, если вы используете разные значения для каждого теста. Вам нужно будет убедиться, что ваши тесты будут утверждать для этих значений или эквивалентное свойство инварианта, которое является специфичным для теста. Фиксирование данных может выполняться с использованием нитей-идентификаторов.

Чтобы предоставить пример выше, если вы используете тесты, которые будут сохраняться в базе данных A (с атрибутами A1 и A2), тогда проверка T1 должна сохраняться в экземпляре A со значениями A1 = x1 и A2 = y1 и параллельный тест T2, должен сохраняться другой объект A со значениями A1 = x2 и A2 = y2. Это предполагает, что другие тесты, которые выполняются параллельно, будут изменять значение как A1, так и A2. Если ваши тесты имеют свойство не мутировать A1, тогда все такие значения A1 могут быть постоянными в тестах.

Смежные вопросы