2018년 상반기 스터디 - react.js 6주

Posted by 서동우 on April 21, 2018

10장 테스팅

  • 경쟁에서 살아남을려면 빠르게 개발하면서 품질도 유지해야 한다.
  • 품질을 유지하기 위한 좋은 방법이 단위 테스팅
  • 함수형 기법을 채택할 경우 테스트하기 쉬운 코드를 작성할 수 있다.

10.1 ESLint

  • 자바스크립트는 컴파일하는 언어가 아니고, 엄격한 규칙이 적은 편이다.
  • 코드 작성 후에 브라우저에서 프로그램을 실행하면서 제대로 동작하는지 확인을 해야 함..
  • 위에 경우를 예방하기 위해서 코드를 분석해서 문제 발생할 요지를 알여주는 방법을 제공
  • 힌팅 또는 린팅: 코드를 분석해서 잠재적으로 오류 코드를 찾아서 알려주는 행위
  • 힌팅, 린팅하는 도구로 jshint, jslint, eslint 등이 있다.
  • ESLint를 사용하기 위해서는 몇가지 규칙을 지정해야 한다.
  • 규칙 지정 방법은 eslint –init 를 이용해서 규칙을 지정할 수 있다.
    1. 질문 답변 방식으로 저정하는 방법
    2. google이나 airbnb 같은 곳에서 만든 표준을 사용하는 방법
  • 파일 형식은 yml 이나 js 형식으로 할 수 있다.

10.2 리덕스 테스트하기

  • 리덕스는 데이터를 다루기 떄문에 꼭 테스트 케이스를 만들어야 한다.
  • 테스트를 먼저 작성하면 예상대로 작동하는지 쉽게 이해할 수 있음

10.2.1 테스트 주도 개발(TDD)

  • 테스트 주도 개발은 기술이 아니라 습관
  • TDD는 다음과 같은 단계를 거친다.
    1. 테스트를 먼저 작성한다.
    2. 테스트를 실행하고 실패한다.(빨간색)
    3. 테스트를 통과하기 위해 필요한 최소한의 코드를 작성한다.(녹색)
    4. 코드와 테스트를 함께 리팩토링한다.(빨간색)
  • 리듀서 작성 시 어떻게 동작해야 하는지 먼저 생각하게 되는데, 이런 것을 테스트로 먼저 만들어서 표현하면 더 쉽게 만들 수 있다.
  • TDD는 습관이라서 많은 연습을 통해야 한다.

10.2.2 리듀서 테스트하기

  • 리듀서는 입력 인자에 따라 결과를 계산해 변환하는 순수 함수
  • 테스트에서는 입력과 액션을 제어
  • 이 예제에서는 jest 를 사용
  • 테스트를 위해서 describe와 it를 만들어야 함. describe는 테스트 스위트를 만들 때 사용하고 it는 각 테스트를 만들 때 사용
  • 테스트 대상 리듀서을 테스트 대상 시스템이라고 부른다.
  • TDD 를 활용해서 테스트를 하면 보다 효율적으로 리듀서를 테스트할 수 있다.
import C from './actions/constants';
import colorReducer from './reducers/colorReducer';

//테스트 스위트를 만든다.
describe('color 리듀서', () => {
    //테스트
    it('ADD_COLOR 성공', () => {
        const state = {};
        const action = {
            type: C.ADD_COLORS,
            payload: {
                id: 0,
                title: 'Test Teal',
                color: '#90c3d4',
                timestamp: new Date().toString()
            } 
        };

        const results = colorReducer(state, action);
        //toEuqal 매처를 사용해서 object의 값(deep search)을 비교할 때 사용
        expect(results).toEqual({
            id: 0,
            title: 'Test Teal',
            color: '#90c3d4',
            timestamp: action.payload.timestamp,
            rating: 0
        });
    });

    //테스트
    it('RATE_COLOR 성공', () => {
        const state = {
            id: 0,
            title: 'Test Teal',
            color: '#90c3d4',
            timestamp: new Date().toString(),
            rating: 0
        };

        const action = {
            type: C.RATE_COLORS,
            payload: {
                id: 0,
                rating: 3
            } 
        };

        const results = colorReducer(state, action);
        //toBe 매처를 사용하면 단순 값 비교
        expect(results.rating).toBe(3);
    });
});

