Skip to content

Latest commit

ย 

History

History
343 lines (230 loc) ยท 18.8 KB

vue+jest1.md

File metadata and controls

343 lines (230 loc) ยท 18.8 KB

ํ”„๋ก ํŠธ์—”๋“œ ํ…Œ์ŠคํŠธํ•˜๊ธฐ 1: ํ”„๋ก ํŠธ์—”๋“œ์—์„œ์˜ ํ…Œ์ŠคํŠธ, Vue + TypeScript + Jest ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์…‹์—…


  1. ํ…Œ์ŠคํŠธ ๋Ÿฌ๋„ˆ๋ž€, ํ”„๋ก ํŠธ์—”๋“œ์—์„œ์˜ ํ…Œ์ŠคํŠธ
  2. Jest ์†Œ๊ฐœ: Jest, Transformer
  3. Jest ์„ค์น˜ํ•˜๊ธฐ (VTU ์‚ฌ์šฉํ•˜๊ธฐ)
  4. Jest ์„ค์ •ํ•˜๊ธฐ: jest.config.js, Preset
  5. ๋ณ€ํ™˜์ด ํ•„์š”ํ•œ ์จ๋“œํŒŒํ‹ฐ ๋ชจ๋“ˆ ์•Œ๋ ค์ฃผ๊ธฐ
  6. ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ๊ด€๋ฆฌํ•˜๊ธฐ: Jest ์„ค์ •์— ๋ช…์‹œ, ์ปค๋ฒ„๋ฆฌ์ง€ ๋ฆฌํฌํŠธ

1. ํ…Œ์ŠคํŠธ ๋Ÿฌ๋„ˆ๋ž€, ํ”„๋ก ํŠธ์—”๋“œ์—์„œ์˜ ํ…Œ์ŠคํŠธ

1-1. ํ…Œ์ŠคํŠธ ๋Ÿฌ๋„ˆ๋ž€

Jest์™€ ๊ฐ™์€ ํ…Œ์ŠคํŠธ ๋„๊ตฌ๋ฅผ ํ…Œ์ŠคํŠธ ๋Ÿฌ๋„ˆ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ํ…Œ์ŠคํŠธ ์ž์ฒด์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ์šฉํ•œ ๋ฉ”์†Œ๋“œ๋“ค์„ ์ œ๊ณตํ•˜๊ณ , ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ํ™˜๊ฒฝ ์…‹์—…์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

Test runners like Jest, mocha, ava let you write test suites as regular JavaScript, and run them as part of your development process. Additionally, test suites are run as part of continuous integration. - React


1-2. ํ”„๋ก ํŠธ์—”๋“œ์—์„œ์˜ ํ…Œ์ŠคํŠธ

ํ”„๋ก ํŠธ์—”๋“œ์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค์Œ 3๊ฐ€์ง€์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•  ๊ฒ๋‹ˆ๋‹ค.

  • UI: HTML ๋งˆํฌ์—…๊ณผ CSS๋ฅผ ์‚ฌ์šฉํ•œ ์Šคํƒ€์ผ ์ž‘์—… ๊ฒฐ๊ณผ๋ฌผ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ
  • ์‚ฌ์šฉ์ž ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง: ๋งˆ์šฐ์Šค, ํ‚ค๋ณด๋“œ, ํ„ฐ์น˜ ๋“ฑ ์‚ฌ์šฉ์ž ์ด๋ฒคํŠธ ์‹œ๋ฎฌ๋ ˆ์ด์…˜
  • API ํ†ต์‹ : API ํ†ต์‹ ๊ณผ ๋™๊ธฐํ™”์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ (API Mocking ๋˜๋Š” ์‹ค์ œ API๋ฅผ ์‚ฌ์šฉ)

ํ…Œ์ŠคํŠธ ์ข…๋ฅ˜๋กœ ๋‚˜๋ˆ ๋ณด๋ฉด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์™€ E2E ํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ๊ฐ ์–ด๋–ป๊ฒŒ ์ˆ˜ํ–‰ํ• ์ง€ ์ •๋ฆฌํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๋‹จ์œ„ ํ…Œ์ŠคํŠธ

  • ์ปดํฌ๋„ŒํŠธ: UI ํ…Œ์ŠคํŠธ์™€ ์‚ฌ์šฉ์ž ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š”, React๋‚˜ Vue ๊ฐ™์€ ๋ชจ๋˜ ํ”„๋ ˆ์ž„์›Œํฌ ํ™˜๊ฒฝ์—์„œ ๋ณดํ†ต ์•ฑ์˜ ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„์—์„œ ์ง„ํ–‰

  • Util ํ•จ์ˆ˜: ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” Util ํ•จ์ˆ˜ ๊ฐ๊ฐ์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰

  • State ํ•ธ๋“ค๋Ÿฌ: ์ฃผ์–ด์ง„ ๊ฐ’์— ๋Œ€ํ•ด State๊ฐ€ ์˜๋„ํ•œ๋Œ€๋กœ ์—…๋ฐ์ดํŠธ๋˜๋Š”์ง€ ํ…Œ์ŠคํŠธ (Vuex์˜ Mutation, Redux์˜ Reducer์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰)


