Comments (3)
test container reference : https://www.testcontainers.org/
1. 테스트 컨테이너의 편리한 경우
- 데이터 엑세스 계층 통합 테스트
- 운영과 동일한 상태로 개발 가능
- 간단한 설정을 통한 컨테이너 생성 가능
- 애플리케이션 통합 테스트
- 다양한 의존성 있는 컴포넌트(e.g. RDB, MQ) 를 편리하게 테스트해볼 수 있음
- UI/ 승인 테스트
- 자동화된 UI 테스트 가능(Selenium 과 호환 가능?)
테스트 컨테이너의 단점
- 테스트 수행 속도가 낮아진다.(컨테이너를 한번만 인스턴스화 하면 해결이 가능하다.)
JDBC 를 사용한다면 간단히 설정 가능
spring:
datasource:
url: jdbc:tc:mysql:8:///soolsul?TC_REUSABLE=true
username: test
password: test121212
driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
Redis의 경우, 별도로 만들어줘야 함.
public abstract class TestRedisContainer {
private static final String DOCKER_REDIS_IMAGE = "redis:7.0.5-alpine";
public static GenericContainer REDIS_CONTAINER =
new GenericContainer<>(DockerImageName.parse(DOCKER_REDIS_IMAGE))
.withExposedPorts(6379)
.withReuse(true);
static {
REDIS_CONTAINER.start();
System.setProperty("spring.redis.host", REDIS_CONTAINER.getHost());
System.setProperty("spring.redis.port", REDIS_CONTAINER.getMappedPort(6379).toString());
}
}
from be-tutorials.
https://www.testcontainers.org/quickstart/junit_5_quickstart/
JUnit 5 Quickstart
1. 테스트 컨테이너가 없을 떄의 문제점
- local installation 에 의존한다.
- 모든 개발자가 모두 같은 설치 버전으로 테스트를 한다는 보장이 없다. (같은 로컬 환경의 테스트가 필요하다)
1. Add Testcontainers as a test-scoped dependency
- gradle 에서 아래와 의존성을 추가하면 JUnit5 와 통합된다. (통합된다는 의미가 뭐지...?)
testImplementation "org.junit.jupiter:junit-jupiter:5.8.1"
testImplementation "org.testcontainers:testcontainers:1.17.6"
testImplementation "org.testcontainers:junit-jupiter:1.17.6"
2. Get Testcontainers to run a Redis container during our tests
@Container
public GenericContainer redis = new GenericContainer(DockerImageName.parse("redis:5.0.3-alpine"))
.withExposedPorts(6379);
- @container (아직 뭔 소리인지 모르겠다.)
- 테스트 생명 주기의 다양한 이벤트에 대해 해당 필드에 알리도록 JUnit 에게 지시한다.
- 해당 객체는 Docker Hub에 특정 Redis 이미지를 사용하도록 구성하고 포트를 노출하도록 구성된 TestContainers GenericContainer 이다.
테스트 실행 시 TestContainer 는 아래와 같은 로그를 보여준다.
- 테스트 메서드가 실행하기 이전 활성화 되었다는 메세지
- local docker setup 을 확인하고 빠르게 테스트 한다는 메세지
- 필요한 경우 image 를 pull 한다는 메세지
- 새로운 컨테이너를 생성하고 준비하기까지 대기하는 상태
- 테스트 이후 컨테이너를 종료 및 삭제하는 상태
3. Make sure our code can talk to the container
- 테스트 컨테이너는 각가 컨테이너마다 랜덤한 포틀르 사용하지만 런타임 실제 포트도 편리하게 사용할 수 있다.
- [notice] 웬만하면
getHost()
메서드를 사용하자. localhost의 경우 일부 환경에서만 동작하기 때문에 다른 환경에서 동작하지 않을 수 있음(e.g. CI 환경)
@Testcontainers
public class RedisBackedCacheIntTest {
private RedisBackedCache underTest;
// container {
@Container
public GenericContainer redis = new GenericContainer(DockerImageName.parse("redis:5.0.3-alpine"))
.withExposedPorts(6379);
// }
@BeforeEach
public void setUp() {
String address = redis.getHost();
Integer port = redis.getFirstMappedPort();
// Now we have an address and port for Redis, no matter where it is running
underTest = new RedisBackedCache(address, port);
}
@Test
public void testSimplePutAndGet() {
underTest.put("test", "example");
String retrieved = underTest.get("test");
assertThat(retrieved).isEqualTo("example");
}
}
from be-tutorials.
사이드 리뷰 피드백
- 샤인 리뷰 피드백 : soolsul/soolsul-server#112
1. @DynamicPropertySource(참고 레퍼런스 : https://recordsoflife.tistory.com/607)
- Spring ver. 5.2.5 이후부터 나온 어노테이션이며, 동적 값으로 속성(property)을 수정을 지원합니다.
- Dynamic PropertyRegistry.add(String, Supplier) 메서드를 통해 Spring Enviorment 일부 속성을 추가합니다.
@SpringBootTest @Testcontainers public class ArticleLiveTest { @Container static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:11") .withDatabaseName("prop") .withUsername("postgres") .withPassword("pass") .withExposedPorts(5432); @DynamicPropertySource static void registerPgProperties(DynamicPropertyRegistry registry) { registry.add("spring.datasource.url", () -> String.format("jdbc:postgresql://localhost:%d/prop", postgres.getFirstMappedPort())); registry.add("spring.datasource.username", () -> "postgres"); registry.add("spring.datasource.password", () -> "pass"); } // tests are same as before }
- @DynamicPropertySource 어노테이션을 선언한 메서드는 정적으로 선언해야 합니다.
- 그리고 DynamicPropertyRegistry 유형 인수(Parameter) 하나만 허용해야 합니다.
2. 대안 테스트 설비
- TestContainer, @DynamicPropertySource 모두 고정 장치 설정과 테스트 코드에 대한 의존도가 높아지는 단점이 있습니다.
- 인프라 설정 및 동적 구성 적용은 이를 필요로 하는 모든 테스트에서 복제됩니다.
- 이러한 단점을 피하기 위해 대부분의 테스트 프레임워크에서 제공하는 테스트 픽스처 기능을 사용할 수 있습니다.
- Q. 테스트 픽스처?? 모든 테스트 전에 RDB 구성 + SpringBoot 구성, 테스트 이후 인스턴스 중지를 설정할 수 있습니다
- 대표적인 예로는 BeforeAll, AfterAll 메서드가 있습니다. 그리고 이를 재사용하기 위해서 @ExtendsWith(---Extension.class) 를 사용하면 동일한 기능을 쉽게 재사용할 수 있습니다.
3. 궁금증
- @DynamicPropertySource 로 Spring Enviorment 설정하면 만약 재실행을 시작하지 않는 경우에는 메인 코드에는 영향을 미치지 않는 것일까? (어노테이션을 확인해보니 런타임 시점에 property 를 덮어씌우는 기능을 하는 것 같음.)
from be-tutorials.
Related Issues (13)
- spring security jwt 로그인 코드 이관
- spring security 권한(Authority) 로직 추가
- jenkins 학습하기 HOT 5
- spring cloud 기본 학습하기
- Spring Core docs 읽는 연습하기
- Spring Transactional 동작 원리 이해하기
- 리눅스 명령어 정리
- Beanstalk Practice HOT 4
- Spring Rest Docs 정리 HOT 1
- [RealMySQL] chapter09. 옵티마이저와 힌트 HOT 1
- SpringBatch practice
- 오프셋 기반, 커서 기반 페이지네이션
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from be-tutorials.