# 1부. 테스트 주도 개발 기초 ###### tags: `지호`, `이규원의 현실 세상의 TDD : 안정감을 주는 코드 작성 방법` --- ## 1. 코드 기능 명세 ### 코드 기능 명세 - 모든 프로그램 코드는 입력과 출력을 갖고 특정 입력에 대해 기대하는 출력이 있다 - 이런 기대 동작들을 코드의 명세 또는 요구사항이라고 부른다 ### 도메인 - 소프트웨어는 문제를 푸는 도구 - 도메인은 소프트웨어가 풀어야 할 문제가 정의되는 공간 ### 프로그래머와 기능 명세 - 명확한 기능 명세가 있어야 프로그래머가 올바른 동작을 하는 코드를 짤 수 있다 - 충분히 명확한 도메인 지식을 확보하지 못했다면 지식 보가을 요청해야 한다 <br/> ## 2. 테스트 기법 ### 수동 테스트 - 품질 담당자가 UI를 사용해 기능을 검증 - 최종 사용자의 사용 경험과 가장 비슷하게 검증 - 실행 비용이 높고 결과의 변동이 큼 (단점) - 가장 온전한 코드 실행 - 인수 테스트에 사용됨 ### 소프트웨어 회귀 - 원래 동작하던 기능이 어떤 시점 이후로 동작하지 않게 되는 현상 - 새로운 기능이 추가됐을 때, 배포를 했을 때 ### 테스트 자동화 - 기능을 검증하는 코드를 작성 - 테스트 코드 작성 비용이 소비되지만, 실행 비용이 낮고 결과의 신뢰도가 높음 - 테스트 코드 작성과 관리가 프로그래머 역량에 크게 영향을 받음 ### 인수 테스트 - 배치가 완료된 시스템을 대상으로 검증 - 전체 시스템 이상 여부 신뢰도가 높음 - 높은 비용: 작성 비용, 관리 비용, 실행 비용 - 피드백 품질이 낮음: 문제의 원인이 무엇인지 알기 힘듦 ### 단위 테스트 - 시스템의 일부(하위 시스템)을 대상으로 검증 - 낮은 비용: 작성 비용, 관리 비용, 실행 비용 - 높은 피드백 품질 - 전체 시스템 이상 여부 신뢰도가 낮음 ### 인수 테스트와 단위 테스트 - 인수 테스트는 시스템 외부에 노출된 영역을 대상으로 진행 - 단위 테스트는 시스템 내부에 있는 하위 시스템을 대상으로 진행 <br/> ## 3. 코드 분해 ### 모듈화 - 분해 - 큰 시스템은 더 작은 하위 시스템으로 분해 가능 - 교체 가능 - 조립 - 작은 시스템은 더 큰 상위 시스템으로 조립 가능 - 모듈 재사용 - 라이브러리 <br/> ## 4. 테스트 우선 개발 ### 테스트 코드 - 가시적이고 구체적인 목표 - 자가 검증 가능 - 반복 실행 가능 - 운영 코드 API의 클라이언트가 됨 ### Test Firtst Development - 운영 코드보다 테스트 코드를 먼저 작성 - 테스트 코드를 통과시킬 운영 코드를 작성 - 프로그래머가 명확하고 검증 가능한 목표를 설정한 후 목표를 달성 <br/> ## 5. 정리된 코드 ### 리팩토링 - 리팩토링 전/후에 생길 수 잇는 기능 변화들을 테스트 코드로 검사해야한다. <br/> ## 6. 테스트 주도 개발 ### 테스트 주도 개발 절차 - RED - 운영 코드를 작성하기 전에 테스트 코드를 먼저 작성 - 실패하는 테스트 추가 - GREEN - 운영 코드를 수정해서 새로 작성한 테스트와 기존에 작성한 테스트를 성공 - 최소한의 코딩 - REFACTOR - 테스트 통과된 결과를 유지하면서 코드를 리팩토링 - 구현 설계 개선 ### 테스트 실패 - 구체적인 하나의 요구사항을 검증하는 하나의 테스트 추가 - 추가된 테스트가 실패하는지 확인 - 실패하는 것을 확인해야 테스트가 동작함을 믿을 수 있다. - 운영 코드 변경이 진행되지 않았기 때문에 실패했는지 확인해야 한다. ### 테스트 성공 - 추가된 테스트를 비롯해 모든 테스트가 성공하도록 운영 코드를 변경 - 테스트 성공은 요구사항 만족을 의미 - 테스트 성공을 위한 최소한의 변경 ### 리팩토링 - 코드 베이스 정리 - 구현 설계 개선: 가독성, 적응성, 성능 - 모든 테스트 성공을 전제 ### 켄트 벡의 설계 규칙 - 테스트 통과 - 의도 노출 - 중복 제거 - 테스트 통과되는 코드만 유지 ### 테스트 주도 개발 비용 - 처음엔 높은 비용으로 시작하지만, 시간이 지나도 비용이 일정 수준으로 유지 - TDD를 사용하지 않으면 처음엔 비용이 낮지만, 어느 순간은 계속 비용이 늘어남 <br/> ## 7. 기대 출력 피드백 ### 기대 출력 피드백 - 사용자 피드백: 사용자가 직접 코드를 사용한 후 경험한 버그나 불만을 제보 - Quality Assurance: 전문 인적 자원에 의한 인수 테스트 - 프로그래머 테스트: 프로그래머가 직접 피드백 장치를 준비 - 도구 피드백: 컴파일 오류, 정적 검사 등 프로그래머가 사용하는 도구가 제공하는 피드백 ### 오버 엔지니어링 - 더 중요한 목적, 기능 요구사항에 써야 할 자원을 불필요하게 낭비하게 됨 - 테스트 주도 개발은 가장 중요한 목표를 우선 달성하도록 유도하며 피드백을 제공 (모든 테스트가 성공) ### 피드백 - 테스트 주도 개발의 핵심은 정해진 절차가 아니라 짧은 주기로 지속되는 피드백 - 피드백에 기반해 안정적으로 지식과 코드를 늘려나가는 것이 목적