학습
Ruby 테스트 주도 개발 (TDD)
Ruby 테스트 주도 개발 (TDD) — 중급
테스트 주도 개발 (TDD)
1. 도입 (왜 배워야 하는가)
테스트 주도 개발(TDD)은 소프트웨어 개발 과정에서 코드 작성 전에 테스트 케이스를 먼저 작성하는 개발 방식입니다. 이 접근 방식은 코드의 품질을 높이고, 버그를 사전에 예방할 수 있는 강력한 방법입니다. TDD를 배우는 것은 실무에서 매우 중요한데, 이는 코드의 유지보수성을 높이고, 팀원 간의 협업을 원활하게 하는 데 큰 도움을 줍니다.
TDD를 도입하지 않으면, 코드가 예상치 못한 방법으로 작동하거나, 시간이 지남에 따라 복잡해져서 유지보수가 어려워질 수 있습니다. 특히, 팀 프로젝트에서는 각자의 코드가 다른 개발자와 충돌하는 일이 잦아지므로, TDD를 통해 이러한 문제를 사전에 방지할 수 있습니다.
2. 핵심 개념 설명
2.1 TDD의 원칙
TDD는 'Red-Green-Refactor'라는 세 가지 단계로 나뉩니다.
- Red: 실패하는 테스트를 작성하여 기능이 없음을 확인합니다.
- Green: 테스트를 통과하는 최소한의 코드를 작성합니다.
- Refactor: 코드를 리팩토링하여 가독성을 높이고 중복을 제거합니다.
비유
TDD는 요리를 할 때 레시피를 먼저 작성하고, 그에 맞춰 재료를 준비하는 것과 비슷합니다. 레시피(테스트)를 먼저 작성하면, 필요한 재료(코드)가 명확해지고, 요리 과정에서 실수를 줄일 수 있습니다.
2.2 관련 용어 정리
| 용어 | 설명 |
|---|---|
| 테스트 케이스 | 특정 기능이 올바르게 작동하는지 검증하는 코드 |
| 리팩토링 | 코드의 구조를 개선하되 기능은 변경하지 않음 |
| 단위 테스트 | 개별 모듈이나 함수의 기능을 검증하는 테스트 |
3. 기본 코드 예제
TDD를 활용하여 간단한 덧셈 기능을 구현하는 예제를 살펴보겠습니다.
# 1단계: 실패하는 테스트 작성
def test_addition
raise "테스트 실패: #{add(2, 3)}는 5가 아닙니다." unless add(2, 3) == 5
end
# 2단계: 최소한의 코드 작성
def add(a, b)
a + b
end
# 3단계: 테스트 실행
test_addition
실행 결과
테스트 실패: 5는 5가 아닙니다.
코드 한 줄씩 동작 설명
test_addition메서드를 정의합니다. 이 메서드는 덧셈 기능이 올바르게 작동하는지 확인합니다.raise구문을 사용하여 조건이 맞지 않으면 오류를 발생시킵니다.add메서드를 정의하고, 두 수를 더한 값을 반환합니다.test_addition메서드를 호출하여 테스트를 실행합니다.- 잘못된 코드: 기능 구현 후 테스트 작성.
- 올바른 코드: 항상 테스트를 먼저 작성하여 실패를 확인.
- 잘못된 코드: 코드 작성 후 리팩토링을 건너뛰는 것.
- 올바른 코드: 항상 리팩토링하여 가독성 높은 코드를 유지.
- TDD는 코드 품질을 높이고 유지보수를 용이하게 합니다.
- 'Red-Green-Refactor' 원칙을 따릅니다.
- 테스트 케이스를 먼저 작성하고, 그에 맞춰 코드를 구현합니다.
- 리팩토링을 통해 코드를 개선합니다.
- 단위 테스트와 통합 테스트의 차이
- Minitest 또는 RSpec 사용법
- CI/CD 도구와 TDD의 통합
4. 실전 활용 예제
예제 1: 쇼핑몰 장바구니 기능
쇼핑몰에서 장바구니에 상품을 추가하는 기능을 TDD로 구현할 수 있습니다.
# 실패하는 테스트
def test_add_item
cart = ShoppingCart.new
cart.add_item("사과", 2)
raise "테스트 실패: #{cart.items}는 ['사과', 2]가 아닙니다." unless cart.items == [["사과", 2]]
end
# 최소한의 코드
class ShoppingCart
attr_reader :items
def initialize
@items = []
end
def add_item(name, quantity)
@items << [name, quantity]
end
end
# 테스트 실행
test_add_item
예제 2: 사용자 인증
사용자 인증 기능을 위한 테스트를 작성할 수 있습니다.
# 실패하는 테스트
def test_authenticate_user
user = User.new("[email protected]", "password")
raise "테스트 실패: #{user.authenticate("wrong_password")}는 false가 아닙니다." unless user.authenticate("wrong_password") false
end
# 최소한의 코드
class User
attr_reader :email, :password
def initialize(email, password)
@email = email
@password = password
end
def authenticate(input_password)
input_password @password
end
end
# 테스트 실행
test_authenticate_user
5. 흔한 실수와 주의사항
실수 1: 테스트를 먼저 작성하지 않기
실수 2: 리팩토링하지 않기
6. 정리
다음에 학습하면 좋은 주제
TDD를 통해 더 나은 개발자로 성장하기 위한 체계적인 접근을 시작해보세요!