인수 받을 때 요구사항에 잘 맞게 개발하는 테스트
기술적인 용어없이 클라이언트가 읽기 좋은 문서로 만든다
- BlackBox 테스트의 성질
- 내부 구조의 동작원리를 테스트가 관여하지 않도록 한다
- 그냥 요청과 응답으로 테스트가 잘 구현되었는지
- 내부적으로 뭘 사용했는지 테스트한 것은 중요하지 않다
여러 직군의 이해를 돕기위한 테스트
- 직군별로 이해관계가 다르다
- 공통의 이해를 기반으로 하는 개발 방법론
- 인수테스트
- 공통적으로 이 기획을 우리가 모두 동의했으니 인수테스트를 진행하겠소
- 인수조건 명시
- 사용자스토리에 대한 설계가 이전에 있어야 한다 (여기서는 스킵)
- 인수테스트가 만족하는 조건
- 시나리오 기반의 표현방식을 사용 (보통의 사용법)
- 체크 방식도 사용
- Given When Then 사용
- 인수 테스트
- 실제 요청 응답 환경과 유사하게 테스트
- 레거시 코드 리펙토링
- 레거시에 대한 인수테스트를 작성하여 기존 기능을 보호
- 그 상태에서 새로운 요구사항을 적용
- 파악이 가능한 부분 먼저 단위테스트로 기능검증
- 인수테스트 → 단위테스트
- 무조건 이렇게 할 필요는 없지만 중요한 코드에 대해서는 보호를 하는것이 좋다
- RestAssured가 요청 (클라이언트)
- Mock으로 응답
- 테스트 서버를 실행 (Random Port)
- 테스트의 웹환경을 어떻게 구축할지 설정
- RestAssured의 포트를 지정
- 랜덤포트 사용
- 여러 테스트가 실행되게 된다면 포트의 충돌이 생긴다.
- 테스트 클라이언트 객체
- 실제 웹서버에 요청을 보낸다.
- 단점은 @Transactional 사용하지 못한다
- 톰캣을 사용한다.
- 인수 받을 때 요구사항에 잘 맞게 개발하는 ATDD의 목적 상 가장 바람직 하다.
- webEnvironment.MOCK으로 사용
- 가짜 요청을 보낸다
- 실제 http를 분석하는것이 아니라 path의 값을 보고 매칭되는 컨트롤러를 찾아서 처리한다
- 하나의 트랜잭션 내에서 동작할 수 있다
- Rollback 사용가능하다
- 이걸로 인수테스트 하기도 한다
- Netty를 기본으로 한다
- Webflux가 포함된 패키지를 사용한다
- dispatcherServlet가 아닌 Webflux의 webinder환경에 적합한 테스트 객체이다
- tomcat을 사용하는 것이 아닌 netty를 사용한다
- 문서화 할 때 Spring Rest Docs를 사용할 때 톰캣 환경에서 Webtestclient를 사용하여 docs를 만들기 위해서는 추가적인 설정이 필요하다
테스트의 격리를 돕는 기능
- @DirtiesContext
- 컨텍스트를 초기화 해준다
- 해당 컨텍스트를 새로 로드하도록 한다
- 컨텍스트 캐싱을 막는다
- 그래서 매번 컨텍스트를 구성하다보니 시간이 많이 걸림
- Repository의 초기화
- 인수테스트에 사용하는 Repository를 알 수 밖에 없다
- 해당 테스트가 특정 Repository에 강하게 결합되어 있다
- @Transactional
- RestAssured에서는 Transactional 사용불가
- 쿼리를 이용한 초기화
- 최대한 블랙박스에 가깝게 만드는 설정
- 실패 인수 테스트 작성
- 실패 단위 테스트 작성
- 테스트 통과 되는 코드 작성
- refactor
- 2 3 4를 1번이 성공할 때 까지 반복
Feature: 간략한 기능 서술
Background: 각 시나리오 사전 조건
Scenario: 시나리오 제목
Given: 사전조건
When: 발생해야하는 이벤트
Then: 사후조건
And: 앞선 내용에 추가적인 내용 기술
- Feature 기준으로 인수 테스트 클래스를 나눈다.
- Scenario 기준으로 하나의 인수 테스트 메서드를 작성한다.
- Feature 내부에 있는 Scenario는 같은 테스트 픽스쳐를 공유한다.
- 픽스쳐란?
- setUp에 공통적으로 사용되는 given 절을 넣어줌
- 가독성 증가
- given절의 모임
- 간단한 성공 케이스 작성
- 테스트가 동작하면 실제 구조에 대해 더 좋은 아이디어를 얻을 수 있음
- When을 먼저 작성
- 내가 무엇을 검증할지 명확하다
- Then
- 어떤 결과를 기대하는지
- Given
- 자연스럽게 Given이 도출된다
- 각 테스트를 메소드로 묶어서 사용
- 문서화 처럼 보일 수 있다
- 재사용 가능
- 너무 길면 ignore 혹은 Disable 처리하고 돌리게 된다
- 테스트의 가독성은 중요하다
- 가독성이 좋지않으면 방치될 수밖에 없음
- 그러면 변경 사항에 대해 수정하기도 힘들다
- 가독성이 좋으면 기능의 스펙을 나타낼 수 있다
- 최대한 쪼개라
- 그렇지 않으면 @Ignore과 @Disable로 범벅이 될 것이다
- 중복 제거 방법
- 메서드 분리
- CRUD 추상화
- 어떻게??
- Cucumber 혹은 JBehave 사용