TDD
TDD란
Test-driven development는 직역하자면 테스트 주도 개발이다.
프로그램을 개발하기 전 이 프로그램이 출력해야하는 결과에 대해 지정하고 기대하는 결과를 표현하는 테스트를 작성해야한다. 또한 이 테스트를 통과하는 프로그램을 개발해야한다.
TDD의 프로세스는 다음과 같다.
- 프로그램이 출력해야하는 결과에 대해 테스트 코드를 작성한다.
- 미리 작성된 테스트를 통과할 수 있는 프로그램을 개발한다.
- 개발한 프로그램이 테스트 코드를 통과하는지 확인한다.
- 테스트 코드를 리팩토링한다. (필요한 경우)
- 프로그램을 리팩토링한다. (필요한 경우)
- 프로그램의 목표를 달성할 때까지 위 프로세스를 반복한다.
모든 공부는 예시를 통해 쉽게 이해할 수 있다. 따라서 아래에 하나의 예시를 통해 이해해보자.
계산기 개발 (TDD)
덧셈, 뺄셈, 곱셈, 나눗셈이 가능한 계산기를 만들 것이다.
먼저 우리는 덧셈, 뺄셈, 곱셈, 나눗셈으로 기능 개발을 나누어 정의할 것이다.
- 덧셈 개발
- 뺄셈 개발
- 곱셈 개발
- 나눗셈 개발
가장 먼저 TDD는 프로그램의 테스트 코드를 먼저 작성해야한다.
덧셈의 경우 아래와 같이 테스트 코드를 작성할 수 있다.
function sumTester() {
if(sum(1,4)===5) console.log("Success!");
else console.log("Failed!");
}
다음으로 덧셈을 하는 프로그램을 개발한다.
function sum(a,b){
return a+b;
}
테스트 코드와 프로그램 모두 작성이 되었다면 결과를 확인하고 수정한다.
결과가 실패로 나온다면 프로그램을 수정하여 정상적인 결과가 나오도록 한다.
그 후 필요한 경우 테스트 코드와 프로그램을 차례대로 리팩토링한다.
나는 여러개의 테스트 케이스를 검증해야 한다고 생각했고 덧셈 뿐만 아니라 뺄셈과 곱셈, 나눗셈에 대한 테스트 케이스도 모두 확인해야하기 때문에 return 값을 boolean 값으로 설정했다.
function sumTester() {
const testCase = [
[1, 2, 3],
[1, 3, 4],
[5, 6, 11],
[68, 82, 150]
];
const result = testCase.map(([a,b,c]) => sum(a,b)===c);
return !result.includes(false);
}
위 처럼 리팩토링이 끝나면 다음 작업인 뺄셈, 곱셈, 나눗셈에 대해서도 동일한 프로세스를 실행하면 된다.
여러 연산을 동시에 할 수 있는 계산기일 경우 추가적인 작업이 더 있을 수 있다.
연산의 우선 순위, 복합적인 연산의 결과 테스트 코드 작성 등.
주의할 점
내가 참고하기 위해 시청했던 영상에서는 TDD에 3가지의 법칙을 적용하여 정의했다. 단순히 개발 전 테스트를 작성한다고 TDD라고 부르기에는 너무 다양한 방식으로 나뉠 것이다. 그것에 제한을 두는 것이 아래 세가지 법칙이다.
- 실패하는 단위 테스트를 작성하기 전까지는 한 줄의 상용 코드를 작성하지 않는다.
- 실패하기에 충분한 양의 단위 테스트만 작성해야 한다.
- 현재 실패하는 테스트 코드들을 성공시킬 만큼만 상용 코드를 작성해야한다.
장점
아직 TDD를 프로젝트에 적용해본 적은 없다. 공부를 하며 느낀 부분과 여러 블로그의 글을 참고하여 작성했다.
- 프로그램의 목적을 이해하는 데 도움이 된다.
- 자신감을 얻을 수 있다.
Jest를 사용하여 React 구성요소 테스트
아래에서는 참고 페이지를 따라서 react 구성요소 테스트 프로젝트를 진행해 볼 것이다.
React Project 생성
npx create-react-app tdd-react
라이브러리 설치
npx create-react-app
을 통해서 프로젝트를 생성한 경우에는 아래의 라이브러리를 설치할 필요 없음.
npm install jest @testing-library/react @testing-libraty/jest-dom @testinglibrary/user-evnet
Src 폴더 내의 모든 파일 삭제, 아래의 3개 파일 생성
index.js 파일 수정
// index.js
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
// App 컴포넌트를 root DOM에 렌더링
createRoot(document.getElementById("root")).render(<App />);
Test code 작성
아래의 테스트 코드는 TDD React라는 문구를 가진 h1 Tag를 검사하는 코드다.
// App.test.js
import React from "react";
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import App from "./App";
test("테스트의 제목을 여기에 작성합니다.", () => {
render(<App />);
expect(screen.getByRole("heading")).toHaveTextContent(/TDD React/i);
});
npm test App.test.js
명령어 실행 시 아래와 같이 실패하는 것을 확인할 수 있다.
프로그램 작성 (App.js 수정)
반드시 h1 tag 내에 TDD React라는 문구를 삽입해야 된다.
export default function App() {
return (
<div>
<h1>TDD React</h1>
</div>
);
}
Test 실행
npm test App.test.js
똑같이 따라했다면 아래와 같이 성공하는 것을 확인할 수 있다.
리팩토링 및 이 후 프로세스는 프로젝트에 적용해보고 연습하는 것을 추천한다.
마무리
TDD라는 개발 방법론을 따라서 개발을 하면 개발 기간도 늘어나고 전체적인 구조를 변경하는 것이 힘들다는 단점이 있다.
하지만 공부를 하는 입장으로 직접 구현을 해보아야 익숙해질 수 있고 사이드 프로젝트는 기간이 중요하지않기 때문에 TDD를 적용하여 개발할 예정이다.
적용 후 후기에 대한 내용은 모꼬지 사이드 프로젝트가 끝났을 때 작성 해야겠다.