October 07, 2020
Front-End 에는 다양한 테스트 영역이 존재한다.
E2E, Unit, UI 테스트 등.. 테스트는 개인적으로 주관이 많이 개입되는 영역이라고 생각한다.
그래서 각자가 생각하는 테스트의 개념이 다르지만, 그 Goal 은 소프트웨어 품질로 동일하다.
이 글은 테스트를 다뤄 보는 목표 지향적이며, 세세한 함수들이나 명렁어는 다루지 않는다.
test-universe(이하 ‘TU’ 라고 칭함) 는 간단한 TO-DO 앱을 통해 테스트 코드를 전반적으로 다뤄 본다.
테스트 렌더러 같은 경우는 리액트 공식문서 에도 예제가 들어가 있는 만큼
스냅샷 테스트를 진행하기 좋은 패키지다.
테스트 렌더러를 통해 계층화된 컴포넌트의 스냅샷을 찍을 수 있다.
스냅샷된 파일은 모두 해당 테스트 폴더 하위의 snapshot 에 저장된다.
create
함수는 컴포넌트 인스턴스를 생성한다. 트리 전체를 메모리상에 렌더링 하게 되기 때문에 원하는 값을 가졌는지 검증이 가능하다.act
는 검증을 위한 컴포넌트의 사전 준비단계인데, BDD 에서의 ‘When’ 영역과 같다.toJSON
메소드를 통해 노드의 속성이 포함된 객체를 반환하는데, 스냅샷 테스트시에 사용할 수 있다.toMatchSnapshot
jest의 단언문을 통해서 toJSON
을 통해 반환된 객체를 스냅샷으로 저장한다.
//TodoListContainer.js
import React, { useState } from "react";
import { Input } from "../components/Input";
import { Button } from "../components/Button";
import { List } from "../components/List";
import { deleteOne } from "../utils";
export const TodoListContainer = () => {
const [state, setState] = useState({ value: "", list: [] });
const deleteTodoList = key => {
const res = deleteOne({ list: [...state.list], key });
setState({
...state,
list: res
});
};
return (
<div>
<Input
value={state.value}
onChange={e => {
setState({
...state,
value: e.target.value
});
}}
/>
<Button
primary
size="large"
label="Add"
backgroundColor="purple"
color="white"
onClick={() => {
const newList = [...state.list];
if (state.value !== "") newList.push(state.value);
setState({
value: "",
list: newList
});
}}
/>
<List data={state.list} deleteTodoList={deleteTodoList} />
</div>
);
};
// __snapshots__/TodoListContainer.test.js
import React from "react";
import { create, act } from "react-test-renderer";
import { TodoListContainer } from "../TodoLIstContainer";
describe("TodoListContainer", () => {
let root;
act(() => {
root = create(<TodoListContainer />);
});
it("renders correctly", () => {
expect(root.toJSON()).toMatchSnapshot();
});
});
이번 TU를 만들면서 스토리북 이라는걸 사용했는데, 만들어진 컴포넌트들을 눈으로 확인하고,
GUI 를 통해 전달되는 props도 바로 바꾸면서 확인할 수 있는 디자인 시스템을 구축할 수 있는 플랫폼이다.
이건 테스트를 다루는 문서이니, 사용법은 패스하겠다.
근데 그게 테스트랑은 무슨 상관인가? 라고 생각할 수 있다
Applitools 라는 툴을 스토리북에 올라간 컴포넌트 스냅샷 테스트가 가능하다.
Applitools 에서 본인들이 설명하기는 AI를 활용한 차세대 자동화 테스트 플랫폼이다.
eyes-storybook 를 통해서, 스냅샷을 applitools eyes 라는 제품에서 확인 할 수 있다.
npm install --save-dev @applitools/eyes-storybook //install
export APPLITOOLS_API_KEY=<your_key> //applitools eyes 에서 사용자 키를 발급받을 수 있다.
//package.json
"scripts": {
"eyes-storybook": "eyes-storybook",
},
// 위 명령어를 통해 스토리북에 올라간 컴포넌트들의 스냅샷을 찍는다.
이제 yarn eyes-storybook
스크립트를 통해 정상적으로 통과된 5개의 스냅샷을 터미널에서 확인할 수 있다.
그리고 applitools eyes 대시보드에 들어가보면 아래와 같이 볼 수 있다.
5개 모두 성공한 스냅샷 테스트 케이스
1개의 실패한 테스트가 존재할 경우
위에서 언급했던 AI 머신러닝을 통해서 어떤점이 변경됐는지 확인해서 표시 해준다.
개발자는 이걸 보고 해당 케이스가 의도한건지 아닌지 판단을 내려 thumbs up
, thubms down
아이콘을 눌러주고 해당 케이스를 마무리하면 된다.
만약 의도하지 않은 거라면 수정되거나 혹은 resolve 할때까지 계속해서 해당 케이스는 실패할것이다.