테스트 주도 개발(TDD)란?

eunbi·2025년 2월 2일

CS 총정리

목록 보기
16/22

테스트 주도 개발(Test-Driven Development, TDD)은 테스트 코드를 먼저 작성한 후, 이를 통과하는 최소한의 기능을 구현하고, 이후 리팩토링을 반복하는 개발 방식이다.

이는 소프트웨어의 안정성과 유지보수성을 높이고, 버그를 줄이는 효과가 있다.


1. TDD의 핵심 개념

"테스트가 실패하는 코드"를 먼저 작성

테스트를 통과할 수 있는 최소한의 코드 작성

테스트를 지속적으로 실행하며 코드 개선(리팩토링) 진행

즉, "테스트 → 기능 구현 → 리팩토링" 과정을 반복하면서 코드를 점진적으로 발전시키는 방식이다.


2. TDD의 프로세스

TDD는 세 단계로 이루어진다.

📌 1) RED 단계 (테스트 실패)

  • 먼저 테스트 코드를 작성한다.
  • 아직 기능이 구현되지 않았기 때문에 테스트는 반드시 실패해야 한다.

예제: Jest를 사용한 간단한 테스트

// sum.js
export function sum(a, b) {
  return a + b;
}
// sum.test.js
import { sum } from "./sum";

test("1 + 2는 3이 되어야 한다", () => {
  expect(sum(1, 2)).toBe(3);
});
  • 실행하면 테스트가 실패해야 한다. (sum 함수가 아직 없기 때문)
 FAIL  ./sum.test.js
 ReferenceError: sum is not defined

📌 2) GREEN 단계 (테스트 성공)

  • 테스트를 통과할 최소한의 기능을 구현한다.
  • 단, 최대한 간단하게 작성하여 테스트를 통과시키는 것이 중요하다.

sum 함수 구현

export function sum(a, b) {
  return a + b;
}
  • 다시 테스트 실행하면 테스트가 통과된다.
 PASS  ./sum.test.js

📌 3) REFACTOR 단계 (리팩토링)

  • 중복 코드 제거, 성능 개선, 가독성 향상 등을 위한 리팩토링을 진행한다.
  • 리팩토링 후에도 테스트가 계속 통과해야 한다.

예제: 불필요한 코드 제거

export const sum = (a, b) => a + b;
  • 다시 테스트를 실행하여 모든 테스트가 통과하면 리팩토링 성공! 🎉

3. TDD의 장점

TDD를 적용하면 여러 가지 이점이 있다.

1) 코드 안정성 증가

  • 코드가 변경될 때마다 테스트를 실행하면 버그를 조기에 발견할 수 있다.
  • 예기치 않은 부작용을 줄여 코드의 신뢰성을 보장할 수 있다.

2) 유지보수성과 확장성 향상

  • 새로운 기능 추가 시, 기존 테스트를 실행하여 문제가 없는지 확인할 수 있다.
  • 팀 프로젝트에서도 안전하게 코드 변경이 가능하다.

3) 개발 속도 향상

  • 초기에는 테스트 작성이 시간이 걸리지만, 디버깅 시간이 줄어들어 장기적으로 생산성이 향상된다.
  • 예상하지 못한 버그를 줄여 개발 프로세스가 원활해진다.

4) 문서화 역할

  • 테스트 코드 자체가 어떤 기능을 하는지 설명하는 문서의 역할을 한다.
  • 코드 이해도가 높아져 협업 시 도움이 된다.

4. TDD를 위한 대표적인 테스트 프레임워크

📌 1) Jest (JavaScript 테스트 프레임워크)

  • Facebook에서 개발한 JavaScript 테스트 프레임워크
  • React, Node.js 환경에서 가장 많이 사용됨
  • 사용법이 간단하며 스냅샷 테스트 및 비동기 코드 테스트 가능
  • 추천 사용: Next.js, React, Express.js 프로젝트
npm install --save-dev jest
// jest.config.js
module.exports = {
  testEnvironment: "node",
};
test("3 + 5는 8이어야 한다", () => {
  expect(3 + 5).toBe(8);
});

📌 2) Mocha + Chai

  • Node.js 기반의 테스트 프레임워크
  • Mocha는 테스트 러너, Chai는 테스트 어서션 라이브러리로 사용됨
  • Jest보다 설정이 필요하지만 커스터마이징이 유리함
  • 추천 사용: 백엔드(Node.js) 프로젝트
npm install --save-dev mocha chai
const { expect } = require("chai");

describe("기본 수학 테스트", function () {
  it("2 + 2는 4이어야 한다", function () {
    expect(2 + 2).to.equal(4);
  });
});

📌 3) Cypress (E2E 테스트)

  • 브라우저 환경에서 실제 UI 테스트 가능
  • 사용자가 웹사이트를 사용하는 방식 그대로 E2E(End-to-End) 테스트 가능
  • 추천 사용: 프론트엔드 애플리케이션 테스트 (React, Vue, Angular)
npm install cypress --save-dev
describe("로그인 테스트", () => {
  it("올바른 이메일과 비밀번호를 입력하면 로그인되어야 한다", () => {
    cy.visit("/login");
    cy.get("input[name=email]").type("test@example.com");
    cy.get("input[name=password]").type("password123");
    cy.get("button[type=submit]").click();
    cy.url().should("include", "/dashboard");
  });
});

5. 실무에서 TDD 적용 방법

💡 실제 프로젝트에서 TDD를 적용하는 방법은 다음과 같다.

1) 단위 테스트(Unit Test)

  • 함수, 모듈, API 등의 작은 단위별 테스트 작성
  • Jest, Mocha, Chai 등을 사용하여 비즈니스 로직 검증

2) 통합 테스트(Integration Test)

  • 여러 모듈이 정상적으로 상호작용하는지 확인
  • API 호출, DB 연동 테스트 진행

3) E2E 테스트(End-to-End Test)

  • 사용자 시나리오를 테스트하여 UI와 백엔드 간의 통합 테스트 수행
  • Cypress, Selenium 등을 활용하여 실제 브라우저에서 동작 테스트

6. 결론

TDD는 코드의 품질을 높이고, 유지보수를 쉽게 하며, 버그를 줄이는 효과적인 개발 방식이다.

처음에는 테스트 작성이 번거롭게 느껴질 수 있지만, 장기적으로 개발 속도를 높이고 코드의 안정성을 확보하는 데 도움이 된다.

Jest, Mocha, Cypress 등의 다양한 테스트 프레임워크를 활용하면 TDD를 보다 쉽게 적용할 수 있다.

0개의 댓글