? 테스트란?
:어떤 대상에 대한 일정 기준을 정해놓고, 그 대상이 정해진 기준에 부합하는지 부합하지 못하는지를 검증하는 과정
1 기능 테스트
:위 그림에서 보면, 기능 테스트의 범위가 제일 큼
:주로 애플리케이션을 사용하는 사용자 입장에서 애플리케이션이 제공하는 기능이 올바르게 작동하는지 테스트
:일반적으로 테스트 전문 부서(QA 부서) 및 외부 QA 업체가 진행
2 통합 테스트
:클라이언트 측 툴 없이 개발자가 짜놓은 테스트 코드를 실행시켜 이루어짐
:애플리케이션의 여러 계층이 연관되어 있어 단위 테스트라고 하기엔 범위가 큰 편임
3 슬라이스 테스트
:애플리케이션을 특정 계층으로 쪼개서 하는 테스트
:API 계층, 서비스 계층, 데이터 액세스 계층이 각각 슬라이스 테스트의 대상이 될 수 있음
:단위 테스트라고 부르기에는 단위가 큰 테스트
4 단위 테스트
:일반적으로 직접 구현하는 핵심 로직 즉, 비즈니스 로직에서 사용하는 클래스들이 독립적으로 테스트하기에 가장 좋은 대상이므로 단위 테스트라고 부르는 경우가 많음
:
Fast 빠르게
:작성한 테스트 케이스는 빨라야함
:자주 돌려야 문제를 빨리 찾는데, 느리면 테스트 케이스 작성 의미 퇴색됨
Independent 독립적으로
:각각의 테스트 케이스는 독립적이어야함
:어떤 테스트 케이스를 먼저 실행시켜도 실행 순서와 관계없이 정상 실행이 보장되어야 함
Repeatable 반복 가능하도록
:어떤 환경에서도 반복해서 실행이 가능해야 한다는 의미
:로컬환경이나 서버 환경에서 실행하든 반복해서 같은 결과를 얻어야 함
Self-validating 셀프 검증이 되도록
:성공 또는 실패라는 자체 검증 결과를 보여주어야 함
Timely 시기 적절하게
:테스트 하려는 기능 구현을 하기 직전에 작성해야 한다는 의미
:구현하고자 하는 기능을 단계적으로 조금씩 업그레이드 하면서 그때그때 테스트 케이스 역시 단계적으로 업그레이드 하는 방식이 더 나음
? JUnit이란?
:테스트 프레임 워크
테스트 대상 클래스
public class StampCalculator {
public static int calculateStampCount(int nowCount, int earned) {
return nowCount + earned;
}
}
StampCalculator 클래스의 calculateStampCout() 메서드에 대한 단위 테스트 코트
public class StampCalculatorTestWithoutJUnit {
public static void main(String[] args) {
calculateStampCountTest();
}
private static void calculateStampCountTest() {
// given
int nowCount = 5;
int earned = 3;
// when
int actual = StampCalculator.calculateStampCount(nowCount, earned);
int expected = 7;
// then
System.out.println(expected == actual);
}
}
결과
false
:테스트 실패함
:계산 결과actual :8 =/= 기대하는 값 expect :7
Given
:테스트를 위한 준비 과정을 명시
:테스트에 필요한 전제 조건이 포함됨
:테스트 대상에 전달되는 입력값(테스트 데이터) 포함
When
:테스트 할 동작/대상을 지정
:단위 테스트에서는 일반적으로 메서드 호출을 통해 테스트를 진행하므로 한두줄 정도로 작성이 끝남
Then
:테스트 결과를 검증하는 영역
:일반적으로 예상하는 값expected과 테스트 대상 메서드의 동작 수행 결과 값actual을 비교해서 기대한대로 동작을 수행하는지 검증Assertion하는 코드가 포함
:테스트 결과를 검증할 때 주로 사용
:예상하는 결과 값이 참이길 바라는 것
테스트 대상
public class StampCalculator {
// (1)
public static int calculateStampCount(int nowCount, int earned) {
return nowCount + earned;
}
// (2)
public static int calculateEarnedStampCount(Order order) {
return order.getOrderCoffees().stream()
.map(orderCoffee -> orderCoffee.getQuantity())
.mapToInt(quantity -> quantity)
.sum();
}
}
:(1) calculateStampCout 테스트 완료
:(2) calculateEarnedStampCount(): 회원이 주문한 주문정보에서 얻게되는 스탬프 개수를 계산하는 기능
calculateEarnedStampCount() 메서드 테스트 코드
public class StampCalculatorTestWithoutJUnit {
public static void main(String[] args) {
calculateStampCountTest(); // (1)
calculateEarnedStampCountTest(); // (2)
}
private static void calculateStampCountTest() {
// given
int nowCount = 5;
int earned = 3;
// when
int actual = StampCalculator.calculateStampCount(nowCount, earned);
int expected = 7;
// then
System.out.println(expected == actual);
}
private static void calculateEarnedStampCountTest() {
// given
Order order = new Order();
OrderCoffee orderCoffee1 = new OrderCoffee();
orderCoffee1.setQuantity(3);
OrderCoffee orderCoffee2 = new OrderCoffee();
orderCoffee2.setQuantity(5);
order.setOrderCoffees(List.of(orderCoffee1, orderCoffee2));
int expected = orderCoffee1.getQuantity() + orderCoffee2.getQuantity();
// when
int actual = StampCalculator.calculateEarnedStampCount(order);
// then
System.out.println(expected == actual);
}
}
:given
:주문한 커피의 수량이 필요하기 때문에
Order와 OrderCoffee 객체 직접 만들어서 테스트에 필요한 데이터 생성
:when
:테스트 대상인 StampCalculator.calculateEarnedStampCount() 메서드에 given에서 생성한 테스트 데이터를 입력값으로 전달
:then
:주문한 수량만큼 스탬프가 계산되는지 Assertion함
결과
false
true
:calculateEarnedStampCount() 테스트 성공
:계산 결과actual :8 = 기대하는 값 expect :8