TDD(Test Driven Development)의 정의와 효과
Goal
- TDD의 정의 - ‘결정과 피드백 사이의 갭을 인식하는 것’을 이해할 수 있다.
- TDD의 효과 - TDD는 언제, 어떻게 사용하면 좋을까
- TDD를 활용하기 어려운 이유와 잘 하는 방법
- 프로그래머 외의 사람들에게는 TDD는 어떤 의미가 있을까
[들어가기 전]
- TDD가 프로그래머에게만 해당한다고 생각하면 애자일의 근본 개념을 망치는 것이다.
- 모든 직무에서 TDD를 적용할 수 있다.
- 또한 TDD의 ‘진짜’개념을 적용하기 위해서는 많은 시간이 걸릴 것이다.
- 우선 아래의 내용을 통해 TDD에 대한 통찰을 얻어보자.
TDD란
TDD의 정의
- Test Driven Development
- 테스트 주도 개발: 테스트가 개발을 이끌어 나간다.
구체적인 행동 레벨에서의 TDD의 개념
테스트를 먼저 만들고 테스트를 통과하기 위한 것을 짜는 것 즉, 만드는 과정에서 우선 테스트를 작성하고 그걸 통과하는 코드를 만들고를 반복하면서 제대로 동작하는지에 대한 피드백을 적극적으로 받는 것이다.
- 보통은 SW 개발을 할 때 코딩을 다 끝나고 난 후 테스트를 한다.
- 코딩이 끝난 후? 개발자가 코딩을 다 짜고 난 후 완성했다고 생각할 때
- 이것의 순서를 바꾸는 것이 TDD를 적용하는 것이다.
- TDD를 적용한 사례
- 예를 들어, 생년월일(input)을 입력받으면 현재 나이(output)를 출력하는 프로그램
- 처음에는 간단한 것으로 목표를 정한다. (태어난 해와 올해의 연도를 입력)
- 2015, 2018 -> (만)3살 우선 이것을 만들겠다는 생각을 한다.
- 만들기도 전에 만든 후에 무엇을 테스트할지를 설계한다.
- 2015, 2018를 입력하면 2가 나오는 테스트 프로그램(장차 만들 프로그램을 테스트할 코드)를 만든다.
- 그 다음에 그 테스트를 통과할 프로그램(1.을 목표로 작성한 코드)를 만든다.
- 올해의 연도 - 태어난 해
- 2018 - 2015
- 테스트 프로그램으로 이 프로그램(3.에 해당하는 코드)을 실행한다.
- 통과했으면 새로운 테스트를 추가한다.
- 이번에는 생월을 추가했을 때 계산하는 프로그램
- 위와 같은 작업을 계속 왔다갔다 수행한다.
추상적인 레벨에서의 TDD의 핵심 개념(중요)
결정과 피드백 사이의 갭에 대한 인식, 더 나아가 결정과 피드백 사이의 갭을 조절하기 위한 테크닉이라고도 할 수 있다.
- 켄트 벡(Kent Beck, 익스트림 프로그래밍의 창시자)
- TDD란?
- 결정과 피드백 사이의 갭에 대한 인식
- 결정과 피드백 사이의 갭을 조절하기 위한 테크닉
- TDD는 프로그래밍 기법이나 기술적인 느낌보다는 심리적인 것으로 볼 수 있다.
- TDD란?
- 결정(decision)?
- 프로그램을 하다보면 ‘이 방법으로 해야지’, ‘이 부분은 이걸 이용해서 짜야지’라는 것을 결정한다.
- 피드백(feedback)?
- 프로그램을 하다보면 성공/실패(에러)라는 피드백을 받는다.
- 이 둘(결정과 피드백) 사이에 갭이 생긴다.
- 갭이 커질수록 문제!
- 내가 그 갭을 모르면 더 큰 문제!
- 즉, 위의 예와 함께 설명하자면
- 결정: 1.을 목표로 코드를 작성할 때, ‘나는 빼기로 나이를 구해야겠다.’라는 것을 결정한다.
- 피드백: 빼기로 계산했을 때의 코드를 테스트 프로그램을 실행한 결과로, 된다/안된다라는 프로그램 상의 피드백을 받는다.
- 이 둘 사이의 갭을 내가 인식한다면 TDD를 하고 있는 것이다.
TDD의 효과
TDD를 왜 해야할까
애자일이란에서 설명한 것과 같이 불확실성이 높을 때 ‘피드백’과 ‘협력’이 중요하다.
- 피드백과 협력이 중요한 이유
- 불확실성이 높을 때 ‘피드백’과 ‘협력’을 이용하면 더 좋은 결과가 나올 확률이 높아진다.
- TDD도 마찬가지로 ‘피드백’과 ‘협력’을 증진시키는 것이기 때문에 불확실성이 높을 때 도움이 되는 것이다.
TDD는 어떤 상황에서 해야할까
- 만약 어떤 부분에 대한 코딩을 여러번 해봤고 결과가 어떻게 나올지 뻔하다면 TDD를 하지 않아도 된다.
- 또한 TDD를 했을 때 얻는 것이 적다면 TDD를 하지 않아도 된다.
-
그렇다면 TDD는 어떤 상황에서 해야할까?
- 처음해보는 프로그램 주제
- 나에 대한 불확실성이 높은 경우
- 고객의 요구조건이 바뀔 수 있는 프로젝트
- 외부적인 불확실성이 높은 경우
- 개발하는 중에 코드를 많이 바꿔야 된다고 생각하는 경우
- 내가 개발하고 나서 이 코드를 누가 유지보수할지 모르는 경우
- 처음해보는 프로그램 주제
- 즉, 불확실성이 높을 때 TDD를 하면 된다.
TDD의 효과
모든 애자일의 실천법은 피드백과 협력을 동시에 증진시킨다.
1. 피드백
- TDD를 하면 피드백이 증가한다.
- 테스트를 통과하는 것으로 잘되고 있는가를 자주 확인할 수 있다.
- 이 부분은 사람들이 쉽게 느낄 수 있다.
2. 협력(이 부분이 핵심!)
- 켄트 벡(Kent Beck)
- ‘test’는 일반적으로 동사로 사용한다. ‘테스트한다.’, ‘테스트해라.’
- 예를 들어, 누가 나한테 생년월일(input)을 입력받으면 현재 나이(output)를 출력하는 프로그램을 주고 test해보라고 한다면 내가 할 수 있는 것은 숫자를 여러 개 찍어보는 것이다.
- 태어난 시간과 지금 시간이 같으면 0
- 태어난 시간이 더 미래의 시간이면 ‘출생 전’
- 등등
- 그러나 TDD를 하면 ‘test’는 명사가 된다.
- ‘test’가 명사가 되면?
- 동사는 그 순간에만 하는 것이고, 명사(대상, 목적어)는 이후에도 소유할 수가 있다.
- 즉, record로 남을 수 있다.
- ‘test’가 저장된다는 것은 남들에게 남들에게 테스트 코드를 보여줄 수 있고, 남들은 그 코드를 직접 실행해볼 수 있다는 것이다.
- 그렇다면 TDD는 왜 협력을 증진시키는가?
- ‘test’가 명사(대상, 목적어)가 되는 순간 이것을 공유하기가 쉬워진다.
- 공유하면 협력이 증진된다.
- 남이 짠 코드를 빨리 이해할 수 있다.
- 남이 짠 코드를 쉽게 이해할 수 있다.
- 용기가 생긴다.(내가 남의 코드를 고쳐서 문제가 있더라도 자동화된 테스트가 알려주기 때문에 큰 걱정없이 고칠 수 있는 용기가 생긴다.)
- 내가 이 코드를 고쳤을 때 이것을 망치면 어떡하지..
- 내가 그 사람의 의도를 모르는데 이것을 고쳐도 될까..
- 즉, 왜 이렇게 짰을까 궁금할 때 ‘test’를 공유하고 그 테스트 코드를 보면 이해할 수 있다.
-
테스트 코드에는 개발자의 개발 과정(어떤 고민/어떤 의사결정)이 나와있기 때문이다.
-
앞의 TDD의 정의(결정(decision)과 피드백(feedback) 사이의 갭을 인식하는 것)와 같이 테스트 코드(feedback)를 보면 그 사람의 의사결정(decision)이 나타나고 상대방은 그 부분은 왜 그렇게 짰는지를 쉽고 빨리 알게 되기 때문에 협력이 증진된다.
TDD의 장단점
그렇다면 TDD는 왜 좋을까
피드백과 협력을 증진시키기 때문에 불확실성에 대해 대비를 하게 해준다.
- 개발속도가 느려진다고 생각하는 사람이 많기 때문에 사람들은 TDD에 대해 반신반의 한다.
- 처음부터 2개의 코드를 짜야한다.
- 중간중간 테스트를 하면서 고쳐나가야한다.
TDD의 장단점
- 연구 논문 결론 취합
- TDD를 하면 개발 시간이 늘어난다.
- 개발 시간의 정의?
- 본인이 ‘다했다고’생각할 때까지, 기능 구현이 끝났을 때까지
- 개발 시간이 TDD를 하지않을 때에 비해 대략 10~30%가 늘어난다.
- 개발 시간의 정의?
- TDD를 하면 결함이 줄어든다.
- 결함이 1/2~1/10 까지 줄어든다.
- SW를 개발하면서 예상하지 못했던 시간을 많이 소요하는 것은 대부분이 버그 때문이다.
- TDD를 하면 이런 버그를 줄일 수 있다.
- TDD를 하면 코드 복잡도가 떨어진다.
- 엔트로피(Entropie)가 낮아진다.
- 깨끗한 코드 가 나온다.
- 유지보수 비용이 낮아진다.
- cf. 복잡도에 대한 재미있는 연구
- 복잡도에 대해 수치로 계산할 수 있다.
- 들여쓰기(Indent)가 많은 코드는 복잡한 코드이다.
- 복잡성 지표(Cyclomatic Complexity)를 통해 들여쓰기에 따라 복잡도를 숫자로 계산한다.
- 계산한 복잡도가 일정 수치 이상이 넘어가면 버그를 고칠 때 나도 모르게 버그를 삽입할 확률이 1에 수렴한다.
- 즉, 내가 버그 하나를 고치려고 그 코드를 고쳤는데 나도 모르게 새로운 버그를 넣는 확률이 1에 수렴한다는 것이다.
-
복잡도가 높으면 버그 숫자가 줄지 않는다.
TDD를 활용하기 어려운 이유와 잘 하는 방법
왜 다들 TDD를 활용하지 못할까? TDD를 하기 여려운 이유는 무엇일까?
- 개발 시간이 증가한다.
- 많은 기업들이 단기적인 성과에 집중해 있다.
- 전체 개발 시간을 줄이는 것보다 오늘 일을 끝내는 것을 강조하기 때문에 TDD 도입이 어렵다.
- 단기적인 것에 집중되어 있으니.. 그때까서 또 고치면 되니까.. 고객이 화내면 안되니까.. 급한 불을 끄면서 허덕이면서 살기 때문에..
- TDD가 어렵다.
- 왜?
- 이제까지 자신이 개발하던 방식을 많이 바꿔야 하기 때문에
- 몸에 체득한 것이 많을수록 바꾸기가 어렵다.
- 언러닝(Unlearning): 이미 배운것을 까먹는 과정
- TDD는 오히려 개발을 별로 안해본 사람에겐 적용하기가 쉽다.
- 왜?
- TDD는 이렇게 해야된다는 이미지/틀이 있다.(핵심)
- ‘반드시 툴(단위 테스트 프레임워크)을 써서 이렇게 해야된다.’라고 생각한다.
- 하지만 이런 규칙에 얽매이는 것은 애자일이 아니다.
- 결국엔 규칙에 얽매여 똑같은 테스트를 copy&paste 한다.
- 너무 도구/규칙에 집착하니까 TDD가 어려워지는 것이다.
TDD를 잘하는 방법?
적응적, 진화적으로 접근해야 한다.
- 나 스스로 ‘어떻게 해야 피드백을 더 자주 받을까’, ‘어떻게 해야 내가 하는 작업에 대해 협력이 잘 일어나게 할까’를 고민하면서 계속해서 내가 일하는 방식을 업그레이드 해야한다.
- 예를 들어, 게임을 개발하면서 stage 3을 테스트할 때
- 항상 stage 1, stage 2를 클리어한 후 테스트를 해야 한다.
- 테스트 비용이 증가한다.
- 어떻게 하면 테스트 비용을 낮출수 있을까를 고민한다.
- 바로 stage 3으로 갈 수 있도록 만든다.
- 피드백을 값싸게 더 자주 받을 수 있다.
- 백도어 접근법: 테스트할 때 어떤 파라미터를 적용하면 내가 원하는 시스템의 시작점으로 가게 하는 것
- 항상 stage 1, stage 2를 클리어한 후 테스트를 해야 한다.
- 중복적으로 하는 노력들을 조금 더 자동화하도록 업그레이드하면 발전할 수 있다.
프로그래머 외의 사람들에게 TDD는 어떤 의미가 있을까
프로그래머가 아닌 일반인은 TDD를 어떻게 사용할 수 있을까
- 마찬가지로 본인이 일을 하면서 내가 하는 일에 대해 나 스스로/다른 사람에게 피드백을 얼마나 자주 받는가를 고민해야 한다.
- 예를 들어, TDD를 이용하여 ppt(세미나용 발표자료)를 만든다고 하자.
- ppt가 충족해야 하는 조건을 정한다. 즉, 핵심 메시지를 정한다.
- 궁극적으로 발표를 통해서 말하고 싶은 것을 한 단어, 한 문장으로 정한다.
- “사용자의 피드백”이 중요하다고 정했다.
- test1. 단순히 ‘이것이 나한테 중요했다.’가 아닌 ‘어떤 의미에서 중요했는가’가 나타나야 한다.
- ppt 한 장 이내로 어떤 의미에서 “사용자의 피드백” 중요했는가를 나타나게 한다.
- 또한 ‘추가적으로 어떤 것을 해볼 수 있을까’를 생각한다.
- 실제 test. 만든 것을 실제 발표 상황을 상상하면서 읽어본다. (핵심)
- 청중 입장에서 어떻게 느껴질까를 생각해본다.
- 이것이 바로 결정-피드백 사이의 갭의 인식(TDD)을 하는 작업이다.
- ppt가 충족해야 하는 조건을 정한다. 즉, 핵심 메시지를 정한다.
프로그래머 외의 사람들에게 TDD는 어떤 의미가 있을까
- TDD는 정형적인 방법으로 하는 것이 중요한 것이 아니라 내가 스스로 TDD라고 하는 방식을 계속해서 발전시켜 나가는 것이 중요하다.
- 내가 이것을 왜하는가를 생각해야 한다.
- 피드백과 협력을 증진시키지 않으면서 TDD를 하면 아무 의미가 없다.
- 그냥 혼자서만 TDD해서 하면 피드백은 되겠지만, 협력이 증진이 되지 않는다.
- 즉, 정답이 있는것이 아니라 본인이 어떻게 발전시키느냐가 애자일의 핵심이다.
관련된 Post
- 애자일 방법론이란 무엇인가? 애자일 방법론의 핵심은 무엇인가?에 대해 알고 싶으시면 애자일이란을 참고하시기 바랍니다.
- 애자일 자격증의 종류와 그 효용 가치에 대해 알고 싶으시면 애자일 자격증을 참고하시기 바랍니다.
- 애자일 데일리 스크럼의 개념과 도입 방법에 대해 알고 싶으시면 데일리 스크럼이란을 참고하시기 바랍니다.
- 짝 프로그래밍(Pair Programming)의 개념과 효과에 대해 알고 싶으시면 짝 프로그래밍(Pair Programming)이란을 참고하시기 바랍니다.