Testing
The classes in this example show the use of named hierarchy levels in order to merge the configuration for specific levels in a context hierarchy. BaseTests defines two levels in the hierarchy, parent and child. ExtendedTests extends BaseTests and instruct
docs.spring.io
틀린 해석이나 내용이 있다면 알려주세요, 감사합니다 😋
5.11. Parallel Test Execution
Spring Framework 5.0은 Spring TestContext Framework를 사용할 때 단일 JVM 내에서 테스트를 병렬로 실행하기 위한 기본 지원을 도입했다. 테스트 코드나 구성을 변경하지 않고 대부분의 테스트 클래스 또는 테스트 메서드를 병렬로 실행할 수 있다
테스트 모음에 동시성을 도입하면 예상치 못한 작용, 잘못된 런타임 동작, 랜덤으로 테스트 실패할 수 있다. 그래서 테스트를 병렬로 실행하지 않는 경우에 대한 지침을 제공한다.
Do not run tests in parallel if the tests:
- Use Spring Framework’s @DirtiesContext support.
- Use Spring Boot’s @MockBean or @SpyBean support.
- Use JUnit 4’s @FixMethodOrder support or any testing framework feature that is designed to ensure that test methods run in a particular order. Note, however, that this does not apply if entire test classes are run in parallel.
- Change the state of shared services or systems such as a database, message broker, filesystem, and others. This applies to both embedded and external systems.
@DirtiesContxt 를 사용하면 contextcache 가 자동 제거 된다.
If parallel test execution fails with an exception stating that the ApplicationContext for the current test is no longer active, this typically means that the ApplicationContext was removed from the ContextCache in a different thread.
This may be due to the use of @DirtiesContext or due to automatic eviction from the ContextCache. If @DirtiesContext is the culprit, you either need to find a way to avoid using @DirtiesContext or exclude such tests from parallel execution.
Testing
The classes in this example show the use of named hierarchy levels in order to merge the configuration for specific levels in a context hierarchy. BaseTests defines two levels in the hierarchy, parent and child. ExtendedTests extends BaseTests and instruct
docs.spring.io
5.12. TestContext Framework Support Classes
5.12.1. Spring JUnit 4 Runner
테스트 클래스에 @RunWith(SpringJUnit4ClassRunner.class) 또는 @RunWith(SpringRunner.class) 애노테이션을 사용하면 된다
대체 러너나 다른 러너를 함께 사용하려는 경우에는 MockitoJUnitRunner 을 선택적으로 사용할 수 있다
@TestExecutionListeners 를 비워서 기본 리스너 비활성화 시킴
@RunWith(SpringRunner.class)
@TestExecutionListeners({})
public class SimpleTest {
@Test
public void testMethod() {
// test logic...
}
}
만약 이런 서포트 클래스가 없다면 직접
@ContextConfiguration을 통해 ApplicationContext를 구성해야한다.
저렇게 쓰면 됨
5.12.2. Spring JUnit 4 Rules
The org.springframework.test.context.junit4.rules package provides the following JUnit 4 rules
- SpringClassRule : SpringTestContextFramework 클래스 수준의 기능 지원하는 JUnitTestRule
- SpringMethodRule: instance 수준 및 method 수준 기능을 지원하는 JUnit MethodRule
SpringRunner와 달리 Spring의 규칙 기반 JUnit 지원은 org.junit.runner.Runner 구현과 독립적이라는 이점이 있으므로 기존 대체 실행기(예: JUnit 4의 Parameterized) 또는 타사와 결합에 용이하다 (MockitoJUnitRunner)
전체기능을 지원하려면 SpringClassRule 과 SpringMethodRule 을 결합해야함
// Optionally specify a non-Spring Runner via @RunWith(...)
@ContextConfiguration
public class IntegrationTest {
@ClassRule
public static final SpringClassRule springClassRule = new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
@Test
public void testMethod() {
// test logic...
}
}
5.12.3. JUnit 4 Support Classes
The org.springframework.test.context.junit4 package provides the following support classes for JUnit 4-based test cases
- AbstractJUnit4SpringContextTests
- AbstractTransactionalJUnit4SpringContextTests
AbstractJUnit4SpringContextTests 는 JUnit4 환경에서 ApplicationContext xptmxm 지원과 통합하는 추상 기본 테스트 클래스
AbstractJUnit4SpringContextTests를 확장하면 명시적 빈 조회를 수행하거나 컨텍스트의 상태를 전체적으로 테스할 때 사용할 수 있는 protected applicationContext 인스턴스 변수에 액세스가 가능
AbstractTransactionalJUnit4SpringContextTests is an abstract transactional extension of AbstractJUnit4SpringContextTests that adds some convenience functionality for JDBC access. This class expects a javax.sql.DataSource bean and a PlatformTransactionManager bean to be defined in the ApplicationContext. When you extend AbstractTransactionalJUnit4SpringContextTests, you can access a protected jdbcTemplate instance variable that you can use to run SQL statements to query the database. You can use such queries to confirm database state both before and after running database-related application code, and Spring ensures that such queries run in the scope of the same transaction as the application code. When used in conjunction with an ORM tool, be sure to avoid false positives. As mentioned in JDBC Testing Support, AbstractTransactionalJUnit4SpringContextTests also provides convenience methods that delegate to methods in JdbcTestUtils by using the aforementioned jdbcTemplate. Furthermore, AbstractTransactionalJUnit4SpringContextTests provides an executeSqlScript(..) method for running SQL scripts against the configured DataSource.
테스트 클래스를 Spring 특정 클래스 계층에 연결하지 않으려면 @RunWith(SpringRunner.class)또는 Spring의 JUnit 규칙을 사용하여 사용자 정의 테스트 클래스를 구성하면 된다
5.12.4. SpringExtension for JUnit Jupiter
JUnit5 에 도입된 JUnit Jupiter Test Framework 와 완전한 통합을 제공한다,
테스트 클래스에서 @ExtentdWith(SpringExtension.class) 애노테이션을 붙이면 된다
ApplicationContext load 지원, 테스트 인스턴스 종속성 주입, 트랜잭션 테스트 메서드 실행 등과 같은 테스트를 구현할 수 있다
- Dependency injection for test constructors, test methods, and test lifecycle callback methods. See Dependency Injection with SpringExtension for further details.
- Powerful support for conditional test execution based on SpEL expressions, environment variables, system properties, and so on. See the documentation for @EnabledIf and @DisabledIf in Spring JUnit Jupiter Testing Annotations for further details and examples.
- Custom composed annotations that combine annotations from Spring and JUnit Jupiter. See the @TransactionalDevTestConfig and @TransactionalIntegrationTest examples in Meta-Annotation Support for Testing for further details.
@ContextConfiguration 과 SpringExtension을 함께 사용
// Instructs JUnit Jupiter to extend the test with Spring support.
@ExtendWith(SpringExtension.class)
// Instructs Spring to load an ApplicationContext from TestConfig.class
@ContextConfiguration(classes = TestConfig.class)
class SimpleTests {
@Test
void testMethod() {
// test logic...
}
}
@SpringJUnitConfig = @SpringJUnitWebConfig + @ApplicationContext
// Instructs Spring to register the SpringExtension with JUnit
// Jupiter and load an ApplicationContext from TestConfig.class
@SpringJUnitConfig(TestConfig.class)
class SimpleTests {
@Test
void testMethod() {
// test logic...
}
}
@ContextConfiguration과 함께 SpringExtension을 사용
// Instructs Spring to register the SpringExtension with JUnit
// Jupiter and load a WebApplicationContext from TestWebConfig.class
@SpringJUnitWebConfig(TestWebConfig.class)
class SimpleWebTests {
@Test
void testMethod() {
// test logic...
}
}
Spring JUnit Jupiter Testing Annotations
Testing
The classes in this example show the use of named hierarchy levels in order to merge the configuration for specific levels in a context hierarchy. BaseTests defines two levels in the hierarchy, parent and child. ExtendedTests extends BaseTests and instruct
docs.spring.io
Dependency Injection with SpringExtension
SpringExtension 은 Jupiter 에서 ParameterResolver 확장 API를 구현하여 Spring provide dependency injection for test constructors, test methods, and test lifecycle callback methods 등을 제공한다
특히 ApplicationContext 에서 @BeforeAll, @AfterAll, @BeforeEach, @AfterEach, @Test, @RepeatedTest, @ParameterizedTest 등의 애노테이션을 사용할 수 있다
Constructor Injection
JUnit Jupiter 테스트 클래스의 생성자에 있는 특정 매개변수가 ApplicationContext 유형 (또는 하위) 이거나, @Autowired, @Qualifier, @Value로 주석이 추가되거나 메타 주석이 추가된 경우 특정 값을 주입한다
생성자가 autowirable 로 간주되는 경우 테스트 클래스 생성자에 대한 모든 인수를 autowire 할 수도 있다
다음 조건 중 하나만 적용하면 (우선순위에 따라서) autowirable 로 간주한다
- The constructor is annotated with @Autowired.
- @TestConstructor is present or meta-present on the test class with the autowireMode attribute set to ALL.
- The default test constructor autowire mode has been changed to ALL.
@TestConstructor
Testing
The classes in this example show the use of named hierarchy levels in order to merge the configuration for specific levels in a context hierarchy. BaseTests defines two levels in the hierarchy, parent and child. ExtendedTests extends BaseTests and instruct
docs.spring.io
If the constructor for a test class is considered to be autowirable, Spring assumes the responsibility for resolving arguments for all parameters in the constructor. Consequently, no other ParameterResolver registered with JUnit Jupiter can resolve parameters for such a constructor.
@DirtiesContext를 사용하여 메서드 전후에 used to close the test ApplicationContext 를 적용할 경우 JUnit Jupiter의 @TestInstance(PER_CLASS) 지원과 함께 사용해서는 안된다.
@TestInstance(PER_CLASS) 가 테스트 메서드 호출 사이에 테스트 인스턴스를 캐싱하도록 지시하기 때문에 종속성 주입이 다시 발생하지 않아 원래 삽입된 Bean에 대한 참조를 유지하기 때문이다
@TestInstance(PER_CLASS)와 함께 "before test method" 또는 "after test method" 모드와 함께 @DirtiesContext를 사용하려면 필드 또는 setter 주입을 통해 제공되는 Spring의 종속성을 구성해야 테스트 간에 다시 주입될 수 있다
OrderService bean 주입
@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {
private final OrderService orderService;
@Autowired
OrderServiceIntegrationTests(OrderService orderService) {
this.orderService = orderService;
}
// tests that use the injected OrderService
}
final 테스트 종속성이 있으므로 qusrudgkf tn djqtdma
If the spring.test.constructor.autowire.mode property is to all (see @TestConstructor), we can omit the declaration of @Autowired on the constructor in the previous example, resulting in the following.
@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {
private final OrderService orderService;
OrderServiceIntegrationTests(OrderService orderService) {
this.orderService = orderService;
}
// tests that use the injected OrderService
}
Method Injection
매개변수가 ApplicationContext(또는 하위 유형) 유형이거나 @Autowired, @Qualifier 또는 @Value로 주석이 추가되거나 메타 주석이 추가되면 Spring은 해당 값을 주입한다
@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {
@Test
void deleteOrder(@Autowired OrderService orderService) {
// use orderService from the test's ApplicationContext
}
}
ParameterResolver 지원으로 타사 확장에서 단일 메서드에 여러 종석성 주입
(placeOrderRepeatedly() 주입)
@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {
@RepeatedTest(10)
void placeOrderRepeatedly(RepetitionInfo repetitionInfo,
@Autowired OrderService orderService) {
// use orderService from the test's ApplicationContext
// and repetitionInfo from JUnit Jupiter
}
}
@Nested test class configuration
스프링 5.3 부터 기본 INHERIT 모드에서 OVERRIDE모드로 변경하려면
@NestedTestConfiguration(EnclosingConfiguration.OVERRIDE)으로 개별 @Nested 테스트 클래스에 주석을 달 수 있다
명시적인 @NestedTestConfiguration 선언은 주석이 달린 테스트 클래스와 해당 하위 클래스 및 중첩 클래스에 적용된다.
@NestedTestConfiguration으로 최상위 테스트 클래스에 주석을 달 수 있으며 이는 모든 중첩 테스트 클래스에 재귀적으로 적용된다
@SpringJUnitConfig(TestConfig.class)
class GreetingServiceTests {
@Nested
@ActiveProfiles("lang_en")
class EnglishGreetings {
@Test
void hello(@Autowired GreetingService service) {
assertThat(service.greetWorld()).isEqualTo("Hello World");
}
}
@Nested
@ActiveProfiles("lang_de")
class GermanGreetings {
@Test
void hello(@Autowired GreetingService service) {
assertThat(service.greetWorld()).isEqualTo("Hallo Welt");
}
}
}
5.12.5. TestNG Support Classes
The org.springframework.test.context.testng package provides the following support classes for TestNG based test cases
- AbstractTestNGSpringContextTests : TestNG 환경에서 통합하는 추상 기본테스트 클래스
- AbstractTransactionalTestNGSpringContextTests : JDBC 액세스를 위한 편의 기능을 추가한 AbstractTestNGSpringContextTests 의 추상 트랜잭션 확장 기능. SQL 문을 실행하여 데이터베이스를 쿼리하는 데 사용할 수 있는 보호된 jdbcTemplate 인스턴스 변수에 액세스할 수 있고, data base 관련 상태를 실행 전후에 확인이 가능하고, 동일한 트랜잭션 번위에서 실행시킬 수 있도록 함, DataSource에 대해 SQLscript 를 실행할 수 있는 executeSqlScript 를 제공함
These classes are a convenience for extension. If you do not want your test classes to be tied to a Spring-specific class hierarchy, you can configure your own custom test classes by using @ContextConfiguration, @TestExecutionListeners, and so on and by manually instrumenting your test class with a TestContextManager. See the source code of AbstractTestNGSpringContextTests for an example of how to instrument your test class.
5.13. Ahead of Time Support for Tests
통합 테스트에 대한 Spring의 AOT(Ahead of Time) 지원
- Build-time detection of all integration tests in the current project that use the TestContext framework to load an ApplicationContext.
-
- Provides explicit support for test classes based on JUnit Jupiter and JUnit 4 as well as implicit support for TestNG and other testing frameworks that use Spring’s core testing annotations — as long as the tests are run using a JUnit Platform TestEngine that is registered for the current project.
- Build-time AOT processing: each unique test ApplicationContext in the current project will be refreshed for AOT processing.
- Runtime AOT support: when executing in AOT runtime mode, a Spring integration test will use an AOT-optimized ApplicationContext that participates transparently with the context cache.
The @ContextHierarchy annotation is currently not supported in AOT mode.
To provide test-specific runtime hints for use within a GraalVM native image, you have the following options.
- Implement a custom TestRuntimeHintsRegistrar and register it globally via META-INF/spring/aot.factories.
- Implement a custom RuntimeHintsRegistrar and register it globally via META-INF/spring/aot.factories or locally on a test class via @ImportRuntimeHints.
- Annotate a test class with @Reflective or @RegisterReflectionForBinding.
- See Runtime Hints for details on Spring’s core runtime hints and annotation support.
사용자가 정의하는 ContextLoader 구현의 경우 AOT 빌드 시간 처리 및 AOT 런타임 실행 지원을 제공하기 위한 AotContextLoader를 구현해야한다. Spring Framework 및 Spring Boot에서는 이미 모두 AotContextLoader를 구현할 수 있다.
사용자 지정하여 TestExecutionListener를 구현하는 경우 AOT 처리에 참여하려면 AotTestExecutionListener를 구현해야한다
(SqlScriptsTestExecutionListener)
'Web > spring' 카테고리의 다른 글
[Spring framework Core] 5. Aspect Oriented Programming with Spring (1) (0) | 2023.02.16 |
---|---|
[Spring framework Web MVC docs] 1.6. Asynchronous Requests (0) | 2023.02.15 |
[Spring framework Web MVC docs] 1.7. CORS (0) | 2023.02.14 |
[Spring framework testing] 5. Spring TestContext Framework (3) (0) | 2023.02.13 |
[Spring framework Web MVC docs] 1.4. Functional Endpoints (0) | 2023.02.12 |