The RED : 이규원의 현실 세상의 TDD - 테스트 주도 개발의 깊은 곳 === ###### tags: `석기` --- ## 인터페이스와 구현 #### 추상화 - 목적에 따라서, 대상이 가지고 있는 것들중에 일부만 투영하는 것. #### 인터페이스 - '무엇'을 표현 - 클라이언트에게 반드시 필요한 정보 - 협력하는 코드 사이의 계약 - 추상화 결과 #### 정보 숨김 - 효과적인 모듈화 - 조직간 의사소통 최소화 - 변경여파 최소화 - 시스템 이해 도움 --- ## 환경 변화와 적응력 #### 모듈화 - 모듈화가 잘 된 코는 환경변화에 덜 민감하다. #### 개체 지향 **OOP 는 late-binding이 특징이다.** ##### ==다형성== #### 개방 - 폐쇄 원칙 - 확장 가능한 경우 모듈은 열려있다고 한다. - 다른 모듈에 의해 사용될 수 있을때, 모듈을 닫혀있다고 한다. ==실습== 실습 중 놀라운 코드 발견... ```javascript= function plus(n) { return n + 1 } function twice(n){ return n * 2 } function triple(n) { return n * 3 } function combineFuncs(functions) { return (src) => functions.reduce((value, fc) => fc(value), src) } const calcuate = combineFuncs([plus, twice, triple]) calcuate(10) // 66 ``` - 위의 `combineFuncs` 함수에 인자를 추가하며 필요한 기능을 덧붙여서 리팩토링 할 수 있다. --- ## 입력과 출력 #### 직접 입력, 직접 출력 - 공개된 인터페이스를 통한 입력과 출력 - 다루기 간단. #### 간접 입력, 간접 출력 - 입력된 인터페이스를 통한 입력과 출력 - 다루기 힘듬. ### 부작용 - 인터페이스 설계에 드러나지 않은 출력 - 실패 - 지연 - 간접출력 --- ## 테스트 대역 ### 대역과 가정 - DOC 준비 비용이 큰 경우 - 구동에 많은 자원이 필요 - 환경 제어가 어려움 #### Dummy - SUT 준비를 위해 해결되어야하는 의존성이 테스트 대상 논리에 의해 사용되지 않는 경우에 의존요소를 대신하는 테스트 대역 #### Stub - 간접 입력 대역 - 미리 준비된 답을 출력 #### Spy - 간접 출력 대역 - SUT의 간접 출력 기록 --- ## Mockists vs Classicsts #### Socialble 테스트 - 의존 대상까지 테스트 #### Solitary 테스트 - 의존대상을 격리시켜서 테스트 대역을 테스팅하는 기법. #### 테스트 대역 - 가정의 안정도 **가정을 얼마나 믿을 수 있을까?** - 테스트 대역이 구현하는 인터페이스가 단순할수록 안정적. - 데스트 대역이 구현하는 인터페이스가 복잡할수록 불안정적이다. #### Mock 의 위험 - 정보 숨김 위배 - 테스트가 SUT 구현에 의존하게 됨. - refactoring 불안 / 고통스럽다. --- ## Should I test private methods #### Private 메소드를 테스트를 해야하는가? :::warning NO ::: #### 비공개 모듈 테스트 - 비공개 모듈의 작성과 사용은 공개 모듈의 구현 영역. - 비공개 모듈 테스트는 공개 모듈 구현 노출. --- ## 테스트 주도 설계 #### 설계가 단위 테스트에 미치는 영향 - 테스트는 인터페이스 설계에 의존 - 인터페이스 설계 품질이 낮으면 테스트 작성이 불편 #### 단위 테스트가 설계에 미치는 영향 - 테스트가 있기 때문에 리팩토링 가능 - 구현설계를 과감하게 개선이 두려움이 없음. #### 단위 테스트에 의지하는 인터페이스 설계 **단위 테스트는** - 일관된 설계를 강요하지 않는다. - 낮은 응집에 대한 피드백을 주지 않는다. - 의도 노출을 요구하지 않는다. #### 단위 테스트에 의지하는 구현 설계 - 단위 테스트는 책임 분산을 유도하지 않음. - Mock을 과도하게 사용할 수 있다. - 코드의 양이 작아지기도 하고 - 구현을 생각하며 테스트 코드를 짜게 된다. - 비공개 운영 코드 테스트 - private method, internal class가 공개되어버린다. --- ## TDD의 한계 ### 은탄환은 없다. - 도구의 법칙 - 유용하고 매력적인 도구지만 / 남용을 주의하여야한다. ### 불안정한 목표 - 모든 코드의 목표가 안정적이지는 않음 - 테스트 코드 작성 비용 부담이 클 수 있음. --- ## 인터페이스와 테스트 #### 인터페이스 - 한 개체가 상호작용하는 다른 개체에 제공하는 상호작용 지점 - 약속된 계약에 의해 서비스를 제공받을때의 말임. #### API - 코드 친화적 소통수단 - 테스트 자동화 비용이 낮음 - 한 시스템이 협력 시스템에 제공. - 테스트 코드도 이를 사용하여 테스트 진행. - 기계를 위한것이므로 테스트(사람)은 어려움 #### UI - 한 시스템이 시스템 사용자에게 제공. - 인간 친화적 소통 수단. - 변경이 잦음. - 테스트 자동화 비용이 높음. --- ## 인수 테스트 주도 개발 ### 인수 테스트 - 배치된 코드를 대상으로 최종 클라이언트 관점으로 테스트 - UI 응용 프로그램 - 사용자가 클라이언트 - 테스트 자동화 작성 / 운영 비용이 상대적으로 높음 - API 응용 프로그램 - 외부 시스템이 클라이언트 ![image](https://user-images.githubusercontent.com/52649378/163497011-ab8cf1a4-f383-4618-b929-1bfe2f5a52d1.png) --- ## 코딩 계획 #### 코딩 작업 설계 - 목표를 정확히 기술 - 어떤 가치를 구현? - 명확한 이정표가 없다면 쉽게 길을 잃는다. - 사용자 스토리 / 테스트 케이스는 목표 기술의 좋은 수단. - 작업 분히 - 전체작업을 하위 작업으로 작게 분리 - 하위 작업 역시 목표를 명확히 분리 #### 업무 가시성 - 투명한 작업자의 업무 내용과 진행도 / 위험요소를 더 빨리 발견할 가능성이 높으짐.