Jest 단위 테스트 관련


:raising_hand: Jest Unit Test 사용법에 대한 공부내용을 기록하는 포스트 입니다.


1. 개요


개발을 진행하면서 직접 화면에서 확인하는 것이 아닌, 테스팅 라이브러리를 통해 단위 테스트를 하는 방법을 간단하게 포스팅한다.

Jest를 사용하였고, 현재 이번 프로젝트에 적용할지에 대한 고민을 하고 있다.

2. 설치


먼저 Vue-Cli를 통해 설정을 하게 되면 아래와 같이 test-utils, vue2-jest, jest등 테스팅 라이브러리가 디펜던시로 들어오게 된다.

image

그리고 생성된 프로젝트안에 jest.config.js를 확인하고 아래 코드를 추가한다.

	testMatch: [
		'<rootDir>/src/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)',
	],

위 코드를 추가하면 우리는 spec 파일을 만들어 테스팅 코드를 작성하면되고 알아서 해당 파일을 실행할 수 있다.

3. Jest 사용법


회원가입을 위한 아래와 같은 Form을 만들었고, 이부분에 대한 간단한 테스팅 작성법을 알아보자.

<template>
	<div class="contents">
		<div class="form-wrapper form-wrapper-sm">
			<form @submit.prevent="submitForm" class="form">
				<div>
					<label for="username">id : </label>
					<input id="username" type="text" v-model="username" />
				</div>
				<div>
					<label for="password">password : </label>
					<input id="password" type="text" v-model="password" />
				</div>
				<div>
					<label for="nickname">nickname : </label>
					<input id="nickname" type="text" v-model="nickname" />
				</div>
				<button
					:disabled="!isJoinValidation || !password"
					type="submit"
					class="btn"
					:class="!isJoinValidation || !password ? 'disabled' : null"
				>
					회원 가입
				</button>
				<p class="log"></p>
			</form>
		</div>
	</div>
</template>

<script>
import { registUser } from '@/api/auth';
import { validateEmail } from '@/utils/validation';
export default {
	data() {
		return {
			username: '',
			password: '',
			nickname: '',
			logMessage: '',
		};
	},
	computed: {
		isJoinValidation() {
			return validateEmail(this.username);
		},
	},
	methods: {
		async submitForm() {
			try {
				const userData = {
					username: this.username,
					password: this.password,
					nickname: this.nickname,
				};
				const { data } = await registUser(userData);
				this.logMessage = `${data.username}님이 가입 되었습니다.`;
				this.initForm();
			} catch (error) {
				this.logMessage = error.response.data;
			}
		},
		initForm() {
			this.username = '';
			this.password = '';
			this.nickname = '';
		},
	},
};
</script>

<style></style>

먼저 이번에 포스팅할 컴포넌트는 회원가입(SignupForm.vue) 이므로 해당 페이지와 vue/test-utils에서 제공하는 shallowMountimport 해 주도록 한다.

import SignupForm from '@/components/SignupForm.vue';
import { shallowMount } from '@vue/test-utils';

shallowMount를 통해서 우리가 원하는 html에 접근할 수 있다고 이해하면 될 것 이다.

  • describe

describe를 통해 테스트 컴포넌트군을 정의한다.

// SignupForm.spec
describe('SignupForm.vue', () => {}
//LoginForm.spec
describe('LoginForm.vue', () => {}
  • test

test를 통해 컴포넌트 군에서 단위별로 테스트할 코드를 작성한다.

	test('가입 시 ID 값은 이메일 형식이어야 한다.', () => {
		// 테스팅 코드
	});
	test('회원가입 버튼은 ID 와 PW 유효성이 확인되기전엔 disabled 되야 한다.', () => {
		// 테스팅 코드
	});
  • wrapper

wrapper 즉 위에서 설명한 shallowMount를 통해서 html에 접근할 수 있도록 정의해준다.

	const wrapper = shallowMount(SignupForm, {
		data() {
			return {
				username: 'test@abc.com',
			};
		},
	});

shallowMount의 2번째 인자에는 옵션이 들어가는데 여기서 우리는 실제 해당 컴포넌트에서 확인하고 싶은 data값을 넣어볼 수 있다.

  • 전체 코드

// 컴포넌트 로딩
import SignupForm from '@/components/SignupForm.vue';
// 테스트 유틸 라이브러리 로딩
import { shallowMount } from '@vue/test-utils';

// SignupForm 테스트 군 산정
describe('SignupForm.vue', () => {
	// ID 값이 이메일인지 여부에 대한 테스팅 명시
	test('가입 시 ID 값은 이메일 형식이어야 한다.', () => {
		// 위에서 로딩한 컴포넌트를 shallowMount를 통해 wrapper 에 매핑
		const wrapper = shallowMount(SignupForm, {
			// SignupForm내 테스팅할 Data 값을 정의
			data() {
				return {
					username: 'test@abc.com',
				};
			},
		});
		// wrapper.vm 을 통해 isJoinValidation 함수의 여부 반환
		const idValid = wrapper.vm.isJoinValidation;
		// isVAlid 값이 Ture 인지 확인
		expect(idValid).toBeTruthy();
	});
	// 회원가입 버튼이 disabled 상태인지 확인하는 테스트군 산정
	test('회원가입 버튼은 ID 와 PW 유효성이 확인되기전엔 disabled 되야 한다.', () => {
		// shallowMount를 통해 로딩한 컴포넌트 매핑
		const wrapper = shallowMount(SignupForm, {
			data() {
				return {
					username: '',
					password: '',
				};
			},
		});
		// find 를 통해 특정 Tag Element 매핑
		const btnElement = wrapper.find('.btn');
		// 해당 button 의 disabled 값 확인
		expect(btnElement.element.disabled).toBeTruthy();
	});
});

4. 최종 정리


간단하게 테스팅하는 부분을 확인하였지만, 실제로 실무에서 사용하도록 하려면 더 많은 경험이 필요할 것 같다.

이번 프로젝트에서 현재 프론트엔드 공통을 잡고 있는데 Jest를 써봐도 괜찮을 것 같다.

참고 사이트