В моем предыдущем посте по тестированию я описал, как использовать TestContainers для обеспечения реалистичных сред тестирования для тестов базы данных. Этот комментарий выявил обратную сторону:
… как отмечалось выше, всегда есть какой-то недостаток. В этом случае затраты на запуск образа Docker и всего, что в нем содержится, увеличат общее время сборки.
В качестве напоминания, вот код, специфичный для TestContainer. Обратите внимание на экземпляр члена postgres
и Rule
JUnit, которое повторно инициализирует его для каждого метода.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
package be.objectify.tcexample.db; import be.objectify.tcexample.AbstractUserDaoTest; import be.objectify.tcexample.UserDao; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.testcontainers.containers.PostgreSQLContainer; import play.db.Database; public class JooqUserDaoTest extends AbstractUserDaoTest implements DbTestSupport, TestData { @Rule public PostgreSQLContainer postgres = new PostgreSQLContainer(); private Database database; @Before public void setup() throws Exception { // the database has all evolutions applied database = create(postgres); // load some test data loadTestData(database); } @After public void tearDown() { destroy(database); } @Override public UserDao dao() { return new JooqUserDao(database); } } |
Принимая во внимание, что значительное увеличение продолжительности теста является результатом времени запуска Docker-контейнера, мы можем вместо этого использовать JUnit ClassRule
чтобы запустить один контейнер и повторно использовать его для каждого теста в классе. Это означает, что вы больше не должны запускать эти тесты параллельно, но производительность значительно перевешивает параллелизацию тестов.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package be.objectify.tcexample.db; import be.objectify.tcexample.AbstractUserDaoTest; import be.objectify.tcexample.UserDao; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; import org.testcontainers.containers.PostgreSQLContainer; import play.db.Database; public class FasterJooqUserDaoTest extends AbstractUserDaoTest implements DbTestSupport, TestData { @ClassRule public static PostgreSQLContainer postgres = new PostgreSQLContainer(); private Database database; @Before public void setup() throws Exception { database = create(postgres); loadTestData(database); } @After public void tearDown() { destroy(database); } @Override public UserDao dao() { return new JooqUserDao(database); } } |
Количество сэкономленного времени зависит от количества методов тестирования в классе. У меня есть несколько тестовых классов, каждый из которых имеет более 30 тестов, и в этих случаях время выполнения падает с минут до секунд. Неплохо для смены пары строк кода.
Ссылка: | Повышение производительности тестирования с помощью TestContainers от нашего партнера по JCG Стива Чалонера в блоге Objectify . |