테스트 코드는 지속가능한 소프트웨어를 만들기 위해서 중요한 장치입니다.
지속가능한 소프트웨어랑 무엇일까요? 지속가능한 소프트웨어는 필요한 업데이트를 즉시 할 수 있어야하고, 지속적으로 건강하게 작동하여야 할 것입니다.
테스트 코드 없이 복잡한 비즈니스 로직을 가진 프로젝트를 계속 진행한다면 어떻게 될까요? 아마도 프로젝트 중반부부터 진전없이 런타임 에러를 고치려고 개발자 도구만 보는 나를 보게 될 것입니다. (...)
이러한 상황을 방지하기 위해 여러가지 테스트 기법들이 있습니다.
Unit Test: 소프트웨어의 최소 단위 (일반적으로 함수) 를 테스트한다.Integration Test: 다수의 단위 기능이 합쳐진 기능에 대한 테스트System Test: 전체 시스템에 대한 동작 테스트Acceptance Test: 고객(사용자)이 구현한 요구사항을 승인할 수 있는지 판단하는 테스트UI Test: UI 기능을 단위로 진행하는 테스트E2E Test: 사용자 입장에서 GUI를 통해 시나리오를 만들어 테스트
이번 포스트에서는 프론트엔드에서 자주 쓰이는 테스팅 도구들인 Jest 와 Storybook 을 통해 Unit Test, UI Test 를 하는 방법을 알아보겠습니다.
Jest
Jest 는 Facebook이 개발한 자바스크립트 테스팅 프레임워크로, React, Vue, Angular, Express 와 같은 자바스크립트 라이브러리 및 프레임워크 기반의 코드를 테스트하기에 최적화되어 있습니다.
Jest 는 설정이 거의 필요 없는 테스트 프레임워크를 목표로 개발되어 테스트 작성의 진입 장벽을 낮추었고, 테스트 실행 속도가 빠르다는 특징이 있습니다.
이어 Jest 는 모의 함수, 타이머, 비동기 테스트 외에도 스냅샷 테스팅, 테스트 커버리지 리포트 등의 다양한 고급 기능들을 지원하여, 개발자가 효율적으로 테스트를 작성할 수 있도록 도와줍니다.
Jest Unit Test 시작하기
Jest를devDependencies에 설치해줍니다.
npm i -D jest
- 파일 네이밍 컨벤션을 지키며 테스트 파일을 생성합니다.
calculationUtils.js의 테스트 파일을 만든다 ->calculationUtils.test.js
- 테스트할 코드를 작성해줍니다.
// calculationUtils.js const calculationUtils = { add(a, b) { return a + b; }, ... } export default calculationUtils; // calculationUtils.test.js describe('더하기 단위 테스트', () => { it('add 함수에 2과 7을 입력하면 9를 결과로 반환한다.', () => { // given const firstOperand = 2; const secondOperand = 7; const expectedResult = 9; // when const result = calculationUtils.add(firstOperand, secondOperand); // then expect(result).toEqual(expectedResult); }); });
Jest 의 각 기능들에 대해서 알아봅시다.
describe: 테스트 그룹을 묶어줍니다.Test Suite와 같은 역할을 합니다.it: 테스트 케이스를 표현합니다. 어떤 코드를 어떻게 테스트하는지 구체적으로 설명합니다.expect: 검증하는 코드를 인수로 입력 받습니다.toEqual():expect의 결과가toEqual()의 인수와 같은지 비교합니다.
단위 테스트는 일반적으로 given, when, then 방식으로 테스트를 진행합니다.
- given : 테스트에 필요한 값들을 설정합니다. (입력 값, 예상 출력 값)
- when : 테스트 대상을 실행합니다.
- then : 실행한 결과 값이 예상한 값과 일치하는지 확인합니다.
위 테스트를 실행하면 다음과 같이 테스트가 완료됐다라고 뜹니다!

테스트가 실패한다면 어떨까요?

