인수 테스트 기반 TDD

CHEESE·2023년 2월 20일
post-thumbnail

인수 테스트를 이용한 개발 흐름

💡 가독성

  • 가독성이 좋지 않으면 방치됨
  • 변경 사항에 대해 수정이 어려움
  • 중복 제거가 필요

중복 제거

  • 메소드 분리
  • CRUD 추상화
  • Cucumber, JBehave와 같은 BDD 도구 사용

의도 드러내기

  • 한글 메소드!

리팩토링하는 이유

  • 테스트를 유지보수하기 좋은 상태로 만들기 위해

💡 인수 테스트 잘 작성하기

인수 조건을 테스트로 옮기기

Feature: 간략한 기능
Background: 시나리오 사전 조건
Scenario: 시나리오 제목

given: 사전조건
when: 발생해야 되는 이벤트
then: 사후조건

And: 앞선 내용에 추가적인 내용 기술

확인하는 방법?

1) 응답 코드로 확인
2) 조회 request 후 response 값에서 확인
중요한 로직이라면 2, 1번으로도 넘어갈 수 있게끔 구성
1+2도 쓸 수 있다~ 그러나 꼼꼼히 만들다가 루즈해지지 않도록 조심

인수 테스트 클래스

  • Feature 기준으로 클래스 나눔
  • Scenario 기준으로 메소드 나눔
  • Feature 내부의 Scenario는 같은 테스트 픽스쳐를 공유

간단한 성공 케이스를 우선 작성

  • 동작 가능한 간단한 케이스 먼저
  • 실패하는 테스트를 지켜보기
  • when - then - given 순서로 작성하기 (명확한 순서대로)

💡 TDD ! 어려워 !

규칙은 간단하지만 잘 하는지 모르겠음
대부분의 내용이 추상적임

인수 테스트 기반으로 TDD를 하면?

  • 인수 테스트로 TDD로 개발할 방향을 지시
  • 중간에 길을 잃더라도 인수 테스트를 기점으로 다시 찾기 쉬움

어떻게 인수 테스트에서 TDD 사이클로 가나?

단위 테스트

  • 작은 코드 검증
  • 빠르게 수행
  • 격리된 방식으로 처리

Test Double

테스트 대상이 의존하는 객체를 협력 객체라고 하는데
이 때 협력 객체를 Test Double이라고 한다.
실제 객체 대신 사용되는 모든 종류의 객체애 대한 일반 용어

Stub

mockito
짜고 치기
A 메소드를 호출하면 B 응답이 나오는 것을 미리 정해둠
when().thenReturn() ~~~

Mock

mocking된 방식으로 만들어진 객체
mocking: 행위를 지정하고 테스트를 만드는게 아니라 협력 객체가 호출되는 횟수를 지정을 하고 호출되었는지 여부를 검증하는 방식
행위를 검증

Fake

다른 객체를 가지고 테스트를 만드는 것
dao -> db
fakeDao -> HashMap

협력 객체를 실제로 만들까 가짜로 만들까?

  • 실제 객체를 사용하면 협력 객체의 행위를 협력 객체 스스로가 정의
  • 가짜 객체를 사용하면 협력 객체의 행위를 테스트가 정의
    테스트의 목적이 뚜렷하다면 가짜 객체

가짜 객체(테스트 더블)을 사용한다면

  • 테스트 대상을 검증할 때 외부 요인(협력 객체)으로부터 철저히 격리
  • 테스트가 협력 객체의 상세 구현을 알아야만 구현 가능 == 깨지기 쉬움

진짜 객체를 사용한다면

  • 협력 객체의 상세 구현에 대해 알 필요 없음
  • 협력 객체의 정상 동작 여부에 영향을 받음

그래서!

  • TDD를 연습할 때는 실제 객체를 활용하는 것을 우선적으로
  • 테스트 작성이 어렵거나 흐름이 이어지지 않는다면 테스트 더블을 활용하는 방법으로 접근

OutSide-In Tdd Inside-Out Tdd

💡 인수 테스트 기반 리팩토링

테스트 코드 - 프로덕션 코드를 다 짜고
불필요한 필드나 클래스를 발견하면
결국 테스트를 다 지우고 새로 짠다... 이게 맞아?
테스트를 먼저 수정한다면?

레거시 코드 리팩토링

  • 인수 테스트를 작성해서 기존 구현된 기능을 보호
  • 파악 가능한 부분부터 단위 테스트를 만들어 기능 검증
  • 인수 테스트 보호 속에서 리팩토링

장점

  • 인수 테스트 작성 후 리팩토링하면 사이드 이펙트에 대한 피드백을 바로 받을 수 있음
  • 기능을 구현하다 꼬여도 인수 테스트 성공 시점으로 리셋 가능
  • 안심하고 작은 단위로 메소드를 분리할 수 있음

  • 기존 코드를 수정하려 하지 말고 새로운 코드를 한 벌 더 만들어보기(스트랭글러 패턴)

💡 인증 기반 인수 테스트

RestAssured 기반의 테스트에서는 auth() 메소드를 통해 로그인과 데이터 요청을 한번에 받을 수 있다.

0개의 댓글