-> 이 사람 자료 겁나 잘 만든다. 보고 배우기
- given
- when
- then
컴포넌트 생성 조건 셋팅
페이지 진입 시 라우트에서 아이디 정보를 가져오도록 되어 있는데 정보 가져오지 못하면 에러 모달 띄워주는 상황 테스트
- 적절한 설계 기법
- 공통 테스트 케이스 재사용
- 테스트 케이스 구조 관리
- 테스트 케이스 적절히 분할
제어할 수 없는 값에 의존하는 코드들을 최대한 줄이기
- 제어할 수 없는 값: 함수의 인자로 받도록, 최대한 진입점에 위치, 함수 기본값 혹은 의존성 주입 통해 해결
- 구현 대신 기능을 검증한다.
변하는 것은 구현.
기능을 검증하면 테스트가 깨지지 않는다.
기능이 변경되면 테스트 코드를 먼저 수정하고 깨진 테스트를 고치기 위해 구현 코드를 수정한다.- mock 사용을 ‘지양’한다.
외부와 분리할 수 있다는 장점이 있지만 구현과 강하게 결합되어 있기 때문에 깨지기 쉽다.- 테스트 케이스만 보고 테스트를 이해할 수 있도록 작성한다.
테스트 케이스간 공유하는 객체를 만들지 않는다.
대신 함수로 만들자.
전후 맥락이 필요한 테스트 케이스를 만들지 않는다.
제품 코드에서 export 되는 상수를 참조하여 작성하지 말자.- 상태를 테스트한다.
상호작용 대신 상태를 테스트 한다.
상태를 테스트하는 것보다 출력을 테스트하는 것이 더 좋
1) 공통 테스트 케이스를 만들어 재사용
ex. 푸시 알림에 대한 일반적인 테스트 케이스 정리
: 새로운 프로젝트에서 푸시 알림에 대해 테스트할 필요가 있으면 이 테스트 케이스 사용
2) 테스트 케이스를 구조화 : 리뷰 시간 절약, 테스트 케이스 업데이트 시간 감소
ex. UI - 주요 기능 - UX / 네비게이션 등 특정 요구 사항 - 경험에 비춰볼 때 버그 가능한 부분
=> 전체적으로 설계 구조, 아이디어 더 잘 이해할 수 있어 리뷰 시간, 업데이트 시간 단축 가능
3) 테스트 케이스를 분할 : 시간 절약 위해 작은 테스트 케이스를 큰 테스트 케이스에 결합하는 경우 작은 단계의 실패가 전체 테스트의 실팰로 이어짐. (매번 다 테스트해야 함). 회귀 테스트 진행 시 실제 위험이 되는 건 몇몇 단계일 뿐일 때도 긴 테스트 케이스 전부 실행해야 할 수도
- 적절한 설계 기법
- 공통 테스트 케이스 재사용
- 테스트 케이스 구조 관리
- 테스트 케이스 적절히 분할
- EP-BVA: EP는 동등 분할(Equivalence Partitioning) 기법으로 프로그램의 입력값과 출력값이 특정 그룹으로 돼 있고 분류된 그룹의 값들을 시스템에서 동일하게 취급한다는 특성을 이용한 테스트 기법입니다. BVA는 경곗값 분석(Boundary Value Analysis) 기법으로 동등 분할의 확장 형태입니다.
- 페어와이즈(pairwise): 가능한 모든 입력값의 조합을 테스트하는 대신 짝들의 조합으로 테스트하는 방법입니다.
- 상태 전이(state transition): 어떤 이벤트가 발생했을 때 테스트 대상이 다른 상태로 전이되는 경우의 수를 테스트하는 방법입니다.
출처 : 테스트하기 좋은 코드 - 테스트하기 어려운 코드
경험상 몇번을 수행해도 항상 같은 결과가 반환되는 함수 (멱등성이 보장되는 순수함수) 가 테스트하기 좋은 코드였다.
- Random(), new Date() (LocalDate.now()) 와 같이 실행할때마다 결과가 다른 함수에 의존하는 경우
- readLine 혹은 inputBox 등 사용자들의 입력에 의존하는 경우
- 전역 함수, 전역 변수 등에 의존하는 경우
- PG사 라이브러리등 외부 SDK에 의존하는 경우
전역, 실행 시 결과 다른 함수, 외부 sdk, 사용자 입력
이런 경우 mocking을 해야 수행 가능, 쉽지 않음
ex. 도메인 로직의 경우
- console.log, System.out.println() 과 같은 표준 출력
- Logger 등을 사용하는 경우
- 이메일 발송, 메세지큐 등 외부로의 메세지 발송
- 데이터베이스 등에 의존하는 경우
- 외부 API에 의존하는 경우
테스트하기 어려운 코드와 테스트하기 쉬운 코드를 분리해야만 한다.
둘을 분리해서, 테스트 하기 어려운 코드에 오염되는 영역을 최소화하는 것이 중요하다.
테스트의 어려움은 전파된다
가장 쉬운 방법은 생성자, 함수(메소드)의 인자로 테스트하기 어려운 코드의 결과를 받는 것이다.
이번 같은 경우 Order.discountWith() 에서 제어할 수 없는 값을 외부에서 주입받도록 한다.
export default class Order {
...
discount() {
const now = LocalDateTime.now(); //안에 있던 것
if (now.dayOfWeek() == DayOfWeek.SUNDAY) {
this._amount = this._amount * 0.9
}
}
}
export default class Order {
...
// 현재시간(now)를 밖에서 주입받도록 한다.
discountWith(now: LocalDateTimw) { //인자로 받도록
if (now.dayOfWeek() == DayOfWeek.SUNDAY) {
this._amount = this._amount * 0.9
}
}
}
물론 이렇게 할 경우 함수의 인자가 너무 많아지는 것은 아닌지 부담스럽게 느낄 수 있다.
그럴때는 몇가지 해결책이 있는데,
제어할 수 없는 값에 의존하는 코드들을 최대한 줄이기
- 제어할 수 없는 값: 함수의 인자로 받도록, 최대한 진입점에 위치, 함수 기본값 혹은 의존성 주입 통해 해결
✅ jest-webpack : webpack 다음 jest
✅ emoji.test.js : vue router test
✅ bottomsheet.js 테스트