테스트
- 어떤 시스템이 제대로 동작하는지 검증하는 과정
- 인수테스트(체크리스트를 받아서 테스트) / 자동테스트(내가하는것)
- 개발자가 저지르는 대표적인 실수
- 인터페이스를 생각하지않고 구현체를 먼저만든다
- red단계에서 컴파일 코드만들고 테스트 실패확인 -> 그래서 개발자는 구현체 보다 인터페이스 작성하는걸 집중 한다.
- 어떤 책임을지고 어디까지 해결해야하는지
- 인터페이스에 집중한다? 객체지향의 핵심원리중 하나인 행동에 집중하는 말과 같다.
- 다시 말하면 TDD가 책임 주도 설계 핵심 과정인
- What/who 사이클을 고민하게 도와준다.
- 어떤 행위를 누가 수행할지 결정하는 과정
- 이 차트는 좋은 설계 나쁜 설계 에도 적용되
- 테스트와 아키텍처는 비례함
테스트 고민
무의미한 테스트
- 이리 명확한 코드에 테스트 코드가 의미가 있을까?
- Jpa구현체가 알아서 잘했을 텐데.
- 분명히 의미는 있지만 커버리지가 목적인 테스트가 된다.
- 행동에 집중한다는 의미에서 행동이 메서드나 함수를 의미하는게아님
- 모든 메서드 테스트 보다 중요한 로직 구분해서 테스트를 해야함.
느리고 쉽게 깨지는 테스트
- 방금 위테스트가 200개가되면? 1분이 걸림 적지않는 부담 시간
- 현업은 200개 테스트 쉽게 넘어감
테스트가 불가한 코드
- 이걸 어떻게함
- mock을 사용하면 설계를 발전시킬수 없다.
-> 이런 고민을 하는테스트가 개선해야하는 신호다 ! 강제로 테스트하지말고
테스트 필요성 및 3 분류
- 정확한 기준?
- 오래된거?
- 테스트 루틴이 없는 코드
좋은 아키텍쳐 좋은 설계
- 둘은 긴밀한 상호보완적 관계
- 솔리드 원칙이 지켜지면 경계가 만들어지고 회귀버그 방지
- 서로에게 영향을 줌
- 가운데를 추구해야된다
- 좋은 설계를 놓쳐서 안되고 회귀버그도 놓쳐선 안된다
- 클래스하나에 테스트 클래스 하나가 만들어짐.
- 만약 너무 많아지면? 클래스를 분할해야될 때
- 자연스럽게 분배된다
- 테스트 작성하다보면 이 원칙을 지킬수 밖에 없다
- 테스트용 컴포넌트와 프로덕션 컴포넌트를 나눠서 작업해야함
- 슈퍼클래스 계약을 서브클래스가 제대로 치환하는지 확인하라!
- 이상적으로 테스트는 모든 케이스에 대해 커버하고 있어야 되니
- 치환 여부도 테스트가 알아서 판단하겠지 맞네
- 인터페이스가 너무 많아서 뭘 호출해야 되는거야
- 단일책임 원칙 위배 인터페이스를 분리해줘야 된다.
정리
- 테스트를 작성한다고 솔리드가 되는게아니라
- 테스트를 하면서 이런것을 챙겨줘야 한다.
- 어떻게 테스트할까 고민하면 솔리드가 자연스럽게 따라옴
테스트 3분류
- 디비를 사용할 수 있는 중형 테스트
- 디비를 사용한다? 소형 테스트가 아니다
- 멀티스레드 환경에서 어떻게 동작할지 몰라 결과가 항상 같은지 보장 못함
- 중형 테스트가 많다? 가장 많이 저지르는 실수
테스트에 필요한 개념
sut?
- 테스트 하려는 대상 System under test
BDD
테스트 픽스처
- 테스트를 하기위해 필요한 자원을 미리 생성해둠
- sut가 테스트픽스처가 됨
- 테스트가 한눈에 잘안들어와 선호하지않는 부분도있음 개인차이
비욘세 규칙
- 유지하고 싶은 상태나 정책이 있다면 알아서 테스트를 만들어야 함
- 유지하고싶은 상태가 있으면 전부 테스트해라
Testabilt
Test double
- double -> 스턴트맨 대역
- 이런식으로 가짜객체 넣어주기
Dummy
- 아무런 구현이없어 테스트 돌아가게하고
- 결과 부분에서 사용자가 메일 대기인지 검증만
Fake
- 자체로직을 들고 있음
- 발송한 메세지를 기록하는 로직
stub
- 주로 외부연동하는 컴포넌트들에 사용 많이함
- 미리 준비된 값을 준비시켜줌
- 보통 mokito이용해서 구현 됨
Mock
- testDouble과 동일한 개념
- 메서드 호출을 확인하기 위한 객체
spy
의존성과 TestBility
- A 가 B를 사용한다.
- 결합이랑 같은의미 다른객체나 함수를 사용한다는 의미
- 의존성 주입이 의존성을 완전히 없에는게 아님
- 의존성을 약화시킨거지 없앤 건 아님
- 의존성을 제거? 객체간의 협력 시스템간의 협력을 부정하는건
- 대부분의 디자인패턴이나 설계는 의존성을 약하게 하는게 목표
- 근대 New는 사실상 하드 코드라 new를 없애는게 더 의존성을 약화시킨다고 한다.
- 오른쪽코드는 고기를 종류별로 ! 여러가지로 넣어줄수 있음
의존성 역전
- 상위 하위 모듈은 모두 추상화에 의존해야 한다.
- 세부사항이 추상화에 의존해야 된다.
- 화살표가 들어오는 방향에서 나가는 방향!
- 화살표의 방향을 바꾸는 테크닉
- import에 사용되는 경로에는 인터페이스나 추상 클래스만 사용해야한다.
- 이건좀 과한대..
- 인터페이스나 추상클래스같은 추상적인 선언을 정책이라보고
- 변동성이 큰 구체적인 요소가 세부사항으로 봐야된다.