JUnit: общий доступ к ресурсу между тестовыми классами, использующими одно и то же расширение - PullRequest
0 голосов
/ 26 мая 2020

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

Реализация : все классы интеграционных тестов помечены @ExtendsWith(DatabaseTestExt::class). DatabaseTestExt реализует BeforeEachCallback (очищать базу данных перед каждым тестом) и BeforeAllCallback. В этом обратном вызове я создаю и помещаю ресурс, который реализует ExtensionContext.Store.CloseableResource (потому что мне нужно закрыть соединение с базой данных и остановить контекст DI до завершения выполнения тестов). Аналогичный logi c для сквозных тестов: начало регистрации, запуск DI, запуск веб-приложения.

Вот краткая версия класса расширения. Полный код можно найти здесь .

class DatabaseTestExt : BeforeAllCallback, BeforeEachCallback, KoinComponent {

    override fun beforeAll(context: ExtensionContext) {
        context.getStore(ExtensionContext.Namespace.GLOBAL).getOrComputeIfAbsent("db") {
            CloseableDatabase()
        }
    }

    class CloseableDatabase : ExtensionContext.Store.CloseableResource {
        init {
            // initialize logging, DI and database logic
        }

        override fun close() {
            // stop DI and database
        }
    }

    override fun beforeEach(context: ExtensionContext) {
        // clean up database
    }
}

Проблема : При такой реализации JUnit создает и закрывает ресурс базы данных в каждом тестовом классе. Я хочу, чтобы он разделял ресурсы между всеми тестами, помеченными @ExtendsWith(DatabaseTestExt::class), потому что создание экземпляра ORM не дешево с точки зрения времени.

Я думал об использовании context.root.getStore() вместо context.getStore(), но тогда это выглядит так жизненный цикл контекста заканчивается в конце всего набора тестов, и это не очень хорошо для моего случая, потому что инициализация DI из DatabaseTestExt конфликтует с EndToEndTestExt.

Итак, можно ли разделить ресурс между тестовыми классами который использует такое же расширение JUnit в JUnit 5? Если нет, не могли бы вы предложить некоторые тестовые фреймворки, которые поддерживают такие logi c?

Спасибо.

PS: Я думал разместить это на sqa.stackexchange.com, но решил опубликовать это сначала здесь.

UPD: я нашел обходной путь для моей спецификации c case :

  • сначала инициализировать соединение с базой данных с ORM beforeAll() вызовите и поместите эти ресурсы в root хранилище контекста.
  • на каждый beforeAll() вызов в расширении DI start (это дешево), извлеките из хранилища сохраненное ранее соединение и поместите его в DI.
  • при каждом вызове afterAll() в расширении уничтожает контекст DI, но не трогает соединение с базой данных.

Таким образом я добиваюсь совместного использования ресурса между несколькими тестовыми классами. Однако проблема из заголовка остается без ответа = /

1 Ответ

0 голосов
/ 26 мая 2020

Чтобы достичь желаемого, вы можете использовать TestContainers и поместить в него docker своей БД.

TestContainers имеет хорошую интеграцию с JUnit5.

Есть пример использования Shared контейнер https://www.testcontainers.org/test_framework_integration/junit_5/#shared -контейнеры

...