E2E ํ…Œ์ŠคํŠธ

์•ฑ ์ „์ฒด๊ฐ€ ์ž˜ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด ๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ๋ธŒ๋ผ์šฐ์ €์—์„œ UI๊ฐ€ ์˜๋„ํ•œ๋Œ€๋กœ ๋ Œ๋”๋ง ๋˜๋Š”์ง€, ๋ผ์šฐํŠธ๊ฐ„ ์ด๋™์ด ์ž˜ ๋˜๋Š”์ง€, ์‹ค์ œ API ํ†ต์‹ ์— ๋ฌธ์ œ๊ฐ€ ์—†๋Š”์ง€ ๋“ฑ์„ Assertion์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค. E2E ํ…Œ์ŠคํŠธ ๋„๊ตฌ๋กœ๋Š” Cypress๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.


2. Jest ์†Œ๊ฐœ: Jest, Transformer

2-1. Jest

Jest๋Š” JavaScript๋กœ ๋งŒ๋“  ํ”„๋กœ๊ทธ๋žจ์˜ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํ…Œ์ŠคํŠธ ๋Ÿฌ๋„ˆ์ž…๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ ๊ด€์ ์—์„œ๋งŒ ๋ณด๋ฉด, UI ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ์Šค๋ƒ…์ƒท ํ…Œ์ŠคํŠธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ ์š”, Mocking์„ ํ†ตํ•œ API ํ†ต์‹  ํ…Œ์ŠคํŠธ๋„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Jest๊ฐ€ ๊ฐœ๋ฐœ์ž๋ฅผ ๋Œ€์‹ ํ•˜์—ฌ ํ•ด์ฃผ๋Š” ์ผ๋“ค์€ ๋‹ค์–‘ํ•˜์ง€๋งŒ, ๋‹จ์ˆœํ•˜๊ฒŒ ๋‹ค์Œ 2๊ฐ€์ง€๋กœ ์ •๋ฆฌํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฐœ๋ฐœ์ž๊ฐ€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ์šฉํ•œ ๋ฉ”์†Œ๋“œ ์ œ๊ณต
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ Node.js ํ™˜๊ฒฝ์—์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ํ™˜๊ฒฝ ์ œ๊ณต

Jest๋Š” jsdom์ด๋ผ๋Š” ๊ฐ€์ƒ DOM ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ์š”, ์ด๋Š” Jest๊ฐ€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ Node.js๋ฅผ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ๋Ÿฐํƒ€์ž„์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Node.js๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๋ณด๋‹ค ๋น ๋ฅด๊ธด ํ•˜์ง€๋งŒ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋‹ค์–‘ํ•œ Web API ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ  DOM์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. Jest๋Š” jsdom์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•  ์ˆ˜ ์žˆ๊ณ  DOM ๋…ธ๋“œ์—์„œ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋“ฑ์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. jsdom์€ Node.js ๋‚ด์—์„œ ๋งˆ์น˜ ์‹ค์ œ ๋ธŒ๋ผ์šฐ์ €์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜์ง€๋งŒ ํƒ์ƒ‰๊ณผ ๋ ˆ์ด์•„์›ƒ ๊ธฐ๋Šฅ์€ ํฌํ•จ๋˜์–ด์žˆ์ง€ ์•Š์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์„ธ์š”.


2-2. Transformer

Jest๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ Transformer์˜ ๋„์›€์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ Plain JavaScript๋กœ ์ž‘์„ฑ๋œ ๋ชจ๋“ˆ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด Node.js์—์„œ ์‹คํ–‰ํ•˜๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†๊ฒ ์ง€๋งŒ, Vue, TypeScript ๋“ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋œ ๋ชจ๋“ˆ์„ ํฌํ•จํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” Node.js๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— Plain JavaScript๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ž‘์—…์„ ๊ฑฐ์ณ์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด Transformer์— ๋Œ€ํ•œ ์„ค์ •์€ ๋’ค์—์„œ ์•Œ์•„๋ณผ Jest ์„ค์ •ํŒŒ์ผ์ธ jest.config.js์—์„œ ํ•ฉ๋‹ˆ๋‹ค.


