Когда строить структуру БД при тестировании с 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/). Данные, которые вы создаете в транзакции, удаляются после завершения тестирования.

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

Другие вопросы по тегам