webpack
기반의 react
는 unitTest
를 하기 위해선 jest
가 국룰이었다.
그렇다면 vite
로 ESbuild
되어 있는 sveltKIT
에서는 기본 내장 TDD tool
인 vitest
를 써보자.
단위 테스트(unit test) 소프트웨어 설계의 최소 단위인 모듈이나 컴포넌트에 초점을 맞춰 테스트하는 것
멋진 말로 테스트 주도 개발 (비슷한 것으로 JDD가 있다.)
테스트를 먼저 깔아보고 그 테스트케이스
가 성공할 때까지 코드를 작성하는 개발 방식이다.
즉 기능을 실제로 구현하기 전에 테스트 케이스를 작성하고 모든 것을 테스트하여 매우 높은 수준의 품질을 유지하게 한다. 개발 중인 코드와 작동 방식을 명확하게 파악할 수 있다. 사실 백엔드 로직을 짜는데 더 많이 활용되지만, 비슷한 기술로 프론트엔드에도 잘 적용할 수 있다.
Vitest는 vite 환경에서 사용할 수 있는 Unit Testing 프레임워크이며, jest를 경험한 적이 있다면, 유사한 함수로 테스트를 진행할 수 있기 때문에 접근성이 좋으며, svelte에는 기본으로 내장되어있을 정도로 필수 지식이 되어가고 있다. (jest랑 비슷함)
% npm create svelte@latest vitest-sveltekit
npm을 통해 svelte를 설치하면 vitest를 사용할 것인지 물어본다.
그 때 YES를 누르자. (유퀴즈 느낌으로다가)
create-svelte version
Welcome to SvelteKit!
✔ Which Svelte app template? › Skeleton project
✔ Add type checking with TypeScript? › Yes, using JavaScript with JSDoc comments
✔ Add ESLint for code linting? … No / Yes
✔ Add Prettier for code formatting? … No / Yes
✔ Add Playwright for browser testing? … No / Yes
_**✔ Add Vitest for unit testing? … No / YES**_ 🤏🏽여기
Your project is ready!
✔ Type-checked JavaScript
https://www.typescriptlang.org/tsconfig#checkJs
✔ Vitest
https://vitest.dev
Install community-maintained integrations:
https://github.com/svelte-add/svelte-adders
Next steps:
1: cd vitest-sveltekit
2: npm install (or pnpm install, etc)
3: git init && git add -A && git commit -m "Initial commit" (optional)
4: npm run dev -- --open
To close the dev server, hit Ctrl-C
Stuck? Visit us at https://svelte.dev/chat
이게 설치가 완료되었으니, 실행해본다.
cd vitest-sveltekit // folder로 들어가기
npm install // 기본 패키지 설치하기
code . // vscode로 실행하기
package.JSON에 들어가 vitest가 설치된 것을 확인한다. svelteKIT의 재밌는 사실은 react처럼 dependencies와 devDependencies가 나눠져 있지않고, devDependencies만 있는 것을 볼 수 있다. 그래도 모두 개발모드로 라이브러리가 설치된다.
//package.JSON
"scripts": {
...,
"test:unit": "vitest"
},
터미널에서 npm run test:unit
을 입력한다.
% npm run test:unit
> vitest-sveltekit@0.0.1 test:unit
> vitest
DEV v0.25.8 /Users/mac/Desktop/vitest-sveltekit
✓ src/index.test.js (1)
Test Files 1 passed (1)
Tests 1 passed (1)
Start at 22:00:00
Duration 1.01s (transform 409ms, setup 0ms, collect 16ms, tests 3ms)
PASS Waiting for file changes...
press h to show help, press q to quit
뭐하나가 돌아가는것을 볼 수 있다. pass 라니 기분 좋다. 스벨트가 기본적으로 테스트코드를 하나 넣어주었다.
// index.test.ts
import { describe, it, expect } from 'vitest';
describe('sum test', () => {
it('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
});
우리는 각 routes 안에 있는 주소 별로 +page.svelte 파일을 이용해 테스트를 진행한다.
npm install --save-dev @testing-library/svelte
npm install --save-dev @testing-library/jest-dom jsdom
NOTE: jest-dom adds handy assertions to Jest and it is recommended, but not required. 엥 갑자기 jest를 쓴다고 할 수 있지만, jest-dom의 어썰션 기능을 쓰는걸 권장한다. 근데 필수는 아님.
세가지 라이브러리의 도움을 받아 진행한다. component render 등의 dom test를 위해 필요하다!
test 에 environment와 globals를 추가한다.
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [sveltekit()],
test: {
include: ['src/**/*.{test,spec}.{js,ts}'],
environment: 'jsdom',
globals: true,
},
});
<script>
let name = 'world';
let buttonText = 'Button';
const handleClick = () => {
buttonText = 'Button Click';
};
</script>
<h1>Welcome to SvelteKit! {name}</h1>
<button on:click={handleClick}>{buttonText}</button>
경로 : src/test/example.test.ts 컴포넌트 테스트를 위해 테스트 폴더를 만들고 멋진 작명의.test.ts(or js) 파일을 만든다.
//example.test.ts
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/svelte';
import Home from '../routes/+page.svelte';
it('renders Welcome text', () => {
render(Home, {name: hojun);
const Element = screen.getByText(/Welcome to SvelteKit hojun/);
expect(Element).toBeInTheDocument();
});
간단한 테스트를 작성한다. 테스트를 작성하기 위해선 또 공부를 해야하는데, dom에 접근하는 쿼리를 이해해야한다. 필요할때마다 검색해서 쓰는게 나을 것 같다.
간단히 공부 겸 설명하자면
it
이 것을 test 해볼 건데, render
함수를 통해 Home component를 rendering한다. mount 된 것과 같은 상황을 연출할 수 있다.
screen
query는 document body에 접근 할 수 있는데, getByText Query를 통해 text를 가져올 수 있다. query API 는 대부분 textMatch를 사용해 인자를 받는다.
//testing-library/svelte getByText link 이렇게 하면 주어진 TextMatch와 일치하는 textContent를 가진 텍스트 노드가 있는 모든 요소를 검색합니다.
//jest-dom ToBeInTheDocument() link This allows you to assert whether an element is present in the document or not.
버튼 클릭 시 바뀌는 text값을 확인하는 것이다.
redzone : 'Button Click' 라는 fail 값 주기
// HOME component
const handleClick = () => {
buttonText = 'Button Click';
};
//example.test.ts
test('button text', async () => {
render(HOME, { name: 'World' });
const button = screen.getByRole('button');
await fireEvent.click(button);
expect(button.innerHTML).toBe('Button Clicked');
});
테스트가 실패하는 것을 볼 수 있다.
// HOME component
const handleClick = () => {
buttonText = 'Button Clicked';
};
(사실 테스트를 수정하는게 아니라 컴포넌트 문서를 수정해야한다^^)
이렇게 간단하게 테스트를 진행해보았다.
사실 테스트를 왜 하냐 라는 생각을 엄청나게 심각하게 무지 미치도록으로 많이하게 된다. 당연 개발에 소요되는 시간을 테스트 작성에 사용할 수 밖에 없다. 하지만 장기적으로 봤을 때 컴포넌트 기획일 수도 있고, 유지보수에 탁월할 수 밖에 없다. 절대적으로 큰 기능위주로 테스트 케이스를 만들고 코드를 작성하는 습관을 들여야겠다.