본문 바로가기
일하는 중에

TypeScript, Unit Test 중 코드 커버리지 실패 원인과 해결

by likebnb 2024. 9. 4.

지난 글에서

    타입스크립트를 사용한 프로젝트에 단위테스트를 적용하면서 겪은 문제와 해결방법을 소개했다. 단위테스트를 위한 기본 구성을 마친 후 실제 테스트 코드를 작성, 기본적인 테스트를 실행해서 구성을 검증했다.

 

단위테스트의 정량적 결과, 코드 커버리지

    테스트 코드를 작성한다는 것은 쌍을 이루는 원래의 코드가 의도한대로 - 정상적으로 - 동작하는지를 검증하기 위함이다. 테스트 프레임워크는 이렇게 작성한 테스트 코드가 원래의 코드를 얼마나 검증(커버)해줬는지를 정량적인 수치로 보고해준다. 참 편리한 도구지만 이 정량적 숫자를 끌어 올리는 것은 오롯이 개발자의 몫이다.

    각설하고 단위테스트를 위한 기본 구성에 코드 커버리지를 위한 추가 구성을 마치고 잘 동작하는 것을 확인한 뒤에 이 구성을 기존 프로젝트(단위테스트를 적용하지 않았던)에 적용했다.   

 

기본 단위테스트 실행은 정상

간단한 테스트 예제 작성 후 vitest run 실행결과

하지만 커버리지는 실패

vitest run --coverage 실행결과, Unhandled Error

뭐지, 예제 프로젝트에선 잘 됐는데...

    매번 느끼는 거지만, 예제는 늘 옳다. 하지만 실전은 온통 - 온갖 예외 상황들이 여기 저기 흩어져 있는 - 지뢰밭이다. 다음과 같이 단위테스트를 실행했을 땐 에러 없이 정상적으로 실행됐다. 

vitest run

    하지만 코드 커버리지를 위해 옵션을 추가하니 Unhandled Error가 발생했다. 오류의 세부내용을 보니 정의되지 않은 속성값을 읽을 수 없단다(Cannot read properties of undefined). 급한 마음에 Undefined 관련 스택오버플로우 글들을 몇 개 찾아서 읽어봤지만 내가 당면한 이 상황과는 딱히 관련이 없어 보였다.

vitest run --coverage

 

호흡을 가다듬고, 문제에서 한 발짝 떨어져서

    오류 메시지를 다시 읽는다. 표면적으로는 undefined properties에 대한 것이지만 그 이면에 있는 맥락을 봐야만 실마리를 찾을 수 있다. 그리고 그 이면을 보려면 오류 메시지를 - 그냥 문자적으로 읽는 것이 아니라 - 자세히 들여다봐야 한다. 오류를 발생시킨 주체와 발생한 시점(파이프라인 중 특정 단계)을 특정하기 위함이다. 거기에 열쇠가 있다.

    이 오류는 기존 프로젝트 코드에서 뱉은 것이 아니라 추가 구성한 @vitest/coverage-v8 모듈에서 뱉은 것이다. 다시 말해 코드 커버리지를 검증하기 위해 프로젝트의 디렉토리를 스캔하는 중에 발생했을 것이다. 생각이 여기에 다다르니 프로젝트의 디렉토리들을 하나씩 열어서 어떤 파일들이 들어 있는지 살펴보게 된다. 그리고 발견한다. 

프론트엔드에서 개발한 정적 리소스들을 배포하기 위해
백엔드에 구성한 public 디렉토리가 문제의 원인이었다. 

아하, 프로젝트를 구성하고 있는 디렉토리가 다르구나! 

    vitest.config.ts 파일의 coverage.exclude에 문제가 된 디렉토리 하위 파일들을 제외하기 위해 "public/**/*"를 추가해줬다.

커버리지 제외 폴더 추가

 

커버리지, 갈 길이 멀구나

    이제 커버리지 옵션이 잘 동작한다. 하지만 코드 커버리지 목표(음,... 80%?)를 달성하려면 갈 길이 멀다.

제외 폴더 추가 후 vitest run --coverage 실행결과

 

 

 

TypeScript, Unit Test를 위한 폴더 구조와 설정

TypeScript, 오호라!   TypeScript를 프로젝트의 주 언어로 사용한지 일 년 쯤 되어 간다. 정확히 말하자면 Node.js를 기반으로 JavaScript를 사용하다가 TypeScript로 전환했다는 것이 맞겠다. 프론트엔드와

likebnb.tistory.com