개인 프로젝트에 Vue 컴포넌트 테스트 적용하기(+Vuex 테스트)
테스트 주도 개발(TDD)에 대해 공부하는 중입니다. 그래서 빌드하고 유지, 보수중인 외대종강시계 크롬 확장앱 프로젝트에 테스트 코드를 붙여보는 연습을 했습니다. 먼저 프 로젝트에서 가장 중요한 컴포넌트라고 할 수 있는 종강 시간을 표시하는 시계 컴포넌트, MainClock.vue
에다가 테스트 코드를 붙여보았는데요. 이 경험을 공유하고자 합니다!
MainClock.vue
일단 MainClock.vue 컴포넌트는 앱에서의 저 시계 부분입니다. 현재서부터 종강까지의 시간을 표시한다는 점에서 종강시계 앱의 가장 핵심적인 부분이죠. 컴포넌트의 코드를 하나하나 설명하기보다는, 주요한 동작 방식과 테스트에 쓰일 변수들을 간략히 설명해보겠습니다.
주요 변수
this.semesterInfo
: 현재 시계에 표시되는 기준 종강/개강 시간 정보를 담고 있는 객체이며 컴포넌트의data()
가 리턴하는 객체의 프로퍼티입니다. Vuex 저장소를 사 용해서 이 값을 업데이트하게 되는데요, 처음에 Vuex store에는 학기 정보가 다음 코드 블럭에서처럼 저장되어 있습니다. 컴포넌트의 created 생명주기에서 현재 시간을 평가하여 Vuex 저장소에서 적합한 시간 정보 중 하나를semesterInfo
변수에 할당하는 식으로 업데이트가 이루어집니다.
semesterInfos: {
// 현재 학기
current: {
act: "종강",
id: "2020-1",
due: Date(...), // 현재학기 종강 날짜
},
// 다음 학기
next: {
act: "개강",
id: "2020-2",
due: Date(...), // 현재학기 개강 날짜
},
// 다음 계절학기
seasonal: {
act: "종강",
id: "2020 여름",
due: Date(...), // 다음 계절학기 종강 날짜
},
},
this.gapTime
:semesterInfo
의 시간 정보를 토대로 현재 시간과의 차이를 계산한 결과를 가지고 있는 객체이며 역시data()
가 리턴하는 객체의 프로퍼티입니다. 프로퍼티로 day, hour, minute, seconds를 가집니다.created
생명주기에서 현재 시간을 평가해semsterInfo
의 설정이 끝나면 이 시간 값을 토대로 현재 시간에서부터 남은 시간을 계산하여 계산 결과의 날짜, 시간, 분, 초 정수 값을 이 변수에 저장하고 이 값은 시계에 그대로 렌더링됩니다..tab-clock-main-btn
: 학기 정보를 바꿀때 사용하는 버튼에 바인딩된 CSS 클래스명입니다. 시계 바꾸기 버튼 element를 선택하는데 쓰입니다.
컴포넌트 동작 방식
this.semesterInfo
변수에 할당된 시간 정보가 현재 시간을 평가해서 정해진다고 했었죠? 그래서 MainClock
컴포넌트는 현재 시각이 어떤 시점에 있느냐에 따라 다르게 동작합니다. 크게 3개의 시점에 따른 동작방식을 가지고 있습니다.
1. 현재 시간이 현재 학기(current) 종강일 이전일 때
- 남은 시간 정보(gapTime의 프로퍼티)가 0이상의 정수로 표현될 것
- 연산할 학기 정보(semesterInfo)가 현재 학기(current)여야 함
- 시계 바꾸기 버튼이 나타나면 안 됨
2. 현재 시간이 현재 학기(current) 종강일 이후이면서 계절학기(seasonal) 종강일 이전일 때
- 남은 시간 정보(gapTime의 프로퍼티)가 0이상의 정수로 표현될 것
- 최초에 연산할 학기 정보(semesterInfo)는 다음 학기(next)여야 함
- 시계 바꾸기 버튼이 나타나야 함
- 시계 바꾸기 버튼을 클릭하면 semesterInfo에 할당된 다음학기(next) 정보가 계절학기(seasonal) 정보로 바뀌어야 함
3. 현재 시간이 계절학기(seasonal) 종강일 이후이면서 다음학기 개강일 이전일 때
- 최초에 연산할 학기 정보(semesterInfo)는 다음 학기(next)여야 함
- 남은 시간 정보(gapTime의 프로퍼티)가 0이상의 정수로 표현될 것
- 시계 바꾸기 버튼이 나타나면 안됨
MainClock.test.js
컴포넌트의 시점별 동작 방식을 설명해 드렸는데요. 사실 이것으로 어떤 테스트 케이스를 만들어야 할지는 정해진 셈입니다. 시점별 동작 방식을 그대로 테스트 케이스로 옮길 것입니다.
이렇게 시점별로 테스트를 하는 방법을 일종의 상태 전이 방식이라고 볼 수 있습 니다. 시스템이 상태를 가지고 있고, 상태에 따라 다르게 동작하는 상황에서 테스트 케이스를 도출하는 방법입니다. TDD를 공부할 때 많이 도움이 되었던 Mesh Korea Front-end Engineering 깃헙 레포지토리에서 다른 테스트 설계 방식도 확인해보실 수 있습니다.
이제 테스트코드를 작성해 보겠습니다. 테스트에는 자바스크립트 테스트 프레임워크 jest
와 Vue 컴포넌트의 테스트를 도와주는 vue-test-utils
를 사용했습니다.
1. localVue 만들기
이 컴포넌트에서는 외부 모듈 두 가지(vue-moment
, Vuex
)를 사용하고 있습니다. 따라서 localVue
인스턴스를 만들고, 모듈을 불러와야 합니다.
import { mount, createLocalVue } from '@vue/test-utils';
import MainClock from './MainClock.vue';
import Vuex from 'vuex';
// 테스트에 사용할 로컬 뷰를 만들고 모듈을 불러옵니다.
const localVue = createLocalVue();
localVue.use(Vuex);
localVue.use(require('vue-moment'));