오늘 intellij communitiy 버전에서 professional 버전으로 옮겼다. 이제부터 TDD를 도입하여 코드를 구현할 거라고 하셨고 TDD개발에 대해서 알아보는 시간도 가졌다.
TTD(Test-Driven Development)는 테스트 주도 개발을 뜻한다.
보통의 소프트웨어 개발 생명 주기 단계는 분석-설계-구현-테스트-유지보수의 단계로 이루어져 있다. 이 개발 방식의 단점은 코드를 전체 구현한 후 테스트를 수행하여 디버깅 시간이 오래걸리고, 기능의 추가가 어렵다는 것이다.
하지만 TDD를 도입하게 되면, 개발 주기를 짧게하고 지속적으로 테스트한다. 이를 통해 재설계의 필요성이 줄어들게 되고 보통 개발 방식의 단점을 극복할 수 있다.
TDD개발을 구글링하면서 설명을 읽는데 애자일 개발 모형이 생각났다. 실제로 TDD방법론이 애자일 모형에서 파생되었다는 것도 알게 됐다. 자격증 공부할 때는 그냥 그렇구나만 했다가 TDD방법론을 직접 사용해보고 애자일에서 파생되었다고 하니 더 이해가 잘 된 것 같다. TDD
일반적인 방식과의 차이점은 테스트 코드를 작성한 뒤에 실제 코드를 구현하는 것이다.
1. Red 단계
- 실패하는 테스트 코드를 먼저 작성한다.
2. Green 단계
- 테스트 코드를 성공시키기 위한 실제 코드를 작성한다.
- 완벽한 코드보단 최대한 빠르게 작업하는 것을 1순위로 작업한다.
3. Blue 단계
- 중복 코드의 제거, 일반화 등 코드를 리팩토링한다.
개발 주기를 짧게하여 유닛테스팅을하 고 위 3단계를 계속 반복한다.
3단계를 수행하기 위해 프로그래밍 목적을 미리 정의 하고, 무엇을 테스트 할 지 미리 테스트 케이스를 작성해야만 한다.
좋은 테스트의 규칙 FIRST
Fast: 테스트는 빠르게 동작하여 자주 돌릴 수 있어야 한다.
Independent: 각각의 테스트는 독립적이며 서로 의존해서는 안된다.
Repeatable: 어느 환경에서도 반복 가능해야 한다.
Self-Validating: 테스트 결과를 boolean 값으로 결과를 내어 자체적으로 검증되어야 한다.
Timely: 테스트는 적시에 즉, 테스트하려는 실제 코드를 구현하기 직전에 구현해야 한다.
AssertThat메서드를 활용해 TDD개발을 할 수 있다. 이 메서드는 출력문을 사용하지 않고 테스트 케이스를 검사할 수 있도록 도와준다.
AssertJ를 정적(static) import하면 클래스 이름없이 바로 사용할 수 있다.
import static org.assertj.core.api.Assertions.assertThat;
패키지.클래스.* 형식으로 클래스의 모든 정적 멤버에 접근할 수 있지만 이는 권장되지 않는다고 한다. (공식가이드 : 정적 멤버가 어느 클래스에서 왔는지 알 수 없습니다. 클래스에서 모든 정적 멤버를 가져오는 것은 특히 가독성에 해로울 수 있습니다. 하나 또는 두 개의 멤버만 필요한 경우 개별적으로 가져오세요.)
AssertJ의 메서드는 사용자가 테스트 중 필요하다고 생각하는 거의 모든 메서드를 갖고 있다.
assertEquals(기대값, 실제값): 실제값(actual)이 기대값(expected)과 내용이 같은지 검증한다.assertThat(실제값).isEqualTo(기대값): 실제값(actual)이 기대값(expected)과 내용이 같은지 검증한다. TDD개발론을 적용해서 다항식 문자열을 입력 받아 연산하여 결과를 반환하는 클래스를 구현했다.
아래는 내가 오늘 AssertThat메서드를 활용하여 TDD개발 방법론을 적용한 순서다.
1. `3 * 1 + (1 - (4 * 1 - (1 - 1)))`를 계산할 수 있는 계산기 만들기를 목표로 설정
2. `1 + 1`을 입력하면 `2`를 출력하도록 테스트 케이스 작성하고 코드 구현
3. `2 + 1`입력 -> `3` 출력하고 이전 테스트 케이스에 영향이 없도록 코드 수정
4. `50 - 30`입력 -> `20` 출력 '''
5. `10 - 20 + 30`입력 -> `20` 출력 '''
6. 중복 코드 제거
7. `10 - 10 - 10 - 10 + 10 + 10 - 10` 입력 -> `-10` 출력 '''
8. `10 * 10 * 10 ` 입력 -> `1000` 출력 '''
⋮
이런식으로 목표를 조금씩 키우는 테스트 케이스 18개를 만들고 나서야 목표한 3 * 1 + (1 - (4 * 1 - (1 - 1))) 문자열을 연산할 수 있었다.
실제로 적용해보니 어려움이 살짝 있었다. 새로운 테스트 케이스만 통과하면 되는데 그 이상을 자꾸 생각하게 되었다. 이런 문제 때문에 실제로 적용하기 어렵다고 한 건가 싶었다. 지금도 바로 적용을 못했는데 나중에 일반적인 개발 주기가 익숙해진다면 더 어려워질 것이다. 꾸준히 연습해서 TDD개발을 진짜 빠르게 할 수 있는 사람이 되고 싶다.
참고 자료