테스트 범위
테스트 범위
웹 애플리케이션은 여러 모듈을 조합해 만든다.
한 가지 기능을 구현할 때 구성되는 모듈들
1.라이브러리가 제공하는 함수
2.로직을 담당하는 함수
3.UI 관련 함수
4.웹 API 클라이언트
5.API 서버
6.데이터베이스 서버
테스트를 작성할 때는 어디부터 어디까지 커버하는 테스트인지 주의해야 한다.
테스트 범위는 크게 네가지로 분류된다.
정적 분석
타입스크립트나 ESLint가 제공하는 기능을 활용
각 모듈 내부의 검증뿐만아니라 (2.로직을 담당하는 함수 ~ 3.UI 관련함수 검증), (3.UI 관련함수 검증 ~ 4.웹 API 클라이언트) 검증처럼 인접 모듈을 연계해 사용할 때의 문제점도 검증한다.
단위 테스트
한 가지 모듈에 한정하여 해당 모듈이 제공하는 기능을 검증하는 가장 기초적인 테스트
독립된 환경에서 검증하기 때문에 실제 애플리케이션을 사용할 때는 거의 발생하지 않는 케이스*(코너 케이스)검증에 적합
코너케이스에 한해서만 예외를 발생시키는 것이 나은 경우도 있다.
어떤 상황에서 예외를 발생시켜야 할지 판단할 때 도움이 된다.
'이런 상황은 일어날 수 없을까? 일어날 수 있다면 어떻게 처리해야 하는가'와 같은 거듭된 검토 과정에서 미처 고려하지 못했던 부분을 발견할 수 있다.
ex: 다른 입력 패턴은 없나?, 예외처리는 충분한가..?
테스트할 모듈이 특정 입력값을 받아 기대하는 출력값을 반환하는지 테스트
UI 컴포넌트는 입력값(props)에 알맞은 출력값(HTML 블록)을 반환하기 때문에 일반적인 함수와 같은 방법으로 테스트할 수 있다.
단위 테스트로 함수가 고려하지 못한 부분이 없는지 검증
통합 테스트
여러 모듈을 연동한 기능을 테스트
1.라이브러리가 제공하는 함수 ~ 4.웹 API 클라이언트, 2.로직을 담당하는 함수 ~ 3.UI 관련 함수 처럼 모듈 조합으로 제공되는 기능을 검증하는 테스트
범위가 넓어질수록 효율적인 테스트가 가능하지만 상대적으로 대략적인 검증에 그치게 된다.
커다란 UI 컴포넌트는 여러 모듈을 조합해 기능을 제공하며, 기능은 주로 인터렉션에서 시작된다.
셀렉트 박스 조작 *(인터렉션)
URL 검색 쿼리 변경됨
검색 쿼리가 변경되어 데이터 취득 API 호출됨
목록 화면 내용 갱신
즉, 셀렉트 박스 조작을 실행하면 목록 화면 내용도 갱신된다.를 테스트 하는 것
코너 케이스 때문에 테스트가 복잡해지면 범위를 좁혀서 통합 테스트를 실시해야 테스트 목적이 명확해진다.
E2E 테스트
UI 테스트 뿐만 아니라 외부 스토리지와 같이 연동 중인 하위 시스템을 포함하는 테스트
1.라이브러리가 제공하는 함수 ~ 4.웹 API 클라이언트 검증을 통틀어 헤드리스 브라우저와 UI 자동화 도구를 결합하여 검증하는 테스트
가장 광범위한 통합 테스트
실제로 애플리케이션을 사용할 때와 가장 유사한 테스트
입력 내용에 따라 저장된 값이 갱신되기 때문에 UI는 물론 연동된 외부 기능이 정상적으로 작동하는지 검증할 수 있다.
테스트 목적
테스트 타입은 테스트 목적에 따라 분류됨
테스트 분야에서 많이 알려진 테스트 타입은 기능 테스트, 비기능 테스트, 화이트 박스 테스트, 회귀 테스트 등이 있다.
테스트 타입은 검증 목적에 맞게 설정해야 하며, 테스트 타입마다 적절한 테스트 도구가 있다.
기능 테스트 (인터렉션 테스트)
개발된 기능에 문제가 없는지 검증하는 테스트
웹 프론트엔드의 대부분 기능은 UI 컴포넌트 조각(인터렉션)에서 시작되기 때문에 주로 인터렉션 테스트가 기능 테스트가 될 때가 많고 중요하다.
웹 프런트는 사용자가 조작할 UI 컴포넌트를 개발하기 때문에 인터렉션 테스트가 대부분
실제 브라우저 API를 사용하는 것이 중요한 테스트라면 헤드리스 브라우저와 UI 자동화 도구를 사용하는 것이 좋음
UI 컴포넌트에는 브라우저 없이도 테스트할 수 있는 가상 브라우저 환경이 있음
실제 브라우저가 없어도 가능한 인터렉션 테스트 사례
버튼을 클릭하면 콜백 함수 호출됨
문자를 입력하면 전송 버튼이 활성화됨
로그아웃 버튼을 클릭하면 로그인 화면으로 이동함
*But 가상 브라우저만으로는 스크롤이나 세션 스토리지같은 기능은 테스트할 수 없다. 실제 브라우저가 없으면 수행하기 어려운 기능의 테스트는 헤드리스 브라우저와 UI 자동화 도구를 사용한다.
실제 브라우저가 필요한 인터렉션 테스트 사례
맨 아래까지 스크롤을 내리면 추가 데이터를 가져온다.
세션 스토리지에 저장된 값을 불러온다.
비기능 테스트(접근성 테스트)
접근성 테스트는 비기능 테스트의 한 종류
신체적, 정신적 차별없이 동등하게 제품을 사용할 수 있는지 검증하는 테스트
최근 전 세계적으로 웹 접근성 관련 API가 여러 플랫폼에 추가되어 테스트 자동화를 할 때 객관적으로 검증할 수 있는 환경이 갖추어짐
마찬가지로 접근성 테스트는 기능 테스트와 동일하게 가상 브라우저와 실제 브라우저를 사용하여 테스트 진행
같은 도구를 사용하면 기능 테스트의 초보자가 접근성 품질을 높이는 출발점으로 삼는데 도움됨
접근성 테스트 실제 사례
(키보드로) 체크 박스를 체크할 수 있다.
오류 응답을 받았을 때 오류 문구를 렌더링한다.
렌더링된 화면에 접근성 위반사례가 있는지 검사한다.
(시각적) 회귀 테스트
특정 시점을 기준으로 전후 차이를 비교하여 문제가 있는지 검증하는 테스트
웹 프론트엔드는 시각적으로 보이는 UI 컴포넌트를 개발하기에 시각적 회귀 테스트가 중요하다.
CSS(종속형 시트)는 UI 컴포넌트에 정의된 스타일뿐만 아니라 브라우저에 적용된 모든 스타일의 영향을 받는다.
회귀 테스트 중 하나인 시각적 회귀 테스트에서는 헤드리스 브라우저에 그려진 내용을 캡처하여 캡처된 이미지 간 차이를 검증한다.
초기에 렌더링된 상태만 캡처하여 비교하는 것에 그치지 않고 사용자 조작으로 변경된 화면까지 캡처하여 비교
시각적 회귀 테스트 사례
버튼 스타일에 차이가 없다.
메뉴 바를 열었을 때 화면에 차이가 없다.
렌더링된 화면에 차이가 없다.
테스트 전략 모델
단위테스트 < 통합 테스트 < E2E 테스트
낮은 유사성, 짧은 실행시간, 높은 안정성 <<< 높은 유사성, 긴 실행시간, 낮은 안정성
상층부 테스트는 많은 시간과 비용이 발생한다.
테스트용 데이터베이스 서버 구축 및 실제 환경과 최대한 유사한 환경을 구축해야 한다.
테스트할 때마다 제품과 연동된 외부 시스템의 응답도 기다려야 하기에 다른 테스트보다 긴 실행 시간이 걸린다.
테스트 계층 간 비용 분배는 테스트 전략을 세울 때 가장 중요한 검토 사항이다.
아이스크리미 콘 (역 피라미드)
상층부 테스트의 비중이 높은 아이스크림 콘은 안티패턴으로 자주 언급되는 테스트 전략 모델이다.
운용 비용이 높을 뿐만 아니라 외부 모듈의 의존성 때문에 아주 가끔식 실패하는 불안정한 테스트가 비교적 많다.
만약 모든 테스트가 통과되는데 수십 분이 상이 걸리면 개발 흐름에 나쁜 영향을 주게 되며 더 나은 개발 환경을 만들고자 테스트를 자동화한 것이 오히려 개발 경험을 해치는 상황이 발생한다.
그러나 실행 시간을 줄이려고 실행 빈도를 줄이면 테스트 자동화의 신뢰성은 낮아진다.
테스트 피라미드
하층부 테스트의 비중이 높을수록 더욱 안정적이고 가성비 높은 테스트가 가능하다는 것이 핵심
하층부는 실행 시간이 짤방 신속성이 높고, 자주실행할 수 있어서 안정성도 높다.
프론트엔드 테스트 자동화에도 테스트 피라미드가 우수한 전략이라는 의견이 지배적
테스팅 트로피
켄트 도즈(Kent C Dodds)가 만든 테스트 전략 모델
통합 테스트 비중이 가장 높아야 한다는 것이 핵심
프론트엔드 개발에서 단일 UI 컴포넌트로 구현되는 기능은 거의 없다.
테스팅 트로피에는 사용자 조작을 기점으로 한 통합 테스트 비중이 높을수록 더욱 우수한 테스트 전략이라는 의도가 있음
테스팅 라이브러리와 제스트를 사용하면 헤드리스 브라우저 없이도 사용자 조작을 재현해 테스트할 수 있어서 실행 속도가 빠르면서도 실제 제품과 유사한 테스트가 가능하다.
테스트 전략 계획
테스트 전략 모델을 참고해 프로젝트에 최적인 전략을 수립하려면 테스트 대상 및 목적에 따른 판단 기준을 정립해야 한다.
테스트가 없어 리팩터링이 불안한 경우
릴리즈된 프로젝트에 테스트 코드가 없으면 리팩터링이 불안할 수 있다.
이때는 먼저 릴리즈된 기능을 목록으로 정리해야 한다.
정리가 됐다면 변경 전후로 결함이 발생하지 않았는지 검증하는 회귀 테스트를 작성해야 한다.
작성된 회귀 테스트가 있다면 자신있게 리팩터링을 시작할 수 있다.
웹 API 서버에 대한 의존성이 깔끔하게 분리되지 않았다면 테스트 작성이 어렵다.
이 때 목 서버를 활용하여 통합 테스트를 실시한다.
목 서버를 활용하면 구현 코드를 수정하지 않아도 테스트할 수 있어 리팩터링 시작전에 테스트를 작성하고 싶은 개발자에게 유용하다. * 특히 릴리즈된 프로젝트에서 효과적
통합 테스트가 늘어날수록 안심하고 리팩터링할 수 있는 기능이 많아진다.
점진적으로 테스트를 늘리면서 리팩터링을 실시하면 더욱 안정된 테스트 피라미드 모델을 만들 수 있다.
반응형으로 제작된 프로젝트
반응형 웹은 하나의 HTML에서 다양한 디바이스에 알맞은 화면을 제공한다.
반응형 웹은 테스팅 라이브러리만으로는 스타일을 포함한 세밀한 테스트가 어렵다.
반응형처럼 디바이스 간 서로 다른 스타일을 제공하는 경우, CSS가 적용된 렌더링 결과를 검증할 브라우저 테스트가 필요함
이런 상황에서 실시하는 테스트가 브라우저를 사용한 시각적 회귀 테스트
스토리북은 UI 컴포넌트 단위로 시각적 회귀 테스트가 가능하다.
반응형으로 프로젝트를 제작해야 한다면 스토리북을 사용해서 테스트를 작성하는 것이 효율적
Storybook -> reg-suit를 활용한 시각적 회귀 테스트
데이터베이스를 포함한 E2E 테스트가 필요한 경우
목서버가 아닌 실제 웹 API 서버를 사용해서 E2E 테스트를 하고싶다면 테스트용 스테이징 환경을 사용해야 한다.
스테이징 환경이란 실제로 배포할 환경에 가까운 형태로 만든 테스트용 환경을 의미
E2E 테스트는 테스트 엔지니어가 프로젝트를 릴리즈하기 전에 테스트 계획서를 보면서 수동으로 하는 경우가 많고, 브라우저를 사용한 UI 자동화 방식으로 테스트하는 경우도 있다.
브라우저를 사용한 UI 자동화는 아이스크림 콘 모델에 가까운 테스트 전략이 되기 쉽다.
명확한 목적을 가지고 더욱 작은 범위의 테스트로도 괜찮은지 먼저 검증해야 한다.
스테이징 환경을 만들지 않고 개발자 혼자서 실시할 수있는 테스트 자동화 방법 with 도커 컴포즈
테스트할 시스템을 컨테이너화해 CI 환경에서 실행한 후 연동중인 여러 시스템과 함께 테스트 하는것
비교적 환경 구축 비용이 적고 개발자 혼자서도 구축할 수 있는 장점이 있다
컨테이너를 활용해 테스트하려면 E2E 테스트 프레임워크의 사용법 및 컨테이너 가상화 지식, 연관 시스템 설정 지식이 필요
주의사항
테스트를 너무 많이 작성하고 있는지 되돌아보기
테스트 타입 및 전략은 무수히 많고 여러 종류의 테스트를 작성하다 보면 테스트 범위가 중복되는 것을 발견할 수 있다.
스토리북이나 E2E 테스트가 중요한 프로젝트라면 UI 컴포넌트 테스트는 오류 패턴을 검증하는 것으로 충분하다는 결정을 내릴수도 있다.
테스트 범위 중복은 테스트를 활발히 작성하는 시기에 발견된다.
이전에 기능을 개발하기 위해 작성된 테스트 규모는 새 기능을 개발할 때 어느정도로 테스트를 작성해야 하는지 결정하는 참고 지표로 활용된다.
이 참고 지표는 팀에 일정 규모 이상의 테스트를 작성하도록 유도한다.
지나치게 많이 작성한 테스트를 발견했다면 과감하게 줄이자.
프로젝트에 알맞은 기술 구성은 무엇이며 어떤 테스트 전략이 프로젝트에 적합한지 항상 되돌아보자.
Last updated