2019. 8. 6. 11:37ㆍFrontend
F/E의 Test
Test란?
애플리케이션이 요구 사항에 맞게 동작하는지를 검증하는 행위
- QA(Quality Assuarance)
- 프로토타입 UX 검증 및 개선,
- 서버 API 호출 및 확인
- 특정 작업 이후 UI 변경 사항 확인
등의 모든 작업들...
Test 종류
1. 단위 테스트
작은 단위(주로 모듈 단위)를 전체 애플리케이션에서 떼어 내어 분리된 환경에서 테스트하는 것
장점
- 세밀한 부분까지 테스트 가능
- 빠르게 실행 가능
단점
- 의존성 있는 모듈 제어를 위해 모의 객체를 무조건 사용해야 하며, 이 경우에도 잘 연결되어 상호작용하는지 검증하지 못한다
- 작은 단위의 리팩토링에도 쉽게 깨진다
2. 통합 테스트
단위 테스트보다 좀 더 넓은 범위의 테스트로, 주로 두 개 이상의 모듈이 상호 작용하는 것을 테스트하는 것
장점
- 비교적 모의 객체 사용이 적으며, 리팩토링을 해도 쉽게 깨지지 않는다
- 모듈 간 연결시 발생하는 에러 검증 가능
단점
- 복잡한 알고리즘 및 분기문을 가질 때 비교적 테스트가 번거롭고, 중복이 발생할 확률이 높다
3. E2E 테스트
내부구조를 모르는 사용자의 관점에서 테스트를 진행, 기능 혹은 UI 테스트라고 불린다
장점
- 실제 상황에서 발생하는 에러를 사전 발견 가능 (환경 유사)
- 브라우저 외부에서 직접 제어하는 테스트 가능 (js로 확인 불가한 에러 사항)
- 브라우저의 구체적인 행위까지 제어 가능
- 큰 범위의 리팩토링에도 깨지지 않음 (테스트 코드가 전혀 실제 내부 구조에 영향 받지 X)
단점
- 비교적 실행 속도가 느려, 빠른 피드백 받기 어려움
- 여러 상황을 조합해야 해서 테스트 코드 작성이 어려움
- 기능을 세분화 할 수 없어 코드의 중복이 발생함
- 예상치 못한 문제(네트워크 오류 등)으로 실패하는 일이 종종 있어 100% 신뢰할 수 없음
대표 도구
Selenium Webdriver
: E2E 테스트 도구 중 가장 널리 사용, but 단점 그대로 가짐Cypress
,TestCafe
: 최근 등장, E2E 단점 최소화
WebDriver
- 통일된 API를 기반으로 브라우저를 제어하기 위해 만든 HTTP 기반의 프로토콜
- 브라우저(서버 역할) + 제어 요청 기기(클라이언트 역할)
자동화 테스트
결국 테스트는 반복되는 작업
이를 자동화하여
- 비용 줄인다
- 실수 방지
- 적극적인 리팩토링 가능
- 결국, 코드 품질은 향상된다.
하지만, 이에 너무 집착하다보면 주객전도 되어 기회비용이 증가할 수 있다.
따라서, 기회비용이 더 큰 불필요한 TEST 코드는 없애는 방향을 유지한다.
좋은 테스트 코드
- 빠른 실행속도
- 내부 변경에도 영향을 받지 않는 코드(낮은 결합도)
- 버그 검출 가능한 코드 (구체적인 테스트 명세)
- 안정적인 테스트 결과(언제나 동일한 결과를 보장)
- 명확한 의도 (사람이 볼때 한번에 무슨 의도인지 파악 가능)
테스트 전략
모든 상황에 맞는 득과 실을 잘 따져서, 적합한 테스트 도구를 사용해 전략을 세우는 것이 중요하다.
최신 테스트 도구를 사용해 시각적 요소 VS 상태 관리를 분리하여 더 나은 테스트 전략을 세울 수 있다.
1. 시각적 요소 TEST
HTML 비교하기
예상되는 화면의 HTML을 직접 작성하여 문자열을 통해 비교한다.
스냅샷 테스트 (HTML)
- 사용도구
- JEST, ...
- 예상되는 코드를 미리 작성 X
- 처음 실행된 결과물을 파일로 저장해두는 방식 사용
- 그 이후 테스트 실행시마다 저장된 파일의 내용을 비교 (회귀 테스트)
- 예상 결과를 직접 코드로 관리해야하는 번거로움을 없애줌
###
테스팅 도구
구분
Test Runner
테스트를 구동할 수 있는 환경을 제공
특징
- 테스트 파일을 읽어들여 작성한 코드를 실행
- 결과를 특정한 형식으로 출력해줌
Reporter
를 지정해 원하는 형태로 출력 가능
- 부가적으로 코드 변경시 테스트를 자동 실행하는
Watcher
기능 제공
대표 도구
- 브라우저에서 코드를 직접 실행
Karma
- Node.js 환경에서 코드를 실행 (테스트 프레임워크와 통합된 형태로 제공)
Jest
Test Framework
테스트 코드 작성을 위한 기반을 제공해주는 js 도구
특징
- 프레임워크 제공 함수를 사용해서 테스트 도구를 작성
- 함수 예 :
describe
,beforeEach
,it
,expect
- 함수 예 :
- 프레임워크가 테스트 코드를 자동 실행 후 결과를 반환
대표 도구
Mocha
,Jasmine
,AVA
,Jest
Test Mathcer(단언)
테스트 코드를 좀 더 편리하게 작성할 수 있도록 도와줌
특징
테스트 코드 = 초기화 + 단언
- 단언은 개별 테스트가 통과하기 위한 조건을 명확히 기술하기 위해 사용됨
test('테스트 설명', () => {
expect('검증 대상').toXxx('기대 결과');
});
에서 기본형 비교를 위한 toXxx
부분에 사용되는 함수
- 자연어에 가까운 BDD(Behavior-driven development)방식의 API가 사용 (
Chai
,Jasmine
)- 초기엔
Junit
(java
단위 테스트 도구)과 유사한 방식의 API를 많이 따름
- 초기엔
- 대부분 자신만의 단언을 추가해 사용할 수 있는 플러그인 확장 기능 제공
Karama
,Buster.js
대표 도구
- 테스트 프레임워크에서 다양한 방식의 단언 API를 제공
Chai
,Jasmine
,AVA
,Jest
- 별도 단언 라이브러리 사용 권장
Mocha
Test Double (Mock, Spy, Stub...등 모의)
모의란 실제 객체 대신 테스트를 위해 동작하는 객체로, 분리된 단위 테스트를 통해 외부 의존성 주입 가능
특징
- spy, stub, mock 등의 다양한 테스트 더블을 쉽게 만들 수 있도록 도와줌
- spy : 객체의 특정 메서드가 호출 된 적이 있는지, 어떤 인자가 넘어왔는지 검증
- stub : 테스트가 어려운 코드를 대체, 다른 코드 경로를 트리거하는데 사용, 비동기 코드 테스트 단순화
- mock : 원하는 결과를 정의하여 비교
- 일반적으로 js 객체 또는 함수를 직접 변경하거나 생성하는 형태로 사용
- 모듈 단위로 사용할 수 있는 기능 제공 :
Jest
- js의 타이머 API 직접 제어하며 테스트 :
Jasmine
,Sinon.js
대표 도구
- 테스트 프레임워크에서 다양한 방식의 단언 API를 제공
Chai
,Jasmine
,AVA
,Jest
- 별도 단언 라이브러리 사용 권장
Mocha
컴포넌트 단위 테스트
Vue
, React
와 같은 경우 컴포넌트 단위로 개발이 이루어짐Storybook
은 컴포넌트 단위의 개발 환경을 지원하는 도구이다.
특징
- 뷰 개발시 고립된 환경을 제공, 관심사를 의존성과 환경으로부터 분리시킨다.
- 따라서, 외부 상태에 의존하지 않고 고립된 상태에서 컴포넌트 개발을 할 수 있다.
테스트 실행 환경
브라우저
브라우저를 통해서 테스트 코드를 실행
- E2E 테스트 도구를 제외하고는
Karma
(테스트 러너)를 사횽하는 것이 유일한 방법- 별도의 테스트 프레임워크 추가 필요 (
Jasmine
사용 권장)
- 별도의 테스트 프레임워크 추가 필요 (
장점
- 브라우저의 모든 기능(네트워크 IO, 렌더링 엔진 등)을 활용한 테스트 가능
- 동일한 테스트 코드를 다양한 환경에서 실행할 수 있음 (
Selenium
등 활용) - 브라우저 호환성 및 기기 환경에 대한 테스트 진행 가능
단점
- 초기 구동 속도가
Node.js
에 비해 느림- 개선 : 헤드리스 브라우저를 사용한 빠른 피드백
- 브라우저라는 별도의 app실행을 위해 런처를 추가 설치해주어야 함
- 크로스 브라우징 테스트 등의 테스트시 별도 환경 구축괴 유지보수 필요
- 모듈 단위의 테스트를 위해선
webpack
등의 번들러를 사용해야 한다 - 개선 : 완료/배포시에만 CI 서버와 통합해 크로스 브라우징 테스트
- 개선 : 환경 구축 대신 외부서비스를 사용해 Karma 연동
- 모듈 단위의 테스트를 위해선
Node.js
- 최근 가장 많이 쓰이는 도구
Mocha
,Jest
- 테스트 러너 + 테스트 프레임워크 통합 => 설치 및 실행이 비교적 간단
장점
- 빠른 속도 (
Node.js
의 프로세스가 훨씬 빨라서) - 훨씬 간단하고 안전한 방식으로 테스트 가능
- 개별 프로세스에서 원하는 모듈만
import
하여 테스트 가능
- 개별 프로세스에서 원하는 모듈만
단점
- 브라우저의 모든 API를 제대로 활용할 수 없다는 것
DOM(Document Object Model)
이나BOM(Brower Object Model)
등의 API 미제공- 개선 : 가상으로 브라우저 환경 구현 (
jsdom
)사용. but 100% 구현 X- 렌더링 엔진 X -> UI 요소의 레이아웃 테스트 X
- 네비게이션 관련 동작 X
- 크로스 브라우징에 대한 테스트 X
앞으로 사용할 Test 도구 =>
Node.js
- 브라우저 환경 굳이 필요 X
- 크로스 브라우징 테스트 X
- 브라우저 실제 동작(렌더링, 네트워크 IO, 내비게이션 등)의 테스트가 많이 필요하지 않을 것으로 판단됨
Tool 비교
구분 | Mocha | Jasmine | Jest | Karma | 기타 |
---|---|---|---|---|---|
구조적 테스트 제공 | O | O | O | X | |
테스트 구동환경 제공,Test Runner | O | X | O | O | |
단언문 제공 | X | O | O | X | Chai |
목, 스파이, 스텁 제공 / Test Double | X | O | O | X | Sinon.JS |
코드 커버리지 리포트 생성 | X | X | O | X | Istanbul |
비동기 지원 | O | O | O | X |
F/E Testing Tool 선호도
2018.stateofjs에서 선호도 조사를 실시한 결과가 자세히 나와있다.
대중적인 조합
- 브라우저 :
Karma + Jasmine
- Node.js :
Jest
orMocha + Chai + Sinon.js
Jasmine
- BDD 스타일의 단언 API를 사용하는 통합 테스크 프레임워크
장점
- 비동기 코드 테스트 지원
- 모든 환경에서 사용가능 (Node.js & 브라우저)
- 별도 라이브러리 설치 필요 X
- 테스트 명세를 그룹화 할 수 있다 (목적에 맞게 묶어 관리 가능)
- 비교적 빠른 테스트
Mocha
- 다른 모의 라이브러리를 함께 사용할 수 있음
- 즉, 단언 라이브러리를 따로 설정해주어야 함.
장점
- 유연하다 (어느 라이브러리와도 함께 사용될 수 있다.)
- 간단하고 명료한 API
- 비동기 테스트 코드 지원
- 테스트 실행이 빠름
- 보다 높은 사용성
단점
- 자동모의나 스냅샷 테스트 미지원
- 설치(환경 구성이)가 까다롭다.
- 비교적 비동기 테스트 지원이 적다
Karma
- 실제 브라우저에서 테스트를 실행할 수 있도록 도와줌
실행방식
- 커맨드 라인에서 Karma 실행시,
웹서버 구동
->HTML 페이지 생성
->모든 코드 로드
- 브라우저 직접 실행 후 접속하면 로드된 코드가 실행되어 실행 결과가 브라우저 콘솔에 출력됨
- Karma는 해당 정보를 지정된 리포터를 통해 정리한 후, 커맨드 라인에 결과 보여줌
-
테스트 커버리지
lstanbul
lib로 설치해 측정 가능coverage
폴더 안 브라우저 런처 별 폴더 생성index.html
을 열어 측정 결과 확인
-
크로스 브라우징 테스트 가능
- 로컬 PC에서도 다양한 브라우저에 대한 테스트 동시 실행 가능
장점
- 오래된 브라우저나 브라우저 간 호환성을 지원해야할 때 좋음
- 웹 드라이버 등으로 원격 테스트 가능
- 여러 브라우저 동시 테스트 가능 (
Selenium
등 도구 설치 및 간단한 코드 설정 필요) - 모든 브라우저 지원
단점
- 브라우저에 너무 특화되어있음
Jest 가장 좋아 보임
- facebook에서 만든 lib
- 최근 안정성 및 성능이 눈에 띄게 좋아지면서 주목 받음
- Testing Framework (All-in-one 테스팅 라이브러리)
- 이전에 따로 조합해야 했던 Test Runner, Test Mathcher, Test Mock 프레임워크를 한번에 제공해준다.
- 내부적으로
Jamine
스타일의 단언 API를 사용 test.js
로 끝나거나__test__
디렉토리 안의 파일들을 테스트 파일로 자동 인식함- 특정 테스트를 수행하려명
npm test <경로를 포함한 파일명>
장점
- 빠른 속도 (
Node.js
기반) + 각 모듈 분리 => 안전- 빠른 초기 구동속도를 활용하여 각각의 테스트 파일을 독립된 프로세스에서 실행
- 각 모듈이 서로 에게 영향 X, 샌드박스 내부에 있는 것처럼 실행되 안전함
- 비동기 코드 테스트 지원
- 쉬운 설치 및 실행
- 간단한 커맨드 라인 옵션 등
- 쉬운 커버리지 측정 (
istanbul
내장) - 스냅샷 테스트
- DOM, window 객체 API 가상 브라우저 환경 제공 (
jsdom
내장) - 자동 모의(Auto Mocking)
- 단위 테스트 사항 제외
- 테스트 파일 필터링
- 이미 검증된 파일에 대한 불필요한 테스트 실행 방지
- 인터랙티브한 커맨드 라인 인터페이스를 통해 테스트 대상 파일들을 변경할 수 있는 기능 지원
- 현재 진행 중인 테스트 취소 / 매치되는 테스트 필터링하여 실행 등..
- 샌드박스 병렬 테스트
단점
Jasmine
사용을 강요- 단언문, 모의, 자체 모의 메소드를 가짐
- 자동 모의 때문에 상대적으로 느림
- 순차적인 테스트, 개별 테스트마다 새로운 자식 프로세스 생성 => 단일 프로세스 보다 느림
- 개선 : 다수의 프로세스를 병렬로 실행/ 테스트 파일 필터링 기능/CPU 코어 수 등을 고려해 최적화
Refernce
Toy Project
- js위주는 node.js로 돌리기
- UI/UX 관련 project는 cypress로
- karma+jasmine 조합 테스트 : 명확한 차이 및 사용 이유를 알기 위함
각 토이 프로젝트마다 READ_ME.md 작성 실행 방법 (별도 환경 구성 등 작성)