Test-Driven Development : By Example
지난 10월, TDD에 대한 관심을 갖게 되며 몇 가지 토이 프로젝트를 TDD로 구현했다.
머리속에 드는 생각을 도식화 하고, 정리가 끝나면 그 순서대로 개발을 하는 것에 익숙했던 나에게 테스트 코드 작성은
‘이게 맞는건가?’, ‘이런것 까지 해야할 필요가 있을까?’ 싶은 것이었다.
아직도 손에 익지 않아서 나의 경우는
- 어떠한 기능을 구현할 것인지 생각한다.
- 대충 pseudo로 구현을 한다.
- 작동하는 테스트코드를 작성한다.
- 리펙토링을 하며 수정한다.
와 같은 순서로 기능을 구현했다.
정통적인 TDD의 방식은 아니었지만, 테스트코드에 익숙해 지기 위해 나름 정한 최소한의 룰이었다.
한 가지 계속 생각하며 손에 익을 때 까지 연습했던 것은 가능한 한 모든 메소드를 테스트 코드로 작성
하는 것이었다.
( 물론 이것도 메소드 분리, 자잘한 수정이 모여서 큰 수정이 된 경우에는 빠뜨리는 것들이 항상 생긴다. )
그렇게 하다보니 구조적인 변경이 생겨서 수정을 하게 되어도 테스트 코드 실행 -> 성공의 결과를 계속 확인하면서 수정을 하다보니 예전에 작성하면서 흔히 드는 ‘대체 어디서부터 잘못된거지?’하면서 revert를 누르던 습관이 줄어들었다. ( intelliJ의 좋은 점 중 하나는 local history 확인 시 테스트 성공여부까지 나온다는 것 )
자연스럽게 조금 더 TDD에 대해 공부해 보고 싶어졌고, 추천도서였던 이 책을 골라서 읽었다. 1장은 JUnit을 사용하여 TDD로 간단한 어플리캐이션을 구현하는 것이엇는데, 이부분은 술술 읽혔다. 2장은 python을 이용하여 XUnit을 생성하는 것이었는데, 1장처럼 기능 구현이라기 보다는 테스트기능 자체를 구현하는 것이었다.
처음에는 기능구현인 줄 알고 XUnit이 뭔지도 모르는데 어떻게 하라는건가 당황했는데 그냥 한 번 책을 읽어보니 테스트 기능을 만드는 것임을 알 수 있었다.
3장은 TDD를 구현하는데 참고할 만한 사항에 대해 정리해 놓았다. 생각보다 내가 하고 있던 방향과 일치하는 것이 많아 공감을 하며 읽었다.
1. Junit
github 바로가기
1부는 JUnit을 사용하여 TDD로 기능을 구현하는 방법에 대한 이야기를 한다.
jupiter를 사용하여 테스트 코드를 구현했다.
// build.gradle
dependencies {
testCompile('org.junit.jupiter:junit-jupiter:5.4.2')
testCompile('org.assertj:assertj-core:3.11.1')
}
- TDD 구현 방법
- 작은 테스트를 하나 추가한다
- 모든 테스트를 실행해서 테스트가 실패하는 것을 확인한다
- 조금 수정한다
- 모든 테스트를 실행해서 테스트가 성공하는 것을 확인한다.
- 중복을 제거하기 위해 리팩토링한다
중복을 제거
한다는 것이 내가 생각하는 이책에서 말하는 TDD의 핵심 구현 방식이다.
테스트 코드를 통과시키기 위해 stub구현(메서드의 서명부와 반환 명령만 적는 식으로 해서
이 메서드를 호출하는 코드가 컴파일 될 수 있도록 껍데기만 만들어 두는 것)을 하고,
당연한 반환값 혹은 로직에 ‘하드코딩’을 한다.
하드코딩의 단계를 거치다 보면 input값과 output값, 혹은 연산을 하는 중 중복된 값을 찾을 수 있는데, 이것이 우리가 변수 혹은 인자로 분리할 수 있는 값이다.
2. XUnit
github 바로가기
2부는 XUnit의 기능을 수현하는 방법에 대한 이야기를 한다.
3. 방법론
1장에서 언급한 divide and conqire
와 2장에서 언급한 rinse and repeat
는 3장의 기본적인 개념이 된다.
나는 pair-programing에 대해 직접적인 경험이 없지만, 가끔 동료들과 어떤 이야기를 하다가
이게뭐지? 하면서 다시 처음부터 코드 작성을 하면 훨씬 이해하기 쉬운 코드가 작성되는 경험을 한 적이 있다.
3장에서는 TDD를 도입하기 위한 마음가짐과 방법론에 대한 이야기가 나와있는데
- 모르겠으면 지우고 다시 시작하기
- 개인작업의 경우 테스트가 실패한 상태로 하루를 마치기
- 팀작업의 경우 테스트가 모두 성공한 상태로 하루를 마치기
- 리팩토링단계에서는 어떻게 해야하는지
- 학습테스트를 통해 개념학습과 TDD학습을 동시에 하는것
등 에 대한 설명이 적혀져 있다.