10.2.3 스토어 테스트하기

  • 스토어가 잘 작동한다면 앱도 잘 작동할 가능성이 높다.
  • 테스트 절차는 리듀서로 스토어를 만들고, 상태를 가정해 주입하고, 결과를 검증하는 단계
  • 제스트에서는 테스트 스위트를 실행하기 전과 후에 정해진 코드를 실행하도록 해주는 준비와 정리 기능이 있음.
    • beforeAll과 afterAll은 각각 테스트 스위트 실행 전 후에 호출
    • beforeEach와 afterEach는 it에서 선언된 각각의 테스트 실행 전 후에 호출

10.3 리액트 컴포넌트 테스트하기

  • 리액트 컴포넌트는 DOM을 생성하거나 갱신할 때 리액트가 따라야 할 지침을 제공
  • 이런 컴포넌트를 테스트하려면 컴포넌트를 렌더링해서 생성되는 DOM을 예상 DOM과 비교해봐야 한다.
  • jsdom을 활용해서 노드 상에 브라우저 환경을 시뮬레이션하여 테스트를 진행할 수 있다.
  • 엔자임 : 에어비앤비가 만든 리액트 컴포넌트 테스트 유틸리티, react-addons-test-utils 을 같이 설치해야 사용 가능
    • 테스트나 조건 검사 프레임워크가 아니고, 테스트를 위해 리액트 컴포넌트를 렌더링하는 과정을 처리하고 자식 엘리먼트를 순회하거나, 상태나 프로퍼티를 검증하거나, 이벤트를 시뮬레이션하거나 DOM에 대한 질의를 던질 떄 필요한 도구를 제공
    • shallow : 단위 테스트를 위해 컴포넌트를 한 단계 렌더링해준다.
    • mount : 브라우저 DOM을 사용해 컴포넌트를 렌더링한다. 컴포넌트 생애주기 전체를 테스트해야 하거나 자식 엘리먼트의 상태나 프로퍼터를 테스트해야 한다면 mount가 필요하다.
    • render :컴포넌트로 정적 HTML 마크업을 렌더링할 때 필요하다. render가 있으면 컴포넌트가 적절한 HTML을 생성하는지 테스트할 수 있다.
  • 컴포넌트 모킹
    • 목(Mock) 함수를 사용해서 테스트하는 방법
    • Mock : 테스트를 할 때 실제 객체를 대신할 수 있는 객체, 단위 테스트 자체에 초점을 맞추기 위한 중요한 기술
    • 목적은 테스트를 작성할 때 테스트 대상 컴포넌트나 객체, 즉 SUT에만 집중하게 해주는 것
    • HOC 테스트는 목을 써서 하면 효율적으로 할 수 있다.
  • 제스트에서는 일반 컴포넌트도 목으로 주입 가능
  • 컴포넌트 테스트 할 때 다른 연관된 컴포넌트에 신경쓰지 않고 해당 컴포넌트만 테스트가 가능
    jest.mock('color경로', () => color 컴포넌트);
    
  • 제스트에서는 우리가 직접 만든 목을 사용하기 위한 모듈을 생성할 수 있다.
  • 테스트에 목 코드를 직접 넣는 대신 mocks 디렉터리에 목 정의가 들어 있는 파일을 넣을 수도 있다.

10.4 스냡샷 테스팅

  • UI 개발에 TDD를 적용하기는 어렵고 때로는 비실용적이기도 하다.
  • 스냅샷 테스팅을 사용하면 UI 컴포넌트에 원치 않는 변화가 생기지 않았음을 확신할 수 있는 테스트를 빠르게 진행할 수 있다.
  • 제스트는 렌더링한 UI의 스냅샷을 저장할 수 있고 나중에 진행하는 테스트에서 SUT가 렌터링한 결과를 스냅샷과 비교할 수 있다.
  • 이를 통해 소스 코드 변경이 UI에 원치 않는 변화를 야기하지 않았음을 빠르게 확인하면서도 UI 테스트 구현의 어려움을 해결

10.5 코드 커버리지 사용하기

  • 코드 커버리지는 테스트가 소스 코드 중 몇 줄에 실제로 테스트 했는지 보고하는 과정이다.
  • 제스트에는 이스탄불이라는 자바스크립트 도구 있고 이 도구가 테스트를 분석해서 검사 표시
  • 콘솔 및 html에서도 해당 결과를 볼 수 있음
  • package.json에 커버리지 관련 옵션을 추가할 수 있다.(테스트를 통과하기 위해 필요한 최소한의 코드 커버리지 등을 정의)
  • 보통 85%이상 커버할 수 있도록 하면 좋다

테스트 소스 링크

테스트소스

참고자료

  • 러닝 리액트
  • https://facebook.github.io/jest/docs/en/api.html