반응형

테스트코드/개요 11

11. 단위 테스트 안티 패턴

비공개 메서드 단위 테스트 단위 테스트를 하려고 비공개 메서드를 노출하면 기본 원칙 중 하나인 식별할 수 있는 동작만 테스트하는 것을 위반한다. 비공개 메서드를 직접 테스트하는 대신, 포괄적인 식별할 수 있는 동작으로서 간접적으로 테스트하는 것이 좋다. 비공개 메서드를 절대 테스트하지 말라는 규칙에도 예외가 있다. 예외를 이해하려면 코드의 공개 여부와 목적 간의 관계를 다시 살펴봐야 한다. 식별할 수 있는 동작 구현 세부 사항 공개 좋음 나쁨 비공개 해당 없음 좋음 테스트로 유출된 도메인 지식 도메인 지식을 테스트로 유출하는 것 또한 흔한 안티 패턴임 보통 복잡한 알고리즘을 다루는 테스트에서 일어난다. 테스트를 작성할 때는 특정 구현을 암시하지 말라. 단위 테스트에서는 예상 결과를 하드코딩하는 것이 좋다..

10. 데이터베이스 테스트

DB 테스트를 위한 전제 조건 통합테스트에서는 관리 의존성이 그대로 있어야 한다. 형상 관리 시스템에서 DB 유지 모든 개발자를 위한 별도의 DB 인스턴스 사용 DB 배포에 마이그레이션 기반 방식 작용 참조 데이터는 애플리케이션이 제대로 작동하도록 미리 채워야 하는 데이터다. 인메모리 DB는 일반 DB와 기능적으로 일관성이 없기 때문에 사용하지 않는 것이 좋다. 또한 운영 환경과 테스트 환경이 일치하지 않는 문제가 발생한다. 일반 DB와 인메모리 DB의 차이로 인해 테스트에서 거짓 양성 또는 거짓 음성이 발생하기 쉽다. 쓰기를 철저히 테스트 하는 것이 중요하다. 위험성이 높기 때문 쓰기 작업이 잘못되면 데이터가 손상돼 DB뿐만 아니라 외부 애플리케이션에도 영향을 미칠 수 있다. 그러나 읽기는 해당하지 않..

9. 목 처리에 대한 모범 사례

목의 가치를 극대화하기 비관리 의존성에만 목을 사용하는 것은 목의 가치를 극대화 하는 첫번째 단계일 뿐이다. 목을 사용할 때는 꼭 **시스템 끝에서 비관리 의존성과의 상호 작용**을 검증하라!! IBus 는 시스템 끝에 있다. IMessgeBus는 컨트롤러와 메시지 버스 타입 사슬에서 중간 고리일 뿐이다. IMessageBus 대신 IBus를 목으로 처리하면 회귀 방지가 좋아진다. 목 처리에 대한 모범 사례 비관리 의존성(외부 시스템)에만 목 적용하기 시스템 끝에 있는 의존성에 대해 상호 작용 검증하기 목은 통합 테스트만을 위한 것이다. 도메인 모델(persistance Layer) 은 단위 테스트 범주에 속하고, 컨트롤러를 다루는 테스트(presentation Layer)는 통합 테스트다. 테스트당 목..

8. 통합 테스트를 하는 이유

통합테스트? 통합 테스트는 테스트 스위트에서 중요한 역할을 함 단위 테스트 개수와 통합 테스트의 균형을 맞추는 것도 중요함 단위 테스트가 아닌 모든 테스트를 통합 테스트에 해당함 통합 테스트는 회귀 방지와 리팩터링 내성이 우수하고, 단위 테스트는 유지 보수성과 피드백 속도가 우수하다. 통합 테스트는 주요 흐름(happy path)과 단위 테스트가 다루지 못하는 예외 상황(edge case)을 다룬다. 비즈니스 시나리오당 하나 or 두 개가 있으면 시스템 전체의 정확도를 보장해 준다. 코드의 4가지 유형에서 도메인 모델 및 알고리즘은 단위 테스트에, 컨트롤러는 통합 테스트에 해당함 테스트 피라미드를 통해 다시 보는 테스트 수와 테스트 종류와의 관계 좋지 않은 테스트를 작성하는 것보다 차라리 테스트를 작성하..

7. 가치 있는 단위 테스트를 위한 리팩토링

리팩토링할 코드 식별하기 모든 제품 코드는 2차원의로 분류가 가능 복잡도 또는 도메인 유의성 협력자 수 코드 복잡도 코드 복잡도는 코드 내 의사 결정(분기) 지점 수가 클수록 → 복잡도 커진다. 도메인 유의성 코드가 프로젝트의 문제 도메인에 대해 얼마나 의미 있는지 일반적으로 도메인 계층(data aceess Layer)의 모든 코드는 최종 사용자의 목표가 직접적인 연관성이 있음 → 도메인 유의성이 높다 유틸리티 코드의 경우 연관성이 거의 없다. 복잡한 코드와 도메인 유의성을 갖는 코드가 단위 테스트에 가장 이롭다. 회귀 방지에 뛰어나기 때문! 코드의 4가지 유형 도메인 모델과 알고리즘 보통 복잡한 코드는 도메인 모델 but 100%는 아님 간단한 코드 협력자가 없이 코드가 간단한 경우 테스트할 가치가 ..