위와 같이 예상했던 값과 실제로 받은 값이 출력되며 테스트 대상의 버그를 찾을 수 있습니다.
Jest를 통해 느낀 점
저는 뉴스 스탠드 미션을 구현하며 Jest 로 Unit Test 코드를 작성하기 시작하였습니다.
Unit Test 를 작성하며 느낀 점은:
- 코드 수정 이후에도 기능이 정상적으로 동작하는지 확인해 볼 수 있다.
- 기능의 동작방식의 문서화가 잘된다.
- 테스트를 작성하면서 기능들을 모듈화하여 설계하는 습관이 생긴다.
Unit Test를 만들려면 코드가 독립적이여야 하기 때문에
Storybook
Storybook 은 UI 컴포넌트를 독립적으로 개발하고 테스트할 수 있게 해주는 오픈 소스 도구입니다. 주로 React , Vue , Angular 와 같은 프레임워크와 함께 사용됩니다.
Storybook 에서는 UI 컴포넌트가 각각 개별적인 환경에서 애플리케이션의 나머지 컴포넌트에 영향을 주지 않도록 테스트 할 수 있습니다. 컴포넌트들이 독립적으로 테스트 되기 때문에 컴포넌트가 의도한대로 작동하는지 확인하기가 쉬워집니다.
컴포넌트의 독립적인 시각적 표현을 통해 문서화를 하고, 비개발자 팀원들과 협업을 할 때도 용이합니다.
Storybook 은 다양한 시나리오에서 컴포넌트들을 쉽게 테스트 할 수 있어 개발자가 어플리케이션 전체를 탐색하며 오류를 찾을 필요가 없어집니다.
Storybook UI Test 시작하기
Storybook을 시작하기 전에,React프로젝트를 하나 생성합니다. 저는Create React App으로 프로젝트를 생성하겠습니다.
npx create-react-app <프로젝트 이름>
Storybook의 설치와 초기설정을 도와주는 다음 명령어로 패키지를 설치해줍니다.
npx sb init
설치가 완료되면 다음 디렉토리가 생성됩니다.
.storybook:Storybook설정 파일이 포함되어 있습니다.src/stories:Storybook컴포넌트와 테스트 코드가 예시로 들어있습니다.
- 파일 네이밍 컨벤션을 지키며 테스트 파일을 생성합니다.
Button.jsx의 테스트 파일을 만든다 ->Button.stories.jsx
- 테스트할 컴포넌트의 스토리를 작성해줍니다.
import { fn } from '@storybook/test'; import { Button } from './Button'; export default { title: 'Example/Button', component: Button, parameters: { layout: 'centered', }, argTypes: { backgroundColor: { control: 'color' }, }, args: { onClick: fn() }, };
스토리는 위와 같이 컴포넌트 스토리 포맷(Component Story Format) 으로 작성하고 default export 해줘야 합니다.
컴포넌트 스토리 포맷의 프로퍼티들은 다음과 같습니다.
| 프로퍼티 | 설명 |
|---|---|
| title | 컴포넌트의 위치를 나타내는 문자열. Storybook의 사이드바에 표시됩니다. |
| component | 스토리를 작성하는 컴포넌트를 가리킵니다. |
| args | 컴포넌트에 전달되는 기본 속성 값을 정의합니다. |
| argTypes | 각 속성의 유형, 설명 및 기본값과 같은 메타데이터를 정의합니다. |
| decorators | 스토리를 래핑하여 스타일링 또는 컨텍스트 추가와 같은 추가 렌더링을 하는 함수입니다. |
| parameters | 레이아웃 또는 액션과 같은 스토리나 컴포넌트에 대한 설정을 정의합니다. |
| template | 여러 스토리에서 코드 중복을 피하기 위해 재사용 가능한 스토리 함수 패턴을 정의합니다. |
| storyName | Storybook UI에 표시될 스토리의 이름을 정의합니다. |
| includeStories | 스토리북에 포함할 스토리 목록을 배열로 정의합니다. |
| excludeStories | 스토리북에서 제외할 스토리 목록을 배열로 정의합니다. |
Storybook을 실행해줍니다.
npm run storybook
위 명령어로 Storybook 을 실행하면 별도의 서버가 실행되고, 다음과 같은 페이지에 스토리를 볼 수 있습니다.

Storybook을 쓰며 느낀 점
저는 팀 프로젝트였던 이슈 트래커 미션을 구현하며 Storybook 으로 UI Test 를 주로 작성하였습니다.
UI Test 를 작성하며 느낀 점은:
- 독립적인 컴포넌트 환경으로 인해 테스트뿐만 아니라 개발을 할 때도 도움이 많이 된다.
- 즉각적으로 시각적 피드백이 가능하기 때문에 팀원과의 협업에 도움이 된다.
마치며
이번 포스트에서는 Unit Test 와 UI Test, 그리고 각 테스트의 프레임워크를 살펴보았습니다.
제가 학습하고 직접 구현한 부분은 전체의 일부분이지만, 각 테스트들의 필요성과 장점을 충분히 느낄 수 있었다고 생각하고, 다음 프로젝트들에도 계속 사용하며 학습해보려고 합니다.
어플리케이션 구현에 있어서 가장 이상적인 장면은 처음부터 설계를 완벽히 해내고 버그가 안나는 것일테지만, 그것은 아마 불가능할 일이라는 것을 알기에, 저는 테스트 도구들의 힘을 빌려 버그를 최소화 하려고 합니다.
물론 프레임워크가 유명하다고 해서 만병통치약은 아닐겁니다. 따라서 Jest, Storybook 이 외에도 다른 프레임워크를 공부하고 프로젝트에 알맞은 테스팅 라이브러리/프레임워크를 적용하도록 노력하려고 합니다.