테스트란 소프트웨어의 관점에서 정의하면
프로그램을 실행하는 경우에 요구 사항에 맞춰 동작하는지 검증하는 행위 라고 할 수 있다.
테스트에는 다양한 종류가 있는데, 보통 범위에 따라서 단위 테스트, 통합 테스트, E2E(End to End) 테스트로 구분할 수 있다.
흔히 개발자가 작성하는 테스트는 모두 단위테스트라고 오해할 수 있는데, 각 테스트 방식마다 고유한 장단점이 있어 잘 구분하여 상황에 맞게 적절한 방식을 선택해야 한다.
소스 코드의 특정 모듈이 의도된 대로 정확히 작동하는지 검증하는 절차다. 즉, 모든 함수와 메소드에 대한 테스트 케이스를 작성하는 절차를 말한다.
보통 레이어 단위(Controller, Service, Repository)로 혹은 특정 클래스에 대해서 정상적으로 동작하는지 확인하는 것으로 핵심적인 테스트라고 할 수 있다.
자바에서는 보통 단위 테스트로 Junit이라는 도구를 사용하여 테스트한다.
@Test
public void moveCar() {
Car car = new Car("xeropise");
car.move();
assertThat(car.getPosition()).isEqualTo(2);
}
모듈이 의존성을 가지는 경우, 의존하는 모듈을 Mock이라는 가짜 객체로 만들어 특정 행동 및 결과값이 나오도록 정의한 후 테스트할 수 있다.
Mock 객체는 다음과 같은 상황에 사용할 수 있다.
단위 테스트와 달리 개발자가 변경할 수 없는 부분 (외부 라이브러리, 데이터베이스) 까지 묶어서 같이 검증할 때 사용하는 테스트이다.
보통 독립된 2개 이상의 모듈이 동시에 동작하는 경우에 테스트하며 모듈 간의 연결에서 발생하는 에러를 검증할 수 있다.
단일 모듈이 복잡한 알고리즘이나 분기문을 가지고 있다면, 단위 테스트에 비해 테스트가 번거롭고, 테스트 중복이 발생할 확률이 높다.
SpringBootTest도 모든 모듈이 제대로 초기화되는지 확인하는 과정이므로 통합테스트라고 할 수 있다.
@SpringBootTest
class ApplicationTests {
@Test
void contextLoads() {
}
}
테스트는 다양한 방법이 있는데 나는 MockMvc를 이용하여 테스트 하였다.
애플리케이션의 흐름을 처음부터 끝까지 테스트하는 것을 말한다.
유닛 테스트나 통합 테스트의 각 모듈이 정상 동작함을 증명할 수 있지만, 애플리케이션의 동작까지 모두 정상 동작하다는 것을 증명해 줄 수는 없다.
실제 사용자의 사용 시나리오를 테스트함으로써 애플리케이션 동작을 테스트하고, 이 테스트를 통과함으로써 애플리케이션이 제대로 동작함을 보장하는 것이다.
가령 유저가 유저 정보를 조회한다고 하면, 계정을 등록하고, 로그인하는 과정이 먼저 수행되어야 한다.
@Test
public void user_search_test() throws Exception {
String account = "xeropise";
String password = "1234";
String email = "whrbql1@gmail.com";
// 계정 등록
reigster_first(account, password, email).andExpect(MockMvcResultMatchers.status().isCreated());
// 로그인
MvcResult result = login(account, password).andExpect(MockMvcResultMatchers.status().isCreated()).andReturn();
ObjectMapper objectMapper = new ObjectMapper();
ApiResponse<TokenResponse> response = objectMapper.readValue(result.getResponse().getContentAsString()
, new TypeReference<ApiResponse<TokenResponse>>() {
});
String accessToken = response.getBody().getAccessToken();
UUID userId = response.getBody().getUserId();
// 조회
search(accessToken, userId).andExpect(MockMvcResultMatchers.status().isOk());
}
다만, 테스트에 비용이 많이 들기 때문에 꼭 필요한 만큼만 테스트를 수행해야 한다.
참고한 책 및 사이트
https://heegs.tistory.com/16
https://openclassrooms.com/en/courses/5661466-use-testing-in-java-to-achieve-quality-applications/6291356-mock-more-use-cases-with-mockito
https://velog.io/@ongsim123/TIL-Unit-test-Integration-test-e2e-test-%EA%B7%B8%EB%A6%AC%EA%B3%A0-TDD
https://fe-developers.kakaoent.com/2023/230209-e2e/