6. 단위 테스트 스타일

단위 테스트의 세가지 스타일 단위 테스트는 세가지 스타일이 있다. 출력 기반 테스트 상태 기반 테스트 통신 기반 테스트 출력 기반 테스트 테스트 대상 시스템(SUT)에 입력을 넣고, 생성되는 출력을 점검하는 방식 반환 값만 검증하면 됨 사이드 이펙트가 거의 없음 함수형이라고도 함 거짓 양성 방지가 가장 우수함 상태 기반 테스트 작업이 완료된 후 시스템 상태를 확인하는 방식 여기서 상태란 SUT나 협력자 중 하나, 혹은 DB나 파일 시스템과 같은 프로세스 외부 의존성의 상태를 의미 통신 기반 테스트 협력자 간의 통신을 검증하는 방식 허위 경보에 가장 취약함 세가지 스타일 중 출력 기반 테스트를 선호해라! 출력 기반 테스트 >>>>> 상태 기반 테스트 >>>>>>>>>>>>>>>>>>>>>>>>>> 통신 기..

5. 목과 테스트의 취약성

목과 스텁 구분 테스트 대역은 목과 스텁으로 구분 목(Mock) 외부로 나가는 상호 작용을 모방하고 검사하는데 도움 SUT가 상태를 변경하기 위한 의존성을 호출 ex) 이메일 발송 스텁(Stub) 내부로 들어오는 상호작용을 모방하는데만 도움 SUT가 입력 데이터를 얻기 위한 의존성을 호출 ex) DB로부터 데이터 검색 테스트 대역은 크게 목과 스텁으로 나뉜다. 목과 스텁의 구분 도구로서의 목과 테스트 대역으로서의 목을 구분하자 도구로서 목은 목 라이브러리(ex)Mockito)을 말함 테스트 대역으로의 목은 위에서 말했던 외부로 나가는 상호 작용을 위한 목 목과 스텁을 함께 쓸수도 있다. Mockito의 경우 둘 다 사용 @DataJpaTest @ExtendWith(MockitoExtension.class..

4. 좋은 단위 테스트의 4대 요소

좋은 단위 테스트에는 다음 4가지 특성이 있음 - 회귀 방지 - 리팩토링 내성 - 빠른 피트백 - 유지 보수성 회귀 방지 코드를 수정한 후, 기능이 의도한 대로 작동하지 않는 경우를 말함 → 즉, 코드 수정 후 버그가 있는데도 테스트가 통과되면 안된다. 회귀를 방지하려면 다음 사항을 고려해 봐야 한다. 테스트 중에 실행되는 코드의 양 코드 복잡도 코드의 도메인 유의성 일반적으로 실행되는 코드가 많을수록 회귀가 나타날 가능성이 높음 회귀방지를 극대화하려면 테스트가 가능한 많은 코드를 실행하는 것을 목표로 해야 한다. 리팩토링 내성 테스트를 실패로 바꾸지 않고 기본 애플리케이션 코드를 리팩토링할 수 있는지에 대한 척도 → ex) 메서드 이름을 바꾸거나, 코드 조각을 새로운 클래스로 추출하기 거짓 양성 리팩토..

3. 단위 테스트 구조

3. 단위 테스트 구조 단위 테스트의 구조 크게 AAA 패턴과 Given-When-Then 패턴 준비 (Arrange, Given) 실행 (Act, When) 검증 (Assert, Then) 단위 테스트 안티 패턴 테스트 간에 높은 결합도를 가지면 안된다. 테스트를 수정해도 다른 테스트에 영향이 있으면 안됨 준비(Given) 단계에서 생성자로 SUT를 준비하면 테스트 가독성이 떨어짐 테스트만 보고 큰 그림을 보기 힘듦 정적 팩토리 메서드나 빌더 패턴을 이용해서 SUT나 협력자를 준비하자. 단위 테스트 명명 지침 엄격한 명명 정책을 따르지 않는다. 표현의 자유를 허용하자 비개발자들에게 시나리오를 설명하는 것처럼 테스트 이름을 짓자. 단어를 밑줄(_)로 구분하자. 가독성이 향상 된다. 유틸리티 코드의 경우 ..

2. 단위 테스트란 무엇인가

통합 테스트 런던파의 통합 테스트 : 실제 협력자 객체를 사용하는 모든 테스트를 통합 테스트이다. 고전파는 런던파 입장에서 모두 통합 테스트이다. 고전파의 통합 테스트 : 공유 의존성 접근하는 테스트 또는 둘 이상의 동작 단위 검증할 때 통합 테스트이다. 단위 테스트의 정의 - 작은 코드 조각을 검증 - 빠르게 수행 가능 - 격리된 방식으로 처리 가능 → 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트 좋은 테스트의 규칙(FIRST) Fast: 테스트는 빠르게 동작하여 자주 돌릴 수 있어야 한다. Independent: 각각의 테스트는 독립적이며 서로 의존해서는 안된다. Repeatable: 어느 환경에서도 반복 가능해야 한다. Self-Validating: 테스트는 성공 또는 실패로..

반응형