Spring Boot Test horror
-
Upload
- -
Category
Technology
-
view
80 -
download
1
Transcript of Spring Boot Test horror
В программеТестирование живого приложения● Старые подходы
○ @ContextConfiguration○ @ContextHierarchy && @DirtiesContext○ @ActiveProfiles
● Что нового нам приготовил Spring Boot?○ @SpringBootTest○ @TestConfiguration○ @MockBean && @SpyBean && @*Beans○ @DataJpaTest○ @WebMvcTest
● Кэширование spring контекстов● Шкала тестов
ДаноЧат поддержки разработчиков
assistant
yegor256-assistant
jbaruch-assistant
Queue
мыweb
rest
rest
rest
Default AnswersDatabase
ДаноЧат поддержки разработчиков
assistant
yegor256-assistant
jbaruch-assistant
Queue
мыweb
rest
rest
rest
Default AnswersDatabase
А давайте тестировать
У кого спросить? [yegor256/jbaruch]
router
yegor256-assistant
jbaruch-assistant
Default AnswersDatabase
Yegor256 Resolver$tokens.yegor256
JBaruch Resolver
...
$tokens.jbaruch
А давайте тестировать. Тест #11. Пишем Egor256WordsFrequencyResolverTest.2. Как ни крути, но нужен более “интеграционный тест”
1. Пишем TextBasedQuestionTypeResolverTest2. Вручную создаем три бина для тестирования
TextBasedQuestionTypeResolver на примере Барух vs Егор кейса
А давайте тестировать. Тест #2
1. Пишем TextBasedQuestionTypeResolverTest2. Вручную создаем три бина для тестирования
TextBasedQuestionTypeResolver на примере Барух vs Егор кейса3. Все падает потому что не подтягивается application.yml4. @PropertySource …
А давайте тестировать. Тест #2
@SpringApplicationConfiguration(classes = ....class, initializers = YamlFileApplicationContextInitializer.class)public class OurTest { @Test public test(){... }}
А давайте тестировать. Тест #2
Spring Boot обновки
1. @SpringBootTest2. @TestConfiguration3. @MockBean && @SpyBean4. @DataJpaTest5. @MockMvcTest
Углубляемся в Spring. Тест #21. Применяем @SpringBootTest2. Долго…3. @SpringBootTest(classes = ...class)
Углубляемся в Spring. Тест #21. Применяем @SpringBootTest2. Долго…3. @SpringBootTest(classes = ...class)4. Стало быстрее
Углубляемся в Spring. Тест #21. Применяем @SpringBootTest2. Долго…3. @SpringBootTest(classes = ...class)4. Стало быстрее5. С кэшированием конфигураций – еще быстрее
Углубляемся в Spring. Тест #2@ContextHierarchy({ @ContextConfiguration(classes=WordsCommonConfiguration.class), @ContextConfiguration(classes= ...class)})
Углубляемся в Spring. Тест #2@ContextHierarchy({ @ContextConfiguration(classes=WordsCommonConfiguration.class), @ContextConfiguration(classes=....class)})
Порядок важен! Т.к другая конфигурация использует бины из WordsCommonConfiguration
Но ничего не закешировалось. Тест #2
@SpringBootTest – должен быть везде@Import – должен быть нигде@ActiveProfiles – один на всех
Но ничего не закешировалось. Тест #2
@SpringBootTest – должен быть везде@Import – должен быть нигде@ActiveProfiles – один на всехSpringBootTest.properties – должны быть одинаковые
Но ничего не закешировалось. Тест #2
@SpringBootTest – должен быть везде@Import – должен быть нигде@ActiveProfiles – один на всехSpringBootTest.properties – должны быть одинаковые
Порядок важен!Любая перестановка – cache miss
Но ничего не закешировалось. Тест #2
@SpringBootTest(properties={"a=b","b=a"})@SpringBootTest(properties={"b=a","a=b"})
Но ничего не закешировалось. Тест #2
@SpringBootTest(properties={"a=b","b=a"})@SpringBootTest(properties={"b=a","a=b"})
Кэш не сработает
Но ничего не закешировалось. Тест #2
@SpringBootTest – должен быть везде@Import – должен быть нигде@ActiveProfiles – один на всехSpringBootTest.properties – должны быть одинаковые
Б – безопасность@SpringBootTest@ActiveProfiles("yegor_vs_jbaruch")public abstract class ResolversAbstractCommonConfiguration {
}
А если наоборот?@DirtiesContext(...)
methodMode() default MethodMode.AFTER_METHODclassMode() default ClassMode.AFTER_CLASS...
Spring Boot обновки
1. @SpringBootTest2. @MockBean && @SpyBean3. @TestConfiguration4. @DataJpaTest5. @MockMvcTest
Синергия с Mockito1. @MockBean/@SpyBean2. @PostConstruct для настройки3. @Bean для настройки конкретных моков
1. Запустим все тесты2. DeveloperAssistantApplicationTests.contextLoad падает3. Загрузил бины из другого теста!
Все ли хорошо?
Spring Boot обновки
1. @SpringBootTest2. @MockBean && @SpyBean3. @TestConfiguration4. @DataJpaTest5. @MockMvcTest
1. Запустим все тесты2. DeveloperAssistantApplicationTests.contextLoad падает3. Загрузил бины из другого теста!4. @TestConfiguration!
Все ли хорошо?
1. Не сканируется @SpringBootTest2. Не сканируется другими конфигурациями и тестами3. Не прерывает процесс сканирования @SpringBootTest
@TestConfiguration
1. Запустим все тесты2. DeveloperAssistantApplicationTests.contextLoad падает3. Загрузил бины из другого теста!4. @TestConfiguration!5. DeveloperAssistantApplicationTests.contextLoad работает
Все ли хорошо?
1. Запустим все тесты2. DeveloperAssistantApplicationTests.contextLoad падает3. Загрузил бины из другого теста!4. @TestConfiguration!5. DeveloperAssistantApplicationTests.contextLoad работает6. А AnswerCacheServiceJPABackendTest перестал7. Загрузил бины из другого теста!
Все ли хорошо?
Два процесса сканирования1. @SpringBootTest сканирование2. @SpringBootApplication (@ComponentScan)
Вверх
Два процесса сканирования1. @SpringBootTest сканирование2. @SpringBootApplication (@ComponentScan) Вниз
Вверх
Два процесса сканирования
@SpringBootTest
@SpringBootApplication
src/main будет так же просканирован*
test classpath extends main classpath
Два процесса сканирования
@SpringBootTest
@SpringBootApplication
src/main будет так же просканирован*
test classpath extends main classpath
Два процесса сканирования
@SpringBootTest
@SpringBootApplication
src/main будет так же просканирован*
test classpath extends main classpath
Два процесса сканирования
@SpringBootTest
@SpringBootApplication
src/main будет так же просканирован*
test classpath extends main classpath
Два процесса сканирования
@SpringBootTest
@SpringBootApplication
src/main будет так же просканирован*
test classpath extends main classpath
1. Запустим все тесты2. DeveloperAssistantApplicationTests.contextLoad падает3. Загрузил бины из другого теста!4. @TestConfiguration!5. DeveloperAssistantApplicationTests.contextLoad работает6. А AnswerCacheServiceJPABackendTest перестал7. Загрузил бины из другого теста!8. @SpringBootConfiguration остановит сканирование
Все ли хорошо?
Spring Boot обновки
1. @SpringBootTest2. @TestConfiguration3. @MockBean && @SpyBean4. @DataJpaTest5. @MockMvcTest
@DataJpaTest
1. сканирует все репозитории2. конфигурирует EntityManager3. загружает другие конфигурации
1. сканирует все репозитории2. конфигурирует EntityManager3. загружает другие конфигурации4. фильтрует все не относящееся к Data/JPA
Применим знания
@DataJpaTest
Тестируем DefaultAssistantJpaBackendTest1. @DataJpaTest не загружает компоненты Spring2. Делаем конфигурацию, загружаем недостающее
Тестируем DefaultAssistantJpaBackendTest1. @DataJpaTest не загружает компоненты Spring2. Делаем конфигурацию, загружаем недостающее3. Ничего не работает, из за @SpringBootConfiguration
Тестируем DefaultAssistantJpaBackendTest1. @DataJpaTest не загружает компоненты Spring2. Делаем конфигурацию, загружаем недостающее3. Ничего не работает, из за @SpringBootConfiguration4. Переносим в новый package – все @*Test тесты должны быть
изолированы
@WebMvcTest
1. Не грузит компоненты спринга2. Грузит только то что относится к Web3. Сразу изолируем в отдельный пакет
Получаем суперспособность:
@AutowiredMockMvc mockMvc;
Где настраивать @MockBean1. В @*Configuration –
если мок нужен на этапе создания контекста2. В тесте (@Before/setup/etc)
если мок нужен только на этапе выполнения теста
Что же делает @SpringBootTest1. Без classes
a. сканирует со своего пакета “вверх” в поисках @SpringBootConfigurationi. игнорирует остальных
b. падает если не находит или находит несколько в одном пакете
2. classes=~@Configurationa. поднимет только указанные конфигурации
3. classes=~@TestConfigurationa. поднимет указанный контекст и продолжит сканирование. см пункт 1
Зачем нужен @SpringBootTest1. Полный тест на весь контекст2. Изменение properties3. Тесты с определенным скоупом – пакет/конфигурация/автоскан
Зачем нужен @TestConfiguration1. Если нужно не прерывать сканирование @SpringBootTest2. Изолированные тесты (игнорируется при сканировании)
Выводы1. Spring для Unit тестирования может быть быстрым2. Кэш контекстов – хрупкая штука3. Для тестов – только @TestConfiguration
Выводы1. Spring для Unit тестирования может быть быстрым2. Кэш контекстов – хрупкая штука3. Для тестов – только @TestConfiguration4. Изолировать группы тестов с помощью
Выводы1. Spring для Unit тестирования может быть быстрым2. Кэш контекстов – хрупкая штука3. Для тестов – только @TestConfiguration4. Изолировать группы тестов с помощью
a. выделения в пакетыb. @SpringBootConfiguration
Выводы1. Spring для Unit тестирования может быть быстрым2. Кэш контекстов – хрупкая штука3. Для тестов – только @TestConfiguration4. Изолировать группы тестов с помощью
a. выделения в пакеты (особенно для @*Test)b. @SpringBootConfiguration
5. SpringBootTest надо в основном использоватьдля микросервис тестов
Выводы1. Spring для Unit тестирования может быть быстрым2. Кэш контекстов – хрупкая штука3. Для тестов – только @TestConfiguration4. Изолировать группы тестов с помощью
a. выделения в пакетыb. @SpringBootConfiguration
5. SpringBootTest надо в основном использоватьдля микросервис тестов
6. Если есть DirtiesContext – стоит задуматься :)
Unit Component Microservice
Что нужно Junit/Mockito @ContextConfiguration @SpringBootTest
Кто управляет new Spring Spring Boot