우아한테크코스 레벨2 기간에 학습한 E2E 테스트 강의 내용을 정리한다.
미션을 진행하면서 여러가지 의문이 들 수 있다.
Q. 컨트롤러는 어떻게 테스트할까?
Q. 웹 기반에서는 어떻게 테스트할까?
위와 같은 의문을 가지고 답을 고민하면서 글을 읽으며 본인만의 답을 찾아보자!
spring-boot-starter-test
안에는 junit에 대한 라이브러리가 존재한다.@SpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE
@WebMvcTest
@SpringBootTest
보다 가볍게 테스트할 수 있다.@JdbcTest
@Transactional
어노테이션을 포함하고 있기 때문에 기본적으로 각 테스트마다 Rollback된다.테스트들의 종류, 즉 테스트의 목적이 존재하지만 경계를 구분하기 어려운 경우도 존재한다는 것을 인지하고 가자
단위는 어떤 메소드 혹은 어떤 클래스가 될 수 있다.
단위에 대한 정의에서 공통적으로 이야기하는 것은 가장 최소한의 개념
이다. (가장 작은 단위 혹은 범위)
@DisplayName("지하철역 정보를 수정한다.")
@Test
void updateStation() {
// given
Station station = new Station("강남역");
// when
station.updateStation("판교역");
// then
assertThat(station.getName()).isEqualTo("판교역");
}
위의 코드에 대해서는 이견이 없을 것이라고 생각한다. 하지만 협력 객체를 사용해야 하는 경우에는 개발자들마다 어떻게 단위 테스트를 수행할 것이냐에 대해서는 의견이 나뉠 수 있다.
@DisplayName("구간을 추가할 수 있다.")
@Test
void addSection() {
// given
Station station1 = new Station("강남역");
Station station2 = new Station("잠실역");
Station station3 = new Station("역삼역");
Line line = new Line("2호선", "green", station1, station2, 10);
// when
line.addSection(station2, station3, 5);
// then
assertThat(line.getStations()).containsExctlyElementsOf(Arrays.asList(station1, station2, station3));
}
즉, 위와 같이 station 뿐 아니라 Line 그리고 그 안에서는 또 Section과 같이 여러 객체가 협력하는 경우에는 어떻게 단위
라는 개념을 나누고 단위 테스트
를 진행할 것이냐 하는 고민이 있을 수 있다.
두 객체가 서로 연관된 객체라면 둘 다 실제 객체를 사용해서 테스트하자라는게 Sociable Tests
이고, 연관된 객체를 고립시켜서 연관 객체에 대해서는 Mock과 같은 가짜 객체를 주입해서 테스트하자는 것이 Solitary Tests
이다.
출처 : Solitary or Sociable? Testing Events and Listeners using Laravel
무엇이 옳다고 이야기하는 것은 적절하지 않다고 생각한다. 단지 단위
라는 개념을 어떻게 받아들이냐에서 차이가 존재한다고 생각한다.
독립된 단위가 서로 연결될 때 올바르게 작동하는지를 확인하는 테스트이다.
통합 테스트는 요청부터 DB까지 갔다가 응답까지의 흐름(flow)를 모두 통합이라고 보는 넓은 의미에서의 경우가 있을 수 있고, 좁은 의미에서 통합 테스트는 애플리케이션과 DB 연결을 확인하거나 다른 서비스와 잘 연동되는지를 확인하는 경우를 말할 수도 있다.
하지만 독립된 단위
가 서로 연결되어 잘 동작하는지를 확인하는 목적
이라는 점에서는 공통된다.
E2E(End-to-End) Test의 목적은 끝(End)에서 끝(End)까지 다 검증하려는 것에 있다.
앞서 보인 지하철역을 생성하는 테스트의 경우가 E2E 테스트의 예시로도 볼 수 있다.
그리고 여기에서 보인 AcceptanFixture.post()
메소드는 사실 다음과 같은 코드이다.
RestAssured.given().log().all()
.body(params)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.when()
.post("/stations")
.then().log().all()
.extract();
즉, RestAssured
라는 것을 활용하여 테스트한 것이다.
RestAssured는 REST Assured Java 라이브러리를 사용하여 애플리케이션의 HTTP EndPoint에 초점을 맞춘 테스트 도구이다.
즉, 우리는 RestAssured를 사용해서 애플리케이션으로 오는 요청과 응답에 대해서 테스트할 수 있는 것이다. 즉, 애플리케이션의 HTTP EndPoint에 초점을 맞춰서 테스트를 할 수 있게 된다.