Mocha 플러그인을 활용한 단위 테스트
프로젝트 생성 시 수동 설정을 하면 단위 테스트를 사용할 수 있음
C:\JetBrains\vscode_workspace>vue create test1
Vue CLI v4.5.9
? Please pick a preset: (Use arrow keys)
Default ([Vue 2] babel, eslint)
Default (Vue 3 Preview) ([Vue 3] babel, eslint)
> Manually select features
Vue CLI v4.5.9
? Please pick a preset: Manually select features
? Check the features needed for your project:
(*) Choose Vue version
(*) Babel
( ) TypeScript
( ) Progressive Web App (PWA) Support
( ) Router
( ) Vuex
( ) CSS Pre-processors
(*) Linter / Formatter
>(*) Unit Testing
( ) E2E Testing
Vue CLI v4.5.9
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Linter, Unit
? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
> 2.x
3.x (Preview)
Vue CLI v4.5.9
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Linter, Unit
? Choose a version of Vue.js that you want to start the project with 2.x
? Pick a linter / formatter config: (Use arrow keys)
> ESLint with error prevention only
ESLint + Airbnb config
ESLint + Standard config
ESLint + Prettier
Vue CLI v4.5.9
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Linter, Unit
? Choose a version of Vue.js that you want to start the project with 2.x
? Pick a linter / formatter config: Basic
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>(*) Lint on save
( ) Lint and fix on commit
Vue CLI v4.5.9
? Please pick a preset: Manually select features
? Check the features needed for your project: Choose Vue version, Babel, Linter, Unit
? Choose a version of Vue.js that you want to start the project with 2.x
? Pick a linter / formatter config: Basic
? Pick additional lint features: Lint on save
? Pick a unit testing solution: (Use arrow keys)
> Mocha + Chai
Jest
기본 기능 테스트
src/sum.js
let sum = (a, b) => a + b;
export default sum;
tests/unit/sum.spec.js
import { expect } from 'chai';
import sum from '@/sum';
describe('sum', () => {
it('add 2+3 equals 5', () => {
expect(sum(2, 3)).to.equals(5);
})
});
yarn test:unit 명령 실행
C:\JetBrains\vscode_workspace\test1>yarn test:unit
yarn run v1.22.10
warning ..\package.json: No license field
$ vue-cli-service test:unit
Download the Vue Devtools extension for a better development experience:
https://github.com/vuejs/vue-devtools
You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html
WEBPACK Compiling...
[=========================] 98% (after emitting)
DONE Compiled successfully in 5362ms
[=========================] 100% (completed)
WEBPACK Compiled successfully in 5362ms
MOCHA Testing...
HelloWorld.vue
√ renders props.msg when passed (39ms)
sum
√ add 2+3 equals 5
2 passing (46ms)
MOCHA Tests completed successfully
Done in 13.85s.
packge.json
{
"name": "test1",
"version": "0.1.0",
"private": true,
"scripts": {
.....
"test:unit": "vue-cli-service test:unit",
....
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11"
},
"devDependencies": {
....
"@vue/cli-plugin-unit-mocha": "~4.5.0",
....
"@vue/test-utils": "^1.0.3",
"babel-eslint": "^10.1.0",
"chai": "^4.1.2",
"eslint": "^6.7.2",
....
},
....
}
test/unit/example.spec.js
- describe : 관련 테스트들을 묶어 테스트 블록을 테스트 스위트 형태로 생성
- it : test 함수의 별칭
- ShallowMount : @vue/test-utils 패키지에서 제공되고, HellowWorld 컴포넌트에 propsdta 의 msg 값을 마운트
- div.hello>h1{{{msg}}} 값이 msg 변수값과 일치하는지 비교
- mount 함수와의 차이점 : mount는 전체 자식 컴포넌트까지 랜더링 하지만 shallowMount는 자식 컴포넌트를 랜더링 하지 않고 직접 마운트 된 컴포넌트만 렌더링
- text : HTML 태그를 제외한 문자열만 추출
import { expect } from 'chai'
import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message'
/*
<template>
<div class="hello">
<h1>{{ msg }}</h1>
....
</div>
</template>
*/
const wrapper = shallowMount(HelloWorld, {
propsData: { msg }
})
expect(wrapper.text()).to.include(msg)
})
})
Vue 컴포넌트 테스트
totolistapp 프로젝트 이용
Mocha 테스트 솔루션 추가
C:\JetBrains\vscode_workspace\test1>vue add @vue/unit-mocha
WARN There are uncommitted changes in the current repository, it's recommended to commit or stash them first.
? Still proceed? Yes
📦 Installing @vue/cli-plugin-unit-mocha...
yarn add v1.22.10
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@2.1.3: The platform "win32" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@1.2.13: The platform "win32" is incompatible with this module.
info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved 0 new dependencies.
Done in 12.59s.
✔ Successfully installed plugin: @vue/cli-plugin-unit-mocha
🚀 Invoking generator for @vue/cli-plugin-unit-mocha...
⚓ Running completion hooks...
✔ Successfully invoked generator for plugin: @vue/cli-plugin-unit-mocha
example.spec.js 파일 삭제
test/unit/List.spec.js
- Vue.nextTick : 비동기로 처리.
- 다음 DOM 업데이트 사이클이 완료된 후에 테스트가 수행될 수 있도록 Promise 패턴을 사용해 then 내부에서 테스트 수행
- 마지막 done 인자를 사용해 테스트가 완료 되었음을 알림
- 훅
- before : 테스트의 시작 전 실행
- after : 테스트 종료 후 실행
- beforeEach : 테스트 스위트 전체의 시작 전 실행
- afterEach : 테스트 스위트 전체의 종료 후 실행
- dispatchEvent : 클릭 이벤트를 일으킴
- _watcher.run : Vue 인스턴스에서 상태의 변경을 감지할 수 있도록 감시자를 구동
import { expect } from 'chai';
import { mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import Vue from 'vue';
import store from '@/store';
import List from '@/components/List.vue';
import Constant from '@/Constant';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('List.vue', () => {
let wrapper;
before(() => {
wrapper = mount(List, { store, localVue });
})
it('초기 렌더링 화면 테스트', (done) => {
//const wrapper = mount(List, { store, localVue });
Vue.nextTick().then(() => {
expect(wrapper.vm.$el.querySelectorAll('li').length).to.equal(4);
done();
}).catch(done);
})
it('새로운 todo 추가 후 목록확인', (done) => {
wrapper.vm.$store.dispatch(Constant.ADD_TODO, { todo: "스쿼시" });
wrapper.vm.$store.dispatch(Constant.ADD_TODO, { todo: "수영" });
Vue.nextTick().then(() => {
var list = wrapper.vm.$el.querySelectorAll('li');
expect(list[list.length - 1].textContent).to.contain('수영');
expect(list[list.length - 2].textContent).to.contain('스쿼시');
expect(list.length).to.equal(6);
done();
}).catch(done);
});
it('클릭 이벤트 후 렌더링 결과 확인', (done) => {
/*
입력값을 TodoList의 첫번째 자식 컴포넌트인
InputTodo 컴포넌트의 로컬 데이터에 새로운 todo 입력
*/
wrapper.vm.$children[0].data.todo = "피겨 강습";
const evtClick = new Window.Event("click");
var addbutton = wrapper.vm.$el.querySelector('span.addbutton');
addbutton.dispatchEvent(evtClick);
wrapper.vm._watcher.run();
Vue.nextTick().then(() => {
var list = wrapper.vm.$el.querySelectorAll('li');
expect(list[list.length - 1].textContent).to.contain('피겨 강습');
expect(list.length).to.equal(5);
done();
}).catch(done);
});
});
Jest를 이용한 테스트 방법
Facebook에서 만든 테스트 솔루션으로 다음과 같은 장점이 있음
- 쉬운 설정 : 사용자의 zero-configuration 경험을 제공하는것이 Jest의 기본 철학이라고 밝힐 만큼 설정 파일의 작성을 최소화
- 스냅샷 테스트 : DOM 요소의 스냅샷을 캡처해서 저장하고 다음 번 테스트 시에 기존 스냅샷과 비교할 수있는 스냅샷 테스트 기능을 손쉽게 사용 가능
Jest 설정
yarn install
vue add @vue/unit-jest
__tests__/sum.spec.js
import sum from '@/sum';
describe('sum 테스트', function() {
it('add 2+3 equals 5', () => {
expect(sum(2, 3)).toBe(5);
})
});
Vue 컴포넌트에 대한 테스트
__tests__/LIst.spec.js
import { mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import Vue from 'vue';
import store from '@/store';
import List from '@/components/List.vue';
import Constant from '@/Constant';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('List.vue', () => {
let wrapper;
beforeAll(() => {
wrapper = mount(List, { store, localVue });
wrapper.vm.$store.dispatch(Constant.ADD_TODO, { todo: "스쿼시" });
})
it('초기 렌더링 화면 테스트(Jest)', () => {
expect(wrapper.vm.$el.querySelectorAll('li').length).toEqual(5);
})
it('스냅샷 테스트(Jest)', (done) => {
Vue.nextTick().then(() => {
expect(wrapper.vm.$el).toMatchSnapshot();
done();
}).catch(done);
});
});
jest 실행
yarn test:unit
또는
설치후
npm install -g npx
npx jest (프로젝트 디렉터리에서)
스냅샷을 갱신하고 싶다면
npx jest -u (프로젝트 디렉터리에서)
'책 > Vue.js 퀵스타트' 카테고리의 다른 글
서버 사이드 렌더링 (0) | 2020.11.28 |
---|---|
트랜지션 효과 (0) | 2020.11.28 |
vue-router를 이용한 라우팅 (0) | 2020.11.28 |
Vuex를 이용한 상태관리 (0) | 2020.11.27 |
axios를 이용한 서버통신 (0) | 2020.11.25 |