Презентация подготовлена по материалам выступления Александра Бармина на витебском Miniq #26, который был проведен 25 июня 2020 года:
https://community-z.com/events/miniq-qa .
Про доклад:
Spring Framework - невероятно мощный и удобный инструмент для разработки приложений на Java. Немало решений уже создано на его основе, да и многие новые также создаются на этой платформе.Spring Framework предоставляет удобный инструментарий не только для разработки, но и для тестирования ПО. В докладе мы рассмотрим инструменты, которые предлагает Spring для тестирования отдельных компонентов, написания интеграционных и контрактных тестов, а также рассмотрим возможность совместного использования Spring и TestContainers.
2. 2020 EPAM Systems, Inc.
• Lead Software Engineer
• EPAM Lab Mentor
ALEKSANDR BARMIN
• Email: Aleksandr_Barmin@epam.com
• Twitter: @AlexBarmin
CONTACTS
2
3. 2020 EPAM Systems, Inc.
Agenda
1
6
2
3
4
5
W H Y T E S T I N G I S S O I M P O R T A N T
C O N F I G U R I N G C O N T E X T F O R T E S T S
U S I N G R E A L D E P E N D E N C I E S
E X A M P L E S
3
O V E R V I E W O F T E S T I N G
T E S T L A Y E R S
4. 2020 EPAM Systems, Inc.
Overview of testing
• A test case is a set of test inputs, execution
conditions, and expected results developed for
a particular objective, such as to exercise a
particular program path or to verify
compliance with a specific requirement.
• https://en.wikipedia.org/wiki/Test_case
4
5. 2020 EPAM Systems, Inc.
Test Suite
Overview of testing
5
Test
Test
Test case
System Under
Test (SUT)
Verifies behavior of
6. 2020 EPAM Systems, Inc.
Overview of testing
6
Test runner
Test class
Executes
Test method
Test method
Test method Teardown
Verify
Execute
Setup
Fixture
System Under
Test (SUT)
Configures
Restores
Interact
7. 2020 EPAM Systems, Inc.
Overview of testing
7
Order Controller Order Service
Order Data Access
Object
Orders
Database
How to test it in isolation?
8. 2020 EPAM Systems, Inc.
Overview of testing
8
Slow, complex
test
System Under
Test (SUT)
Dependency
Tests
Fast, simple
test
System Under
Test (SUT)
Test Double
Tests
Replaced with
9. 2020 EPAM Systems, Inc.
Why testing is so important – Test Pyramid
9
End-to-
end
Component
Integration
UnitTest the business logic
Verify that a service
communicates with its
dependencies
Acceptance tests for a
service
Acceptance tests for an
application
Slow, brittle, costly
Fast, reliable, cheap
10. 2020 EPAM Systems, Inc.
Why testing is so important – the Ice Cream Cone
10
End-to-end
Component
Integration
UnitTest the business logic
Verify that a service
communicates with its
dependencies
Acceptance tests for a
service
Acceptance tests for an
application
Slow, brittle, costly
Fast, reliable, cheap
11. 2020 EPAM Systems, Inc.
Deployment pipeline
Why testing is so important - The deployment pipeline
11
Pre-commit
tests
Commit test
stage
Integration
tests stage
Component
tests stage
Deploy stage
Production
environment
Not
production
ready
Production
ready
Fast
feedback
Slow
feedback
12. 2020 EPAM Systems, Inc.
Talk is cheap. Show me the code
- Linus Torvalds
12
13. 2020 EPAM Systems, Inc.
The Blog Application
13
Post Controller Post Service Post Repository Post Database
14. 2020 EPAM Systems, Inc.
Testing The Blog Application
14
Post Controller Post Service Post Repository Post Database
PostServiceSpringTest
15. 2020 EPAM Systems, Inc.
@ContextConfiguration
15
public @interface ContextConfiguration {
}
16. 2020 EPAM Systems, Inc.
@ContextConfiguration
16
public @interface ContextConfiguration {
// where to find bean definitions
String[] value() default {};
String[] locations() default {};
Class<?>[] classes() default {};
}
17. 2020 EPAM Systems, Inc.
@ContextConfiguration
17
public @interface ContextConfiguration {
// where to find bean definitions
String[] value() default {};
String[] locations() default {};
Class<?>[] classes() default {};
// how to initialize the Application Context
Class<? extends ApplicationContextInitializer<?>>[] initializers() default {};
}
18. 2020 EPAM Systems, Inc.
@ContextConfiguration
18
public @interface ContextConfiguration {
// where to find bean definitions
String[] value() default {};
String[] locations() default {};
Class<?>[] classes() default {};
// how to initialize the Application Context
Class<? extends ApplicationContextInitializer<?>>[] initializers() default {};
// should context from parent classes be loaded
boolean inheritLocations() default true;
boolean inheritInitializers() default true;
}
19. 2020 EPAM Systems, Inc.
@ContextConfiguration
19
public @interface ContextConfiguration {
// where to find bean definitions
String[] value() default {};
String[] locations() default {};
Class<?>[] classes() default {};
// how to initialize the Application Context
Class<? extends ApplicationContextInitializer<?>>[] initializers() default {};
// should context from parent classes be loaded
boolean inheritLocations() default true;
boolean inheritInitializers() default true;
// what will read bean definitions
Class<? extends ContextLoader> loader() default ContextLoader.class;
}
20. 2020 EPAM Systems, Inc.
@ContextConfiguration
20
public @interface ContextConfiguration {
// where to find bean definitions
String[] value() default {};
String[] locations() default {};
Class<?>[] classes() default {};
// how to initialize the Application Context
Class<? extends ApplicationContextInitializer<?>>[] initializers() default {};
// should context from parent classes be loaded
boolean inheritLocations() default true;
boolean inheritInitializers() default true;
// what will read bean definitions
Class<? extends ContextLoader> loader() default ContextLoader.class;
// name of the context hierarchy level
String name() default "";
}
21. 2020 EPAM Systems, Inc.
@ContextConfiguration and @SpringJUnitConfig
21
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
PostService.class,
CommentValidator.class,
PostSanitizer.class
})
public class PostServiceSpringTest { }
@SpringJUnitConfig(classes = {
PostService.class,
CommentValidator.class,
PostSanitizer.class
})
public class PostServiceSpringTest { }
22. 2020 EPAM Systems, Inc.
@SpringBootTest
The search algorithm works up from the package that
contains the test until it finds a
@SpringBootApplication or
@SpringBootConfiguration annotated class. As long as
you’ve structured your code in a sensible way your main
configuration is usually found.
https://docs.spring.io/spring-
boot/docs/1.5.2.RELEASE/reference/html/boot-features-
testing.html#boot-features-testing-spring-boot-
applications-detecting-config
22
23. 2020 EPAM Systems, Inc.
@SpringBootTest
23
Looks for
@SpringBootApplication or
@SpringBootConfiguration
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(…)
public @interface SpringBootApplication { }
@SpringBootConfiguration
@Configuration
@TestConfiguration
PostControllerSpringBootTest
24. 2020 EPAM Systems, Inc.
@Sql, @SqlConfig and JdbcTestUtils
24
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class PostControllerWithDbInitTest {
}
25. 2020 EPAM Systems, Inc.
@Sql, @SqlConfig and JdbcTestUtils
25
@Sql(
scripts = "/create_posts.sql",
config = @SqlConfig(separator = ";")
)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class PostControllerWithDbInitTest {
}
38. 2020 EPAM Systems, Inc.
Testing The Blog Application
38
Post Controller Post Service Post Repository
Mock or in-
memory
database
39. 2020 EPAM Systems, Inc.
Docker Container
Testing The Blog Application
39
Post Controller Post Service Post Repository
Real DB
instance
Mock or in-
memory
database
40. 2020 EPAM Systems, Inc.
TestContainers
• Integration tests with real dependencies in Docker
containers instead of mocks:
• Databases
• Message queues
• Browsers
• Anything else that could be run in Docker
• https://www.testcontainers.org/
40
PostServiceTestContainersTest
41. 2020 EPAM Systems, Inc.
Examples weren’t shown
• @DertiesContext
• @ActiveProfiles
• @ContextHierarchy
• ReflectionTestUtils
• EnvironmentTestUtils
• Spring Cloud Contract
• Spring Cloud Stream Test
41
42. 2020 EPAM Systems, Inc.
Conclusion
• Follow the Test Pyramid approach
• Use FIRST for tests
• Use SOLID for your code
• Spring Framework has a lot of tools that simplify
testing – use them
• https://github.com/aabarmin/epam-spring-testing
• https://docs.spring.io/spring/docs/current/spring-
framework-reference/testing.html
• https://docs.spring.io/spring-
boot/docs/1.5.2.RELEASE/reference/html/boot-
features-testing.html
• https://www.testcontainers.org/
• https://spring.io/projects/spring-cloud-contract
• https://cloud.spring.io/spring-cloud-static/spring-
cloud-
stream/2.1.3.RELEASE/multi/multi__testing.html
42
Thank you!