F/E Testing Tool (프론트엔드 테스팅 도구)

2019. 8. 6. 11:37Frontend

반응형

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 코드는 없애는 방향을 유지한다.

좋은 테스트 코드

  1. 빠른 실행속도
  2. 내부 변경에도 영향을 받지 않는 코드(낮은 결합도)
  3. 버그 검출 가능한 코드 (구체적인 테스트 명세)
  4. 안정적인 테스트 결과(언제나 동일한 결과를 보장)
  5. 명확한 의도 (사람이 볼때 한번에 무슨 의도인지 파악 가능)

테스트 전략

모든 상황에 맞는 득과 실을 잘 따져서, 적합한 테스트 도구를 사용해 전략을 세우는 것이 중요하다.

최신 테스트 도구를 사용해 시각적 요소 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에서 선호도 조사를 실시한 결과가 자세히 나와있다.

@2018 Testing 도구 선호도 조사 결과

대중적인 조합

  • 브라우저 : Karma + Jasmine
  • Node.js : Jest or Mocha + Chai + Sinon.js

Jasmine

  • BDD 스타일의 단언 API를 사용하는 통합 테스크 프레임워크

장점

  • 비동기 코드 테스트 지원
  • 모든 환경에서 사용가능 (Node.js & 브라우저)
  • 별도 라이브러리 설치 필요 X
  • 테스트 명세를 그룹화 할 수 있다 (목적에 맞게 묶어 관리 가능)
  • 비교적 빠른 테스트

Mocha

  • 다른 모의 라이브러리를 함께 사용할 수 있음
    • 즉, 단언 라이브러리를 따로 설정해주어야 함.

장점

  • 유연하다 (어느 라이브러리와도 함께 사용될 수 있다.)
  • 간단하고 명료한 API
  • 비동기 테스트 코드 지원
  • 테스트 실행이 빠름
  • 보다 높은 사용성

단점

  • 자동모의나 스냅샷 테스트 미지원
  • 설치(환경 구성이)가 까다롭다.
  • 비교적 비동기 테스트 지원이 적다

Karma

  • 실제 브라우저에서 테스트를 실행할 수 있도록 도와줌

실행방식

  • 커맨드 라인에서 Karma 실행시, 웹서버 구동 -> HTML 페이지 생성 -> 모든 코드 로드
  • 브라우저 직접 실행 후 접속하면 로드된 코드가 실행되어 실행 결과가 브라우저 콘솔에 출력됨
  • Karma는 해당 정보를 지정된 리포터를 통해 정리한 후, 커맨드 라인에 결과 보여줌

Alt text

  • 테스트 커버리지 lstanbul lib로 설치해 측정 가능

    • coverage 폴더 안 브라우저 런처 별 폴더 생성 index.html을 열어 측정 결과 확인
      Alt text
  • 크로스 브라우징 테스트 가능

    • 로컬 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 작성 실행 방법 (별도 환경 구성 등 작성)

반응형