before, after 사용하기

Jest에서는 before와 after를 활용해서 테스트 전후에 실행할 코드를 작성 할 수 있습니다.


beforeEach와 afterEach

beforeEach는 테스트가 실행 되기전 afterEach는 테스트가 실행 된 후 실행이 됩니다. 단어 Each에서도 유추할수 있듯이 각각의 테스트가 실행되기 전후에 모두 실행이된다. 예를 들어 3개의 테스트가 있으면 beforeEach 또한 3번 호출된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
beforeEach(() => {
console.log('테스트 전 실행 됨');
});

afterEach(() => {
console.log('테스트 후 실행 돔');
})

for (; i < 6; i++) {
test(`테스트${i}`, ((i) => (() => {
console.log(`테스트${i}`);
}))(i));
}

비동기 사용하기

before, after에서도 비동기를 사용할수 있다. Jest 비동기를 통해서 Jest의 비동기 사용법을 알수 있다. 여기에서도 promise를 반환해주면 비동기를 사용할수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
function asyncFn() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('비동기 사용');
resolve();
}, 500);
});
}

beforeEach(() => {
return asyncFn();
});

async, await를 통해서도 비동기를 사용할수 있다.

1
2
3
beforeEach(async() => {
await asyncFn();
})

오직 한번만 실행 하기

before와 after를 테스트 파일에서 오직 한번 만 사용하기 위해서는 beforeAllafterAll를 사용하면 된다.

1
2
3
4
5
6
7
beforeAll(() => {
console.log('테스트 전 오직 한번만 실행된다.');
});

afterAll(() => {
console.log('테스트 후 한번만 호출된다.');
});

describe 내부에서의 before, after 사용하기

describe 내부에서 before와 after를 사용하는 경우에는 describe 내부의 테스트가 호출 될 경우에만 호출된다. 하지만 describe 외부의 before와 after는 describe 내부의 test를 포함한 테스트 파일 전체의 test가 호출 될때 호출이 된다.


test.only 사용하기

테스트가 실패할때 가장 먼저 확인 해봐야 할것은 테스트 케이스가 오직 실패하는 케이스만 실행 했을때에도 실패하는지 이다.
이를 위해서 test.only를 사용하면 다른 테스트는 스킵하고 해당 테스트만 실행된다. 이때 스킵되는 테스트는 test.only가 존재하는 테스트 파일에 한해서이다.

1
2
3
test.only('', () => {

});

Comment and share

비동기에서 사용할 함수

1
2
3
4
5
function fetchData(check) {
return new Promise((resolve, reject) => {
typeof check === 'function' ? check() : check ? resolve('peanut butter') : reject('error');
});
}

콜백을 이용한 비동기 테스트 해보기

일반적인 상황에서 비동기를 사용하는 보편적인 방법 중 하나는 콜백을 사용하는 것이다. 하지만 Jest에서 테스트 할때는 의도대로 작동 하지 않는다.
Jest 테스트는 콜백을 호출할때까지 기다려주지 않는다. 테스트 함수 내에서 마지막 코드까지 실행을 하게되면 테스트를 완료하게 된다. 그래서 항상 테스트가 통과하게 된다. 테스트 실패하도록 값을 변경하여도 통과하는 것을 확인 할수있다.

1
2
3
4
5
6
7
test('비동기를 콜백 활용하기 - 실패', () => {
function callback(data) {
expect(data).toBe('peanut butter');
}

fetchData(callback);
});

파라미터 done을 활용한 비동기 테스트

done을 파라미터로 받은 경우에는 Jest에서는 done 함수가 호출 될때까지 테스트를 완료하지 않고 기다린다.

1
2
3
4
5
6
7
8
9
10
11
12
test('done을 활용하기', (done) => {
function callback(data) {
try {
expect(data).toBe('peanut butter');
done();
} catch (e) {
done(error);
}
}

fetchData(callback);
});

Promise 활용 하기

비동기로 promise를 사용하는 경우에는 훨씐 간편하게 작성 할수 있다. promise를 리턴해주면 테스트가 정상적으로 작동하는 것을 확인할수 있다. 이때 promise를 리턴하지 않으면 테스트를 수행하기 전에 끝난다.

1
2
3
4
5
test('프로미스 활용하기', () => {
return fetchData(true).then((data) => {
expect(data).toBe('peanut butter');
});
})

Promise Catch 테스트 하기

