Когда строить структуру БД при тестировании с arquilian?
Я начинаю с интеграционных тестов и Arquilian. Я очень доволен инструментом. У меня почти все установлено, кроме одного:
Моя структура базы данных, конечно, стабильна во всем наборе тестов, поэтому, чтобы уменьшить время, необходимое для запуска теста, я хотел бы построить базу данных как можно реже, и каждый тест должен заполнить базу данных, работать на это и почисти.
Я предполагаю, что построение базы данных в начале набора тестов и позволить всем тестам заполнять / стирать базу данных может быть немного рискованным: если один тест не очень хорошо очищает, я могу получить невоспроизводимые тесты.
Но, возможно, создание его в каждом тестовом классе - это хороший подход, в случае проблемного теста его будет легче обнаружить, поскольку область действия меньше.
Я пытался сделать это, используя @BeforeClass и @AfterClass, но они выполняются на клиенте и также являются статическими, поэтому у меня нет ресурсов, готовых для использования для подключения к базе данных.
Правильный ли мой подход к созданию структуры БД перед каждым тестом? Какую фазу жизненного цикла arquilian можно использовать для создания базы данных?
2 ответа
Вам не нужно делать это самостоятельно, по крайней мере, если вы используете JPA 2.1 в своем проекте. Рассмотрим следующий тестовый класс:
@RunWith(Arquillian.class)
public class MyTest {
@Deployment
public static WebArchive createDeployment() throws Exception {
return ShrinkWrap.create(WebArchive.class)
.addAsResource("META-INF/init-schema.sql") // create table ...
.addAsResource("META-INF/testdata.sql") // insert into ...
.addAsResource("META-INF/drop-schema.sql") // drop table ...
.addAsResource("META-INF/persistence.xml");
// and maybe more ...
}
}
createDeployment()
Метод вызывается для создания файла WAR, который должен быть развернут на вашем сервере приложений.
Ваш persistence.xml
должен ссылаться на эти сценарии SQL:
[...]
<persistence-unit [...]>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
<property name="javax.persistence.schema-generation.create-source" value="script" />
<property name="javax.persistence.schema-generation.create-script-source" value="META-INF/init-schema.sql" />
<property name="javax.persistence.schema-generation.drop-source" value="script" />
<property name="javax.persistence.schema-generation.drop-script-source" value="META-INF/drop-schema.sql" />
<property name="javax.persistence.sql-load-script-source" value="META-INF/testdata.sql" />
</properties>
</persistence-unit>
Таким образом, база данных настраивается автоматически при развертывании test-WAR. Убедитесь, что файлы SQL находятся в папке "META-INF" (если вы используете Maven, она находится в "src/test/resources/META-INF").
Если вы хотите контролировать порядок выполнения ваших тестовых методов, вы можете использовать @InSequence
аннотация, например:
public class MyTest {
[...]
private @Inject EntityManager entityManager
@Test @InSequence(0)
public void shouldHaveFoo() {
Foo foo = entityManager.find(Foo.class, Long.valueOf(1));
assertNotNull(foo);
}
@Test @InSequence(1)
public void shouldHaveBar() {
Bar bar = entityManager.find(Bar.class, Long.valueOf(99));
assertNotNull(bar);
}
}
Используйте расширение Transaction для Arqullian, которое работает довольно хорошо ( http://arquillian.org/modules/transaction-extension/). Данные, которые вы создаете в транзакции, удаляются после завершения тестирования.
Единственная проблема заключается в том, что данные, которые находятся в БД, могут повлиять на ваше тестирование. Решение - проверить пустую БД. Он может быть встроенным, реальным или подходом, который описан выше. Но расширение правильно управляет всеми транзакциями, и вам не нужно ни о чем заботиться.