출처 :
마이크로서비스 패턴 (책)
큰 모놀리식 애플리케이션은 테스트하기 아주 어렵다.
테스터블리티 확보는 msa 도입 계기중 하나.
msa 는 특유의 복잡성 때문에 반드시 자동화 필요. (상호작용까지)
9장은 개론을, 10장은 고급 테스트 개념을 다룬다.
여기서 부터는 독후감
9장은 단위테스트 위주이며 mocking 을 활용 하기 때문에 10장이 좀더 기대가 된다.
여기서 재미있던 것은 컨슈머 주도 계약 테스트 (cdc)
였다.
스프링 클라우드 컨트랙트를 활용해서 컨슈머가 주도하여 계약을 생성하는건데, 이부분은 좀 신선 하긴 했으나 쉽게 적용할수 있을지 잘 모르겠다.
특히 컨슈머가 프로듀서 코드베이스를 커밋 해야 한다는점은 일리가 있긴 한데, 컨슈머에게 문법이든, 스펙작성이든 뭔가를 강요해야 하는듯한 느낌을 줄수 있을것 같다.
또한 컨트랙트는 또 누가 관리해야하나.. 물론 백엔드가 하면 되겠지만 백엔드 입장에서도 관리포인트가 계속 늘어난다.
gw 때도 느꼈었지만 모든 컴포넌트와 패턴이 유용한건 맞지만, 모든 msa 컴포넌트가 그렇듯 팀의 구조도 받쳐줘야 유지할수 있다.
그냥 백엔드에서 떼워도 될만한 컴포넌트일수 있으니 어느정도 실리가 있는지 따져보고 차용하도록 하는게 좋겠다.
테스트의 목적 : sutd 의 동작을 확인하는것
여기서 system 이란?
테스트 스위트?
before이나 teardown에서 실행하는 정리메소드같은건 별도 테스트 클래스에 두자. (중복제거)
sut 는 대부분 디펜던시를 갖고있다.
OrderController 를 테스트하기위해 service, repository 모두 띄우는것은 느림.
테스트더블 2종류
모키토 쓰다보면 2개를 딱히 구분하진 않긴 한다.
mock 객체를 만들어줘야 stubing 을 할수 있고 verifing 할수 있기 때문.
종류는 아주 다양하다.
단위테스트
거시적인 종단간 테스트
효용성에 문제가 없는 한도 내에서 가장 범위가 좁은 테스트를 작성하는게 최선.
이 장에서는 주로 서비스 조각을 테스트 하는 전략에 대해서 이야기 한다.
이러면 전체 서비스를 테스트하는 컴포넌트 테스트 개수도 최대한 줄어든다.
화살표는 모두 의존성방향.
API gw 에서 주문서비스 GET /orders/{orderId}
를 테스트 한다고 가정시 관계
컨슈머는 프로바이더가 다음과 같은 일을 하는 endpoint 가 구현되었는지 확인한다.
컨슈머 계약 테스트는 비즈니스 로직을 빠짐없이 체크하는 테스트가 아니다.
mock controller 테스트 이다.
컨슈머쪽 개발자가 프로바이더 쪽에 테스트 스위트를 추가한다!?
코드 반영은 PR을 요청하는식이라니..
역시나 배포 파이프라인이 컨슈머쪽에 있다.
컨슈머가 기대한 대로 프로바이더 컨트롤러가 잘 작성되었는지를 체크할수 있다.
의도는 알겠는데.. 실제로 이런식으로 운영이 가능할까??
Service Integration Contract Test
라고도 한다.
상호간 작용을, 계약(contract) 이라는 샘플 모음집으로 정의 하는것.
예를들어 rest api 계약은, 요청/응답 샘플을 모아놓은것.
스키마는 유용하지 않다. 어차피 프로바이더에 샘플 요청을 넘겨 호출하기 때문.
Pact 프레임워크군 중 하나.
그루비 DSL 작성 가능.
컨슈머 쪽에서 효용성
프로바이더 쪽에서 효용성
org.springframework.cloud.contract.spec.Contract.make {
request {
method 'GET'
url '/orders/1223232'
}
response {
status 200
headers {
header('Content-Type': 'application/json;charset=UTF-8')
}
body("{ ... }")
}
}
API 게이트웨이가 주문 서비스를 어떻게 호출하는지 기술한 계약
스프링 클라우드 컨트랙트는 메시징 기반도 테스트 가능.
프로바이더쪽
컨슈머쪽
독립 단위 테스트
vs 공동 단위 테스트
?
독립 단위 테스트 (어디에도 속하지 않는 비즈니스 로직을 구현한 클래스, 즉 도메인 서비스)
공동 단위 테스트 (사가처럼 여러 서비스에 걸쳐있는경우)
public class OrderTest {
private ResultWithEvents<Order> createResult;
private Order order;
@Before
public void setUp() throws Exception {
createResult = Order.createOrder(CONSUMER_ID, AJANTA_ID, CHICKEN_VINDALOO
_LINE_ITEMS);
order = createResult.result;
}
@Test
public void shouldCalculateTotal() {
order.getOrderTotal());
}
...
}
Order 는 Money 밸류 객체에 의존한다. Money 밸류 객체도 반드시 함께 테스트 해야 한다. -> 공동 단위 테스트
서블릿 mocking 해서 하는 단위 테스트가 예시로 나온다.
인터넷에 많은 예시들이 있으므로 생략
OrderEventConsumer가 각 이벤트를 적절한 핸들러로 라우팅해서 OrderService가 올바르게 호출되었는지 확인한다.
이벤추에이트 트램 목 메시징 프레임워크
를 활용하는 예시여서 생략