이 포스트는 TDD가 어떤 것인지 소개하기 위해 작성되었습니다.
사용된 이미지는 NextStep의 Git에서 가져왔습니다.
TDD는 Test Driven Development의 약자로 테스트 주도 개발을 의미.
매우 짧은 개발 사이클을 반복하는 소프트웨어 개발 프로세스 중 하나.
보통 코드를 먼저 작성하고 단위테스트를 진행하는 방식이 일반적,
하지만 TDD는 테스트를 먼저 작성하고 코드를 작성하게 됩니다.
- 실패하는 단위 테스트를 작성할 때까지 구현 코드(production code)를 작성하지 않는다.
- 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.
- 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.
- 실패하는 테스트가 통과한 후 리팩터링을 진행한다.
우선 TDD를 진행 하기전에 요구사항을 정리한다.
위와 같이 프로그램을 개발 하기위한 요구사항들이 있을 것이다
TDD를 진행 하기위해 자신이 생각 할 수있는 최소 단위로 쪼개고 정리해보자 (보통README.MD
에 정리한다.)
첫번째 기능 요구사항에서 한번 최소단위 요구사항들을 도출 하자.
1. 문자열에서 사칙연산 기호를 추출 할 수있다.
1-1. 문자열에서 정수를 추출 할 수있다.
2. 추출 된 각각의 사칙연산 기호마다 다른 계산 결과가 반환된다.
3. 덧셈과 뻴셈 곱셈 나눗셈을 할 수 있다.
3-1. 덧셈 연산은 정수 1, 정수 2가 파라미터로 넘어오면 3을 반환한다.
3-2. 뺼셈 연산은...
.....이하 생략개발자 마다 각기 다른 요구사항들이 도출 되겠지만 큰 상관은 없다.
이제 위 최소단위 요구사항중 제일 만만한 요구사항부터 TDD를 시작하면 된다.😃
3-1번이 제일 쉬워 보이므로 3-1번을 한번 코딩해 보자
❖ 요구사항으로 부터 우리가 덧셈기능을 구현해야 한다는 것을 알게 되었다 ❖
이제 TDD원칙을 적용 하면 된다.
❗️ 실패하는 테스트를 작성할 때까지 구현코드를 작성하지 않는다.
간단한 덧셈기능을하는 코드를 만들어 보자.
❗️ 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.
컴파일은 실패하지 않고 실행만 실패하는 단위 테스트란 아래와 같다.
(현재 Main폴더에는 아무코드도 없고, Test폴더에 ResultTest.class 하나만 존재하는 상황)
@Test
void addTest(){
int firstNumber = 1;
int secondNumber = 2;
Assertion.assertThat(add(firstNumber,secondNumber)).isEqualTo(3);
}
덧셈을 위해 add()
라는 메서드가 필요하다고 생각되어 add()
를 선언했고
원칙 2
컴파일은 실패하지 않으면서 실행이 실패하는 조건을 만족했다.
(add()
메서드가 어디에도 선언 되지 않았다)
❗️ 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.
이제 Main 폴더에 실제코드를 작성하러 가자! (덧셈을 구현한 메서드이다.)
public class Result{
public int add(num1,num2){
return num1 + num2
}
}
위와같이 함수를 구현하면 실패했던 테스트코드를 동작하도록 만들수있다!
@Test
void sumTest(){
int firstNumber = 1;
int secondNumber = 2;
//Result 객체생성
Result result = new Result();
//result애서 add 호출
Assertion.assertThat(result.add(firstNumber, secondNumber)).isEqualTo(3);
}
add가 선언되지 않아 실패했던 테스트 코드가 동작하게 되었다!
❗️실패하는 테스트가 통과한 후 리팩터링을 진행한다.
add()
가 명확하지 않아 보여 plus()
로 변경.Result
클래스명이 마음에 안들어 Calculator
로 변경TDD는 개발자가 프로그램의 전체적인 구조를 이해하는데 도움을 준다.
BOTTOM-UP 방식
을 통해 대략적인 구조를 파악하고 다시 TOP-DOWN
방식으로 TDD를 진행하면 좀더 클린한 코드가 나오게 된다.테스트 주도 개발은 프로그래밍하면서 나타나는 두려움을 관리하는 방법이다.
이 중 어떠한 것도 프로그래밍에 도움이 되지 않는다.
즉 고민할 시간에 코드를 한줄이라도 더 짤수있게 생산성을 높일 수 있다.
나는 코드에 대한 지식과 경험이 없을수록 빛을 발한다고 생각한다.
대학교 2학년때, 과제를 하며 오류발생시 모든코드에 System.out.println("여기 코드가 오류1")를 넣은 기억이있다..