요즘(몇 년 전 부터 꾸준히 이야기가 많았음) TDD(Test Driven Development) 에 대한 이야기가 많습니다.
하지만 스타트업이나 빨리 개발해서 아웃풋을 뽑아내야하는 그런 상황이라면 사실 테스트를하면서
개발하는 것은, 어느 정도 무리가 있지 않을까? 생각합니다.
그럼에도 불구하고 왜 test를 해야할까요? 저도 의문이 생겼습니다.
테스트에 대한 인강을 듣고있긴 하지만, 지금 내 프로젝트들은 잘 구동되고 최적화도 열심히 하고 있는데
굳이 테스트를 하면서까지 로직을 만들어야하는가? 라는 생각도 듭니다.
그러면 테스트는 무엇이고, 왜 써야하고, 어떻게 써야하는지 알아봅시다!
테스트는 여러가지 종류가 있습니다.
가장 작은 단위(함수, 메소드, 클래스)를 독립적으로 테스트
여러 모듈이나 서비스가 함께 잘 작동하는지 테스트
실제 사용자 시나리오 전체를 테스트
UI 컴포넌트의 동작과 렌더링을 테스트
등등.. 그 이외에도 회귀 테스트, 스냅샷 테스트 등의 여러가지 테스트 들이 있습니다.
이렇게 복잡하고 종류도 많은 테스트들 왜 해야할까요?
// 실제 자주 발생하는 케이스
function calculateDiscount(price, quantity) {
// 수정 전: 할인율 계산 오류
return price * quantity * 0.1;
// 수정 후: 올바른 할인 계산
return price * quantity * (1 - 0.1);
}
// 테스트가 있다면 즉시 발견 가능
test('할인 계산', () => {
expect(calculateDiscount(1000, 2)).toBe(1800);
});
내 예상과 다르게 결과가 나온 경우들이 있지않나요? 저는 엄청 많습니다..
이러한 함수들의 결과가 내가 원하는 경우처럼 나오는지 확인하면 좋겠죠?
생길 수 있는 버그를 예방하고 발견하는데 있어서 장점이 있습니다.
// Before: 레거시 코드
function handleSubmit(data) {
// 복잡한 로직...
}
// After: 리팩토링
function validateData(data) {
// 데이터 검증 로직
}
function processData(data) {
// 데이터 처리 로직
}
// 테스트가 있다면 리팩토링 후에도
// 같은 결과가 나오는지 즉시 확인 가능
함수를 작성하고 리팩토링한 경험들이 있으시나요? 성능적인 측면이나 가독성 등에서 개선하기 위한 노력들은
꼭 필요하다고 생각합니다. 근데 리팩토링 하는 과정속에서 이전과 다른 결과가 나온다면
그 리팩토링은 안하느니만 못하겠죠?
하지만 테스트를 작성한다면 리팩토링을해도 안전하게 할 수 있다~
describe('장바구니 기능', () => {
it('상품 추가 시 총액이 올바르게 계산된다', () => {
const cart = new Cart();
cart.addItem({ price: 1000, quantity: 2 });
expect(cart.total).toBe(2000);
});
it('할인 쿠폰 적용 시 할인이 반영된다', () => {
// ...
});
});
// 이 테스트 코드만 봐도 기능의 동작 방식을 이해할 수 있음
굳이 코드에 주석을 달지 않아도 설명을 함수에 적기 때문에 바로 어떤 기능인지 알 수 있겠죠?
그러면 인수인계하거나 서로 공유할 때도 편하게 할 수 있을겁니다~
아주 다양~ 하게 적용할 수 있습니다! 저 위에 테스트의 종류들을 보셨다시피
함수의 아주 작은 조각부터 브라우저에 나타나는 전체적인 시나리오까지 전부 테스트 할 수 있습니다!
하지만 현실적으로는 점진적으로 도입하는 것이 좋지 않을까? 라고 생각합니다.
그 이유는
이러한 이유들로 인해서 점진적으로 테스트를 도입하려고 합니다.
그래서 저는 세 가지의 부분에서 테스트를 진행해보고자 합니다.
이 세 부분에서 테스트를 진행하고 제품의 안정성을 높여보도록 하죠~~!
[vitest 공식문서] https://vitest.dev/guide/why.html
저는 현재 프로젝트를 vite + react + typescript 를 사용하고 있어서
편한 호환성으로 이득을 취하고자 vitest를 사용하려고 합니다. 자세한 내용은 위에 나와있습니다.
음.. 요약하자면
라네요~
이제 설치 한 번 해볼까요?
# Vitest 및 관련 패키지 설치
npm install -D vitest
npm install -D @testing-library/react @testing-library/jest-dom
npm install -D jsdom
npm install -D @testing-library/user-event @testing-library/react-hooks
저는 리액트 훅도 테스트할꺼니깐 관련 라이브러리들 설치해줍니다~
vite.config.ts
/// <reference types="vitest" />
/// <reference types="vite/client" />
export default defineConfig({
base: "/",
test: {
globals: true,
environment: "jsdom",
css: true,
coverage: {
reporter: ["text", "json", "html"],
},
},
})
tsconfig.app.json
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"composite": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components": ["src/components/*"]
},
// types 추가 해주면 됩니다! 요기!
"types": ["vitest/globals", "@testing-library/jest-dom"],
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"verbatimModuleSyntax": true
},
"include": ["src"]
}
잘 설치가 됐는지 테스트 한 번 해볼까요
일단 test 파일은 test 파일을 따로 만들던가 혹은 그 test 하고 싶은 파일과 같이
[파일명].spec.ts 를 같이 놓는 방법으로 위치시키는데
저는 같이 있는게 조금 더 관리하기 편할 것 같아서 같은 위치에 두고 한 번 테스트 해보겠습니다.
아무곳에서나 test.ts를 만들어줍니다
export function addTest(a: number, b: number) {
return a + b;
}
같은 위치에 test.spec.ts를 만들어줍니다.
import { addTest } from "./test";
describe("vitest 잘되는지 체크", () => {
it("더하기 테스트", () => {
expect(addTest(2, 3)).toBe(5);
});
});
잘되는지 체크해보겠습니다!
겁나 잘 돌아가죠?
저는 참고로 vitest vscode extension을 설치해서 cli 방식말고
클릭하는 방법으로 test 코드를 실행시켰습니다.
자 오늘은 이렇게 해서 테스트 코드는 무엇이고, 왜 써야하는지, 어떻게 써야하는지 , 그리고 vitest 세팅까지 한 번 알아봤습니다! 다음에는 react-hook 이나 비동기 함수등의 테스트를 어떻게 하는지 한 번 알아보도록 하겠습니다!
겁나 잘 돌아가죠?
저는 참고로 vitest vscode extension을 설치해서 cli 방식말고
클릭하는 방법으로 test 코드를 실행시켰습니다.
자 오늘은 이렇게 해서 테스트 코드는 무엇이고, 왜 써야하는지, 어떻게 써야하는지 , 그리고 vitest 세팅까지 한 번 알아봤습니다! 다음에는 react-hook 이나 비동기 함수등의 테스트를 어떻게 하는지 한 번 알아보도록 하겠습니다!