Server/Node.js

Jest - 테스트 코드간 충돌, 간섭 막는 방법 (매번 테스트 결과가 다를 때 해결 방법!)

JaeHoney 2022. 2. 28. 20:03

테스트 코드 충돌 (간섭)

사내에서 jest + supertest를 이용해서 테스트 코드를 작성하고 있었습니다.

 

그런데, 자꾸 테스트를 돌릴 때마다 한 번씩 테스트가 깨지는 현상이 발생했습니다.

 

알고보니 테스트 코드 파일 A가 다른 테스트 코드 파일 B랑 비동기로 실행되다 보니까 서로 간섭하는 현상이 생기는 것이었습니다.

 

상황

충돌을 일으킨 테스트 2가지는 아래와 같습니다.

  • 카테고리 MVC 테스트
  • 상품 MVC 테스트

프로젝트 구조가 상품 등록 API를 테스트할 때는 먼저 카테고리를 생성한 후에 상품 등록 API에 요청을 보내는 구조였습니다.

 

상품 등록 API는 등록할 카테고리의 id를 받아서, 해당 카테고리가 없으면 예외가 발생하기 때문에 그렇게 설계했습니다.

 

카테고리 MVC 테스트는 각 테스트가 실행될 때 category table을 truncate(모든 데이터 삭제)합니다.

상품 MVC 테스트는 각 테스트가 실행될 때 모든 category table, product table을 truncate(모든 데이터 삭제)합니다.

 

원인

원인을 살펴봤더니 아래와 같은 상황들이 발생하고 있었습니다.

 

1. 카테고리를 생성하지 않고 카테고리id가 1인 카테고리를 삭제시도하고 NOT FOUND(404)가 반환되는지 테스트를 하는데, 상품이 생성될 때 카테고리도 생성되어서 기대와 달리 카테고리가 존재하고 정상적으로 삭제되서(204) 테스트가 깨진 현상

 

2. 수정된 카테고리가 잘 수정되었는지 조회해서 비교하는 테스트가 있었는데, 다른 테스트(상품 MVC)에서 category table을 truncate시켜서, 수정된 카테고리가 존재하지 않게 되어 테스트가 깨진 현상

 

3. 기타 등등..

 

해결 방법

결론부터 말씀드리자면, jest의 옵션 중에 --runInBand라는 옵션을 사용하는 방법이 있습니다.

 

truncate의 시점을 어떻게 바꿔도 데이터가 생성되면서 생기는 불일치 문제는 해결할 수 없었습니다.

가령, 카테고리 순서 변경 API의 경우 요청 배열이 현재 카테고리 수 전체와 다르다면 예외를 일으킵니다. 카테고리 순서 변경을 테스트 하는 중 상품 관련 테스트가 카테고리를 생성하면 테스트가 깨집니다.

 

MVC 테스트를 하나로 합치는 방법도 있지만 그러면 보기가 불편했습니다.

 

Jest의 --runInBand를 사용하면 모든 테스트를 직렬로 실행하기 때문에 충돌이나 간섭을 피할 수 있습니다.

 

그러면, 테스트가 더 오래 걸리는 게 아닌가? 하는 의구심이 들었지만, 생각과 다르게 시간이 거의 비슷했고 모든 테스트가 이제 안깨지고 잘 동작합니다.

 

감사합니다.