๋‹ค์Œ์€ Vue ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž์ฒด๋„ *.ts ํŒŒ์ผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์ง€๋งŒ, ์ผ๋‹จ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๋‚ด HelloWorld ๋ชจ๋“ˆ์˜ Transform์— ๋Œ€ํ•ด์„œ๋งŒ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค.

// example.spec.ts

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";
		const wrapper = shallowMount(HelloWorld, {
			props: { msg },
		});
		expect(wrapper.text()).toMatch(msg);
	});
});

๋‹ค์Œ์€ ์œ„์˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” HelloWorld.vue ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์€ vue-jest๋ผ๋Š” Transformer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ <template>, <script>, <style> ๊ตฌ๋ฌธ์„ ์˜๋„์— ๋งž๋Š” Plain JavaScript๋กœ ๋ณ€ํ™˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. <script> ์˜์—ญ์— ์ž‘์„ฑ๋œ TypeScript ์ฝ”๋“œ ์—ญ์‹œ ts-jest๋ผ๋Š” Transformer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Plain JavaScript๋กœ ๋ณ€ํ™˜ํ•ด์•ผํ•˜๊ณ ์š”.

<template>
	<div class="hello">{{ msg }}</div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
	name: "HelloWorld",
	props: {
		msg: String,
	},
});
</script>

<style scoped lang="scss">
div {
	color: #42b983;
}
</style>

3. Jest ์„ค์น˜ํ•˜๊ธฐ

3-1. @vue/cli๋กœ ์ƒˆ ํ”„๋กœ์ ํŠธ ๋งŒ๋“ค๊ธฐ

Vue์—์„œ ๊ณต์‹ ์ง€์›ํ•˜๋Š” VTU(Vue ํ…Œ์ŠคํŠธ ์œ ํ‹ธ)์„ ํ†ตํ•ด Jest๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. VTU๋Š” Vue ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ์œ ํ‹ธ ํ•จ์ˆ˜๋“ค์„ ์ œ๊ณตํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. @vue/cli 3.x ์ดํ›„ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜์—ฌ Vue ์•ฑ์„ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด, ์•ฑ ์ƒ์„ฑ์‹œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํˆด์„ ์„ ํƒํ•จ์œผ๋กœ์จ VTU์™€ ์ถ”๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์‰ฝ๊ฒŒ ์…‹์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ์•ฑ์„ ์ƒ์„ฑํ•  ๋•Œ Unit Testing ๋„๊ตฌ๋กœ Jest๋ฅผ ์„ ํƒํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. VTU ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋„ VTU๋ฅผ Jest์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅ๋‹ˆ๋‹ค.



์ €๋Š” @vue/cli 4.5.13 ๋ฒ„์ „์œผ๋กœ ์•ฑ์„ ์ƒ์„ฑํ–ˆ๋Š”๋ฐ์š”, ์•ฑ ์ƒ์„ฑ์„ ์™„๋ฃŒํ•˜๋ฉด package.json ํŒŒ์ผ์— ์•„๋ž˜์™€ ๊ฐ™์ด ํ•„์š”ํ•œ ์Šคํฌ๋ฆฝํŠธ์™€ ๋””ํŽœ๋˜์‹œ๋“ค์ด Preset ๋ฉ๋‹ˆ๋‹ค. (TypeScript, Babel, Jest ๊ด€๋ จ ํ•ญ๋ชฉ์ด ์•„๋‹Œ ๊ฒƒ์€ ์ƒ๋žต)

{
	"scripts": {
		"test:unit": "vue-cli-service test:unit"
	},
	"devDependencies": {
		"@types/jest": "^24.0.19",
		"@vue/cli-plugin-babel": "~4.5.0",
		"@vue/cli-plugin-typescript": "~4.5.0",
		"@vue/cli-plugin-unit-jest": "~4.5.0",
		"@vue/test-utils": "^2.0.0-0",
		"typescript": "~4.1.5",
		"vue-jest": "^5.0.0-0"
	}
}


3-2. ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ํ•˜๊ธฐ

๊ธฐ์กด Vue ํ”„๋กœ์ ํŠธ์— VTU๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด @vue/cli ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์–ด๋Š” @vue/cli-plugin-unit-jest๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

vue add unit-jest

๊ทธ๋ฆฌ๊ณ  ํŒจํ‚ค์ง€๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ @vue/test-utils, vue-jest ๋“ฑ ์ถ”๊ฐ€๋กœ ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋“ค์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

yarn add @vue/test-utils --dev

4. Jest ์„ค์ •ํ•˜๊ธฐ: jest.config.js, Preset

4-1. jest.config.js

Jest ์„ค์ •ํŒŒ์ผ์€ jest.config.js์ž…๋‹ˆ๋‹ค. jest.config.js ๋Œ€์‹  package.json ํŒŒ์ผ์˜ jest ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ @vue/cli 4.5.13 ๋ฒ„์ „์œผ๋กœ Babel, TypeScript๋ฅผ ํฌํ•จํ•˜์—ฌ ์•ฑ ์ƒ์„ฑ์‹œ ๊ธฐ๋ณธ์œผ๋กœ ์„ธํŒ…๋˜๋Š” jest.config.js ํŒŒ์ผ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

// jest.config.js

module.exports = {
	preset: "@vue/cli-plugin-unit-jest/presets/typescript-and-babel",
	transform: {
		"^.+\\.vue$": "vue-jest", // vue-jest๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  *.vue ํŒŒ์ผ์„ *.js ํŒŒ์ผ๋กœ ์ปดํŒŒ์ผ
	},
};

4-2. Preset

preset ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์™ธ๋ถ€ ์„ค์ •ํŒŒ์ผ ๋‚ด์šฉ์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Shallow Merge์ฒ˜๋Ÿผ ์ดํ›„์— ์ง€์ •ํ•˜๋Š” ์˜ต์…˜๋“ค์ด ๋ฎ์–ด์“ฐ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์œ„์—์„œ Preset์œผ๋กœ ์‚ฌ์šฉ๋œ @vue/cli-plugin-unit-jest/presets/typescript-and-babel์€ ๋‹ค์Œ 3 ๊ฐœ Preset ํ•ฉ์œผ๋กœ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.


5. ๋ณ€ํ™˜์ด ํ•„์š”ํ•œ ์จ๋“œํŒŒํ‹ฐ ๋ชจ๋“ˆ ์•Œ๋ ค์ฃผ๊ธฐ

๊ธฐ๋ณธ์ ์œผ๋กœ Jest๋Š” node_modules์— ์„ค์น˜๋œ ๋””ํŽœ๋˜์‹œ ๋ชจ๋“ˆ์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๋ณ€ํ™˜ ์ž‘์—…์„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Jest ์„ค์ • ์˜ต์…˜ ์ค‘ transformIgnorePatterns์˜ ๋””ํดํŠธ ๊ฐ’์— /node_modules/ ๊ฒฝ๋กœ๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

transformIgnorePatterns: ["/node_modules/"];

์ด๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์จ๋“œํŒŒํ‹ฐ ๋ชจ๋“ˆ์ด Plain JavaScript๋กœ ์ž‘์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ Jest๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ Node.js ํ™˜๊ฒฝ์—์„œ Run ๋˜๋Š”๋ฐ, Node.js 8.x ์ด์ƒ๋ถ€ํ„ฐ ๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„์˜ ๋ชจ๋˜ ECMAScript ๊ธฐ๋Šฅ๋“ค์„ ์ง€์›ํ•˜๊ณ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— Babel ๋˜ํ•œ ํ•„์š”์—†๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ๋‹ค๋งŒ ์•„๋ž˜์˜ ์˜ˆ์™ธ ์‚ฌํ•ญ์— ํ•ด๋‹นํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ๋‹ค๋ฉด ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „ Jest๊ฐ€ ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋“ˆ์„ ์ ์ ˆํ•˜๊ฒŒ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ์•Œ๋ ค์ฃผ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค!

  • ES6 import/export ๋ชจ๋“ˆ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, Node.js์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก module.exports๋กœ ๋ณ€ํ™˜๋˜์–ด์•ผ ํ•จ
  • .vue ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, vue-jest๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€ํ™˜๋˜์–ด์•ผ ํ•จ
  • TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ts-jest๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€ํ™˜๋˜์–ด์•ผ ํ•จ

๋งŒ์•ฝ ํ…Œ์ŠคํŠธ ์ „ ๋ณ€ํ™˜์ด ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ๋‹ค๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด transformIgnorePatterns ์˜ต์…˜์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์„ค๋ช…์€ @vue/cli-plugin-unit-jest ๊ณต์‹๋ฌธ์„œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// jest.config.js

module.exports = {
	// ..
	transformIgnorePatterns: ["/node_modules/(?!name-of-lib-to-transform)"],
};

6. ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ •ํ•˜๊ธฐ: Jest ์„ค์ •, ์ปค๋ฒ„๋ฆฌ์ง€ ๋ฆฌํฌํŠธ

6-1. Jest ์„ค์ •

Jest๋Š” ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ์ธก์ •ํ•˜๊ณ  ์ปค๋ฒ„๋ฆฌ์ง€ ๋ณด๊ณ ์„œ๋„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด jest.config.js ํŒŒ์ผ์— ํ•ด๋‹น ์˜ต์…˜๋“ค์„ ์ง€์ •ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด collectCoverageFrom ๊ฐ’์„ ์ง€์ •ํ•ด์ฃผ๋ฉด, ๋ชจ๋“  *.ts, *.vue ํŒŒ์ผ์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ์ˆ˜์ง‘ํ•˜๋˜, node_modules, coverage, tests ๋””๋ ‰ํ† ๋ฆฌ์— ์กด์žฌํ•˜๋Š” ํŒŒ์ผ๋“ค์€ ์ œ์™ธํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

// jest.config.js

module.exports = {
	// ..
	collectCoverage: true,
	collectCoverageFrom: [
		"**/*.{ts,vue}",
		"!**/node_modules/**",
		"!**/coverage/**",
		"!**/tests/**",
	],
};

6-2. ์ปค๋ฒ„๋ฆฌ์ง€ ๋ฆฌํฌํŠธ

์ด์ œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ด…๋‹ˆ๋‹ค.

# vue-cli-service test:unit
yarn test:unit

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ณด๊ณ ์„œ๊ฐ€ ์ถœ๋ ฅ๋˜๊ณ ์š”,


๋ณด๊ณ ์„œ์˜ ๊ฐ ํ•ญ๋ชฉ์€ ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

  • Stmts: ์ตœ์†Œ ํ•œ ๋ฒˆ ์ด์ƒ ์‹คํ–‰๋œ ๋ช…๋ น๋ฌธ(๋ณ€์ˆ˜์— ๊ฐ’ ์ €์žฅ, ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋“ฑ) ์ฝ”๋“œ์˜ ๋น„์œจ
  • Branch: ์ตœ์†Œ ํ•œ ๋ฒˆ ์ด์ƒ if, switch์™€ ๊ฐ™์€ ๋ถ„๊ธฐ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋œ ๋น„์œจ
  • Funcs: ์ตœ์†Œ ํ•œ ๋ฒˆ ์ด์ƒ ํ˜ธ์ถœ๋œ ํ•จ์ˆ˜์˜ ๋น„์œจ
  • Lines: ์ตœ์†Œ ํ•œ ๋ฒˆ ์ด์ƒ ์‹คํ–‰๋œ ์ฝ”๋“œ ๋ผ์ธ์˜ ๋น„์œจ
  • Uncovered Line: ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€์— ์ธก์ •๋˜์ง€ ์•Š์€ ์ฝ”๋“œ ๋ผ์ธ ์ˆ˜

๋ถ‰์€์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋œ ํŒŒ์ผ๋“ค์€ ๋Œ€์‘ํ•˜๋Š” ํ…Œ์ŠคํŠธ ํŒŒ์ผ์ด ์—†๋Š” ํŒŒ์ผ๋“ค์ž…๋‹ˆ๋‹ค. VTU์˜ Jest Preset์— ๋”ฐ๋ผ, Jest๋Š” ๋””ํดํŠธ๋กœ ๋‹ค์Œ ๊ฒฝ๋กœ์— ํ•ด๋‹นํ•˜๋Š” ํ…Œ์ŠคํŠธ ํŒŒ์ผ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

module.exports = {
	// ..
	testMatch: ["**/tests/unit/**/*.spec.[jt]s?(x)", "**/__tests__/*.[jt]s?(x)"],
};

์•ฑ ์ƒ์„ฑ์‹œ ์ž๋™ ํฌํ•จ๋œ ์ƒ˜ํ”Œ ํ…Œ์ŠคํŠธ ํŒŒ์ผ์ธ tests/unit/example.spec.ts์—์„œ HelloWorld.vue ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— HelloWorld.vue ํŒŒ์ผ์— ๋Œ€ํ•œ ์ปค๋ฒ„๋ฆฌ์ง€๋งŒ 100์ธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



References