03 단위테스트 구조
구성 방법
- AAA 패턴 사용
- 단순하고 균일한 구조를 갖는 데 도움된다.
- 준비 구절 : 테스트 대상 시스템과(SUT, System Under Test) 의존성을 원하는 상태로 만든다.
- 실행 구절 : 메서드를 호출하고 준비된 의존성을 전달하며 출력값을 캡처한다.
- 검증 구절 : 반환값이나 SUT와 협력자의 최종상태, SUT가 협력자에 호출한 메서드 등 검증.
- GivenWhenThen 패턴
- AAA와 차이는 없다. Given-When-Then이 더 읽기쉽다.
- TDD 시에는 기능동작을 알지못하므로, 실행-검증구절을 먼저 작성해도 좋다.
- 복수개의 준비-실행-검증 구절 피하기
- 복수개의 실행구절이 있는것은 여러개의 동작단위를 검증하는 테스트를 뜻한다. = 통합테스트이다.
- 테스트 내 if문 피하기
- 단위테스트든 통합이든 분기가 없는 간단한 일련의 단계여야한다.
- if문은 테스트가 너무 많은것을 검증한다는 표시이다.
- 각 구절은 얼마나 커야하는가
- 준비구(given)이 가장 큰 경우 :
- 테스트 내 private 메서드, factory class로 분리하는것이 좋다.
- 코드 재사용 패턴 : Object Mother , Test Data Builder
- 실행구절이 한줄 이상인 경우를 경계하라.
- 절대 두줄 이상 두지말라고 할수는 없지만, 캡슐화가 깨져있는 경우라고 볼수있다.
- 준비구(given)이 가장 큰 경우 :
- 검증 구절은 검증문이 얼마나 있어야하는가
- 단위테스트는 코드의 단위에 따라 분리되는것이 아니므로, 검증문이 하나만 있어야한다는 말은 옳지 않다.
- 모든 속성 검증 대신, 적절한 필드만 equal 테스트를 하는것이 좋다.
- 테스트 대상 시스템 구별하기
- 테스트 대상을 의존성과 구분하는것은 중요하다. 준비구절에서 다른것들과 구분하기위해 변수명을 sut로 해보자.
- 준비.실행.검증 주석 제거하기
- AAA 패턴을 따르고 준비 및 검증 구절에 빈줄을 추가하지 않아도 되는 테스트라면 구절 주석을 제거하고, 그렇지않으면 주석을 달자.
xUnitTest 프레임워크 살펴보기
.Net 전용 프레임워크이며 다른 언어 프레임워크도 비슷하다. 그냥 검색해서 살펴보자
testFixture 재사용
- 테스트에서 언제 어떻게 코드를 재사용하는지 아는것이 중요하다.
- 준비구절에서 재사용하는것이 가장 효율적.
- TestFixture은 테스트 실행 대상 객체이다. SUT로 전달되는 인수.
- 각 테스트 실행 전에 알려진 고정 상태로 유지하기때문에 동일한 결과를 생성한다.
- 테스트 클래스 생성자 혹은 setup 단계에서 testFixture을 사용하는것은 잘못된 방법.
- 테스트간 결합도가 높아지고 가독성이 덜어진다.
- AAA 패턴을 따르고 준비 및 검증 구절에 빈줄을 추가하지 않아도 되는 테스트라면 구절 주석을 제거하고, 그렇지않으면 주석을 달자.
- 테스트간의 높은 결합도는 안티패턴이다.
- 테스트 클래스에 공유상태를 두지말자.
- 테스트 가독성을 떨어뜨리는 생성자 사용
- 준비구간이 짧더라도 테스트메서드내에서 하는것이 좋다.
- 더 나은 테스트 픽스처 재사용법
- private factory method를 두고 재사용해도좋다.
- 테스트용 db연결 처럼 테스트 전부 또는 대부분에 사용되는 픽스처를 생성자에 인스턴스화하는것은 좋은 방법이다.
단위테스트 명명법
- 좋지 않은 예 : sut_sinario_result -> `Sum_TowNumbers_ReturnsSum` - 쉽고 잘 읽히는 영어제목을 하자 -> `Sum_of_two_numbers` - 엄격한 명명 정책을 따르지는 않는다. - 단어를 밑줄 표시로 구분한다. - 테스트 클래스 명을 지정할때는 보통 ClassNameTest 라고 짓지만, 꼭 Class가 동작단위는 아니므로, 여기서 Class는 동작단위로 검증할수있는 진입점으로 여긴다. - **SUT의 메서드 이름은 테스트명에 포함하지말라.** - 코드를 테스트하는것이 아니므로!! 이는 test suite의 유지보수성에 부정적인 영향을 미친다. - sould be -> is 사실을 서술할때는 소망이나 욕구가 들어가지않아야한다. ### 매개변수화된 테스트 리팩터링하기 - 동작이 너무 복잡하면 매게변수화된 테스트를 사용하지 마라. - 매개변수만으로 테스트결과를 예측할수있다면, 하나의 메서드로 두고 boolean결과를 매개변수에서 같이 넘기자. ### 검증문 라이브러리를 사용한 테스트 가독성 향상 - 가독성이 높은 라이브러리를 사용하자. (책에서는 Fluent Assertions)