TDD
•
Test Driven Development (테스트 주도 개발)
•
테스트 코드 주도하에 실제 프로덕션 코드를 개발하는 개발 방법론
a. 일반적인 개발 루틴
b. TDD 개발 루틴
1.
실패하는 테스트를 구현한다
2.
테스트가 성공하도록(테스트가 성공하는 최소한의 기능) 프로덕션 코드를 구현한다
a.
아래 단계에서 리팩토링을 거칠 것이기 때문에 코드 퀄리티에 크게 신경
3.
프로덕션 코드와 테스트 코드를 리팩토링 한다
Test Code의 장점
•
변화에 대한 두려움이 줄어든다
◦
= 리팩토링에 대한 두려움이 줄어든다
◦
불안함 Down, 지루함 Up
•
디버깅 시간을 줄여준다
•
동작하는 문서의 역할
◦
훌륭한 협업 도구
◦
의사 결정의 흐름을 쉽게 알 수 있음
•
품질 향상에 도움이 된다
◦
기능별로 분리해야 테스트 코드를 작성하는데 수월함 → 함수를 기능별로 분리 → 클린 코드
TDD의 장점
•
오버 엔지니어링 방지
◦
테스트를 통과하는 정도로만 실제 코드를 작성하기 때문에 오버 엔지니어링을 방지할 수 있음
•
테스트 커버리지가 높아진다
◦
테스트 커버리지: 테스트 코드로 검증되는 영역
•
설계에 대한 피드백이 빨라진다
◦
테스트 코드로 빠르고 객관적인 피드백이 가능함
▪
혼자서 코딩을 하더라도 객관적인 피드백을 받을 수 있음
•
요구사항을 명확하게 이해 가능
◦
테스트 코드를 먼저 작성하고 그에 맞게 최소한의 기능을 설계해야 하기 때문에 요구사항을 명확하게 이해할 수 있음
◦
생각하지 않고 코드부터 쓰는 것을 프로세스 수준에서 막아주는 방법
TDD의 단점
•
기능 구현까지의 시간이 늘어난다 (보통 10~30%)
◦
하지만 후에 유지보수 비용까지 생각한다면...
TDD를 시도해볼만 할 때
•
내/외부적으로 불확실성이 높은 경우
◦
내부적 요소: 처음 해보는 프로젝트, 생소한 기술들
◦
외부적 요소: “이거 변경해주세요” “다른 기능도 추가해주세요”
•
코드를 많이 수정해야 하는 경우
•
나중에 다른 누군가가 개발해야 하는 경우
TDD를 적용한다면 비용적인 면을 잘 고려해볼것
우리가 TDD를 실패하는 이유
Bad Case
Good Case
•
코드가 이루고자 하는 가치나 기능을 테스트 하기보다 그 기능을 어떻게 구현하고 있는지를 테스트한다
◦
그 결과 테스트 케이스들과 구현체와 결합도가 높아짐
◦
구현체를 리팩토링하면 결합되어 있는 테스트 케이스가 모두 깨져버림
•
테스트 코드에 정답은 없다
◦
너무 많고 다양한 규칙에 얽매인다 → 자연스럽게 난이도가 올라감 → TDD 어려워
단위테스트
•
테스트중 가장 작은 단위의 테스트
•
일반적으로 메서드 / 함수 레벨
•
검증이 필요한 코드에 대해 테스트 케이스를 작성하는 절차 또는 프로세스
•
단위 테스트는 테스트 코드가 목적 코드의 완전성을 입증해 주기 때문에, 테스트 코드 그 자체만으로 주요한 가치가 있음
좋은 단위 테스트를 위한 F.I.R.S.T 법칙
•
Fast
◦
빠르게, 테스트는 빨라야 함
▪
테스트가 오래걸린다면 여러번 반복하는것이 힘들어짐 → 테스트를 진행하지 않게 됨
•
Independent
◦
독립적으로, 각 테스트는 서로 의존하면 안 됨, 하나가 실패하면 도미노처럼 실패하게 됨
▪
테스트 코드간의 의존성이 높으면 높을수록 사이드 이펙트가 커질 수 밖에 없음
•
Repeatable
◦
반복 가능하게, 환경에 구애 받지 않고 반복적으로 테스트 가능해야 함
▪
모든 환경, 상황에 의존적이지 않아야 함
•
인터넷 연결이 안되거나, 데이터 베이스에 접근할 수 없는 등의 상황에서도 작동하도록 해야 함
•
Self-validating
◦
자가 검증하는, 테스트 코드 스스로 검증할 수 있게 구현
◦
테스트 결과는 Boolean 값으로 나와야 하고, 그렇지 않다면 직접 대조해가며 테스트를 검증해야 함
•
Timely
◦
적시에, 실제 코드 구현 이전에 테스트 코드 작성
Reference
부족한 내용을 댓글로 남겨주시면 그 부분에 대해 보완해서 추가하도록 하겠습니다! 감사합니다