promise의 reject 또한 테스트 할수 있다. 이경우에는 then 대신에 catch를 활용한다. catch 내부에서 테스트 할 코드를 작성한다. 이때 expect.assertions(에러 발생한 횟수)를 테스트 위에 적어주지 않으면 테스트는 정상적으로 실행되지 못하고 완료되어 버린다.

1
2
3
4
test('프로미스 catch 테스트하기', () => {
expect.assertions(1);
return fetchData(false).catch((e) => expect(e).toMatch('error'));
})

Matchers인 resolves를 활용하기

promise then 대신에 Jest에서 제공하는 Matchers 중에 하나인 resolves를 활용할수도 있다. expect에 promise를 넘겨준다. 이때 여전히 return을 사용하여야 한다.

1
2
3
test('resolves 사용하기', () => {
return expect(fetchData(true)).resolves.toBe('peanut butter');
});

Matchers인 rejects를 활용하기

promise catch 대신에 Jest에서 제공하는 Matchers 중에 하나인 rejects를 활용 할수도 있다. 사용 방법은 resolves와 유사하다. 이때 promise catch와 async와는 달리 expect.assertions를 사용하지 않아도 된다.

1
2
3
test('rejects 활용하기', () => {
return expect(fetchData(false)).rejects.toBe('error');
});

async와 await를 활용하기

es6에서 제공하는 비동기 방법인 async와 await를 활용해서도 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
test('async와 await를 활용하기', async() => {
let data = await fetchData(true);
expect(data).toBe('peanut butter');
});

test('async와 await를 활용하기', async() => {
expect.assertions(1);

try {
await fetchData(false);
} catch (e) {
expect(e).toMatch('error');
}
});

Comment and share

데이터 테스트 하기

js에서는 데이터를 검증 할때 아래와 같이 작성한다.

1
expect(wrapper.vm.message).toBe('message');

ts에서도 위와 같은 코드를 작성한 후에 테스트를 돌리니 아래와 같은 에러가 발생하였다.

1
2
TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
src/components/__tests__/HelloWorld.test.ts:12:23 - error TS2339: Property 'message' does not exist on type 'CombinedVueInstance<Vue, object, object, object, Record<never, any>>'.

그래서 정상적으로 테스트 하기 위한 방법은 두가지 정도 인거 같다.


1. vm.$data 사용하기

vm에는 data값을 가지고 있는 $data 객체가 존재한다. 해당 객체를 통해서 검증을 하면 가능하다.

1
expect(wrapper.vm.$data.message).toBe('message');

2. jest.config.js 수정하기

ts-jest를 사용하면 diagnostics옵션의 디폴트값이 true인데 위 코드 처럼 사용할 경우 에러를 발생시킨다. 이를 false로 설정하면 정상적으로 테스트가 가능하다.

1
2
3
4
5
6
7
8
module.exports = {
/// ...
globals: {
'ts-jest': {
diagnostics: false
}
}
}

Comment and share

타입스크립트를 사용할때 추가적으로 설치해야할 라이브러리

뷰를 jest를 통해서 테스트 하고자 할때 설치해야할 라이브러리 목록은 here를 통해서 확인이 가능하다.

  1. ts-jest
  2. @types/jest

jest.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module.export = {
// ...
"moduleFileExtensions": [
// ...
"ts"
],
"transform": {
// ...
"^.+\\.tsx?$": "ts-jest"
},

// jest는 기본적으로 js만을 테스트 파일로 찾기 때문에 .ts 파일도 테스트 파일로 찾을수 있도록 설정 해준다.
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$"
}

tsconfig.json

types에 jest를 추가해준다.

1
2
3
4
5
6
7
8
9
{
"compilerOptions": {
// ...
"types": [
// ...
"jest"
],
}
}

Comment and share

Setup

테스트 코드를 작성하다 보면 테스트마다 공통적으로 사용이 되는 코드가 존재한다. 그중에서 테스트 코드 로직을 실행 하기 이전에 실행이 되어야 하는 공통 코드가 있다. 이때는 사용되는 함수가 beforeEach 함수이다.
해당하는 함수는 각 테스트 코드가 실행되기 이전에 호출된다.

1
2
3
beforeEach(() => {
// 보통 변수의 초기화 등의 코드가 들어가거나 테스트 코드 전에 실행되어야 할 로직이 들어간다.
});

테스트 종료시 호출

각 테스트가 종료 후에 호출이 되는 함수도 존재한다. 이는 afterEach 함수이다.

1
2
3
afterEach(() => {
// 테스트 종류 후에 작업 해야 할 로직이 들어간다.
})

Comment and share

new Vue를 이용한 컴포넌트 테스트

아래의 방법은 실제로 컴포넌트를 생성하여 테스트 하는 방법입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- HelloWorld.js -->

<template>
<div>{{ message }}</div>
</template>

<script>
export default {
data() {
return {
message: "Hello"
}
}
}
</script>

<style>

</style>
1
2
3
4
5
6
7
8
9
10
11
12
// helloworld.test.js

import Vue from 'vue';
import HelloWorld from '../components/HelloWorld.vue';

describe(('HelloWorld'), () => {
it('new Vue를 이용한 테스트', () => {
const helloWorld = new Vue(HelloWorld).$mount();
const message = 'Hello';
expect(helloWorld.message).toBe(message);
});
});

Vue Test Utils 이용한 컴포넌트 테스트

Vue Test Utils에서 제공 하는 mount 함수를 이용해서 좀더 간편 하게 테스트를 할수 있습니다.
message에 접근 하기 위해서 vm 프로퍼티를 이용한다는게 다릅니다.

1
2
3
4
5
6
7
8
9
10
11
12
// helloworld.test.js

import { mount } from '@vue/test-utils';
import HelloWorld from '../components/HelloWorld.vue';

describe(('HelloWorld'), () => {
it('new Vue를 이용한 테스트', () => {
const wrapper = mount(HelloWorld);
const message = 'Hello';
expect(wrapper.vm.message).toBe(message);
});
});

Comment and share

파일 import 불가

Jest에서 Import를 사용 하는 경우 아래와 같이 에러가 발생한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Test suite failed to run

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html

Details:

D:\GIT 소스코드 저장소\TDD\JEST\vue-jest\vue-jest-start\src\test\helloworld.test.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { mount } from '@vue/test-utils';

1. 해당 라이브러리가 정상적으로 설치 되어 있는지 확인한다.

1) jest
2) vue-jest
3) @babel/core
4) @babel/preset-env
5) babel-jest
6) @vue/test-utils
7) babel-core@^7.0.0-bridge.0 (바벨이 7.0 이상 사용중일때)


2. jest.config.js

package.json 또는 jest.config.js에 아래와 같이 입력 한다.

1
2
3
4
5
6
7
8
9
10
11
module.export = {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.vue$": "vue-jest"
}
}

3. babel.config.js

package.json 또는 babel.config.js에 아래와 같이 입력 한다.

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};

정리

구글링 결과 Jest에서 Import를 사용하기 위해서는 Babel을 설치해야 하는 듯하다.
그리고 babel 7 이상을 사용 한다면 babel-core@^7.0.0-bridge.0를 설치해 주어야 한다.

Comment and share

JEST 시작

in javascript, TDD, jest

JEST란

JEST는 페이스북에서 개발한 ‘테스트 프레임워크’ 이다. JEST 이전에는 테스트 라이브러리를 조합해서 사용하였으나 JEST는 이름도 프레임워크인만큼 Test Runner와 Test Mathcher 그리고 Test Mock까지 모두 지원하고 있다.


JEST 설치

아래의 명령어를 통해서 jest를 설치 할수 있다.

1
npm i jest

첫 테스트 코드 작성

test.js라는 파일을 만들고 아래의 코드를 추가한다. JEST에서 테스트 코드 작성은 아래와 같다.

1
2
3
test('테스트 정의', () => {
// 테스트할 로직 구현
});
1
2
3
4
test('문자열은 Hello이다.', () => {
const str = 'Hello'
expect('Hello').toBe(str);
});

package.json에서 scripts 수정

package.json을 아래와 같이 수정한후에 npm run test라고 실행하면 테스트를 시작한다.

1
2
3
4
5
{
"scripts" : {
"test": "jest"
}
}

describe와 it을 이용한 테스트 코드 작성

위에서는 test 함수를 통해서 테스트 코드를 작성하는 방법에 대해서 알아보았다. Jest에서는 이 뿐 아니라 describe와 it을 통해서도 작성 가능하다. describe은 일종의 테스트 그룹이고, it은 작은 단위의 테스트이다. it이 위의 test와 같은 단위이다.

1
2
3
4
5
describe('', () => {
it('', () => {
// 테스트 코드 작성
})
});

Comment and share

  • page 1 of 1

Moon Star

author.bio


author.job