CelestaUnit

Обычно автоматическое тестирование систем, редактирующих данные, представляет определённые сложности и требует использования специальных приёмов (например, развёртывание базы данных в контейнере). Такие тесты обычно выполняются медленно и разработчики избегают их.

В Celesta тестирование методов, редактирующих данные, осуществляется на уровне очень быстро выполняющихся модульных тестов, для чего разработано расширение JUnit5. Модульные тесты выполняются на встроенной непосредственно в Celesta базе H2, работающей в режиме in-memory. Эта база не требует установки, запускается моментально и исчезает после завершения тестов.

За счёт того, что Celesta гарантирует одинаковое поведение классов доступа к данным на всех поддерживаемых типах СУБД (тесты самой Celesta включают в себя прогон сценариев на реальных СУБД), выполнение модульных тестов под H2 является достаточным условием корректности метода и его работоспособности в production базе данных.

Чтобы воспользоваться данной функциональностью, необходимо добавить модуль celesta-unit Maven-зависимости проекта:

<dependency>
    <groupId>ru.curs</groupId>
    <artifactId>celesta-unit</artifactId>
    <version>...</version>
    <scope>test</scope>
</dependency>

Также в тестовый scope проекта необходимо добавить зависимости JUnit5 (примеры см. в документации Junit5).

1. Пример пользования

Наиболее простым способом использования является добавление аннотации @CelestaTest к тестовому классу и использование параметров с типом CallContext в тестах:

/*Аннотация CelestaTest подключает JUnit5 extension class ru.curs.celestaunit.CelestaUnitExtension,
обеспечивающий подстановку CallContext-объектов в параметры тестов.*/
@CelestaTest
public class DocumentServiceTest {

    /*Сервис может быть создан как напрямую,
    так и используя DI */

    DocumentService srv = new DocumentService();

    @BeforeEach
    void setUp(CallContext context) {
        //Здесь можно наполнить базу данными, нужными для каждого теста
    }


    @Test
    /*Параметр CallContext будет подставлен автоматически,
    на основе временной базы данных H2*/
    void documentIsPutToDb(CallContext context) throws ParseException {
        /*Вызываем сервис*/
        srv.postOrder(context, ...);
        /*Проверяем, что данные попали в базу*/
        OrderHeaderCursor header = new OrderHeaderCursor(context);
        header.tryFirst();
        assertEquals("no1", header.getId());
    }
}

Таким образом, каждый из тестов может получать в качестве параметра активный CallContext. Этот контекст формируется на основе базы данных H2, в которой развёрнута Celesta score, и может быть использован для создания курсоров. Если используются @BeforeEach-методы, вызываемые перед каждым тестом, то в них будет передаваться тот же CallContext, что и в тестовый метод.

2. Изменение настроек CelestaUnit по умолчанию

CelestaUnit работает со следующими умолчаниями:

  • Score path: src/main/resources/score.

  • Проверка ссылочной целостности (по Foreign keys) по умолчанию включена.

  • Очистка таблиц перед каждым тестом по умолчанию включена.

  • Сброс значений sequence-ов перед каждым тестом по умолчанию включен.

Изменить умолчания можно, воспользовавшись параметрами аннотации @CelestaTest:

@CelestaTest(scorePath = DocumentServiceTest.SCORE_PATH,
    referentialIntegrity = true,
    truncateTables = false,
    resetSequences = false)
public class DocumentServiceTest {
    public static final String SCORE_PATH = "src/test/resources/score";

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