뷰 테스트 알아보기 01
안녕하세요 요즘 testCode에 관심이 많습니다.
특히 tdd에 관심이 있어서 적용을 해보고 싶어서 도구들을 학습해보려 합니다 :ㅇ
test -> 코드가 spec 정의 후 코드를 짜게 강제 한 다는 점에서 spec 정의 명확히 하지 않고 바로 코딩부터 들어가는 안 좋은 습관이 있는 제게 좀 많은 약을 주지 않을까 생각해봤습니다
목차
- Why Test
- Vue Test Getting Started
- Vue Cli 사용 및 Vuex Test Basic
- 2번째 글에서 앞으로 알아보고 적용할 것들 소개
01. why test 도구 학습
앞서 말했지만 다시 한 번 정리하면
- TDD 잘 학습 (리팩토링 및 명세 잘 짜고 코딩하는 습관 기르기 위해서)
02 Vue Test
오늘 저희가 학습할 내용은 Vue Test Utils 라이브러리 입니다
Vue 공식 라이브러리들은 선택지가 하나 밖에 없는게 장점이자 단점인 듯합니다. 이런 면에서 입문자들이게는 근데 참 좋은 프레임워크 같습니다.
(한놈판 일단 팹시다 👊)
02-01 started
git clone https://github.com/vuejs/vue-test-utils-getting-started
cd vue-test-utils-getting-started
npm install
고대로 예제 Repo를 clone 해와서 test를 돌려봅시다. npm test
counter.js
export default {
template: `
<div>
<span class="count">{{ count }}</span>
<button @click="increment">Increment</button>
</div>
`,
data() {
return {
count: 0,
};
},
methods: {
increment() {
this.count++;
},
},
};
// test.js
import { mount } from "@vue/test-utils";
import Counter from "./counter";
describe("Counter", () => {
// Now mount the component and you have the wrapper
const wrapper = mount(Counter);
it("renders the correct markup", () => {
expect(wrapper.html()).toContain('<span class="count">0</span>');
});
// it's also easy to check for the existence of elements
it("has a button", () => {
expect(wrapper.contains("button")).toBe(true);
});
it("button should increment the count", () => {
expect(wrapper.vm.count).toBe(0);
const button = wrapper.find("button");
button.trigger("click");
expect(wrapper.vm.count).toBe(1);
});
});
test Code를 살펴보면 mount, shallowMount 로 컴포넌트를 리턴한 인스턴스를
wrapper
로 이름 붙여서 api들을 접근합니다.
이벤트에는 trigger
로 상태 변화를 줄 수도 있고
vm
viewModel에 약자인 vm 프로퍼티에 접근해서 data속성 값을 비교할 수도 있습니다.
02-02 example 살펴보며 공부한 API
- mount
- shallowMount
- find
- vm
- toContain
- html
- trigger
- propsData
Mount
렌더링 된 뷰 구성요서가 포함된 Wrapper를 만듭니다.
shallowMount
Mount, ShallowMount 두 API 모두다 Wrapper를 반환하고
Component , {Optipns} parameter로 받는다.
{Optipns}:
context, slots, attatchToDocument, Stub, Mock....
자세한 부분은 아래 링크에서 살펴봅시다
둘의 차이는 어떤 것일까? 공통점 : Wapper contins mounted and rendered Vue component 차이: 스텁된 하위 구성요소
stub 사전으로 보면 남은 부분, 몽당 연필
Shallow , stub 말 그대로 일 부분만 모든 구성요소가 렌더링 되지 않아서
- 다른 컴포넌트로 전이되지도 않고
- 성능상 이점도 있고
- 고로 단위 테스트에서 주로 ShallowMount를 쓴다고 합니다
나머지 살펴본 API
- find
- vm
- toContain
- html
- trigger
- propsData
이 부분도 하나 하나 다뤄보려 했지만 뭐 사실 testCode나 예제 문서를 보면 바로 알만한 것들이여서 넘어가도록 하겠다.
3. Vue Cli 사용 및 Vuex Test Basic
- Vue Test Utils Vue-CLI 공식 플러그인 으로서
npm install -g @vue/cli
vue cli 성치 후
vue create <projectName>
Manual 설정으로 들어가서 unit-test - jest 관련 설정을 입력하자
// package.json
"test:unit": "vue-cli-service test:unit"
기본 설정이 이렇게 되어 있는데 test
| start
는 npm run 을 안 붙여도 되는 명령어이고
나중에 unitTest 이후로 추가되면 나눌 필요가 있겠지만 ...
test: vue-cli-service test:unit --watch"
이렇게 개발을 하는 게 좋을 것 같다 👐
https://vue-test-utils.vuejs.org/guides/getting-started.html
- 추가적으로 __test 폴더에 따로 있는 것보다 같은 폴더에 있으면 component 경로 접근이 편한데
// package.json testMatch에 부분을 이렇게 수정해주면 된다.
"<rootDir>/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)",
또 CLI 기반으로 default로 설치했어도
vue add @vue/unit-jest
로 plugin을 추가해줌으로서 쉽게 설정들을 추가해줄 수 있다.
custom mount함수 만들어서 사용하기 (Component, Option)
추가적으로 reference 로 걸어놓은 aligator에서 소개하는 부분에서 매번 vue 생성자에 접근해서 다시 인스턴스를 만들어주는 형태인데 이런 부분을 함수로 만들어놓으면 꾀 좋은 util로 기능을 할 것 이다 😄
function mountComponentWithProps(Component, propsData) {
const Constructor = Vue.extend(Component);
const vm = new Constructor({
propsData,
}).$mount();
return vm.$el;
const headingData = mountComponentWithProps(FancyHeading, { color: "red" });
const styleData = headingData.style.getPropertyValue("color");
console.log(styleData);
expect(styleData).toEqual("blue");
}
// 이렇게 자주쓰이는 Component, propsData를 받아서 $el로 반환하면 디버깅 하기 용이하다
VueX Test 공부 부족 및 글이 너무 길어 질 것 같아 다음으로 넘기겠습니다. 다음에 또 봐요 안녕
다음글에서 앞으로 알아보고 적용할 것들 소개
- 라이브러리에서 사용되고 있는 것들 보고 살펴보고 좋다고 생각되는 것 사례 들고 적용하기
- 잘 모르는 용어 찾아보고 공부하기 Stub, (Route | Store, Slot Test ...)
- Vuex Test