[xUnit 테스트 패턴] 09장 - 지속되는 픽스처 관리


09장 - 지속되는 픽스처 관리

지속되는 신선한 픽스처 관리

  • 신선한 픽스처는 1회용(transient)일 수도 있고, 지속(persistent)될 수도 있다.
    • 지속적인 테스트 픽스처라도 테스트 끝날 때마다 해체 가능하면 신선한 픽스처 전략으로 쓸 수 있다.

무엇이 픽스처를 지속하게 만드는가

  • 지속 되는 경우
    • SUT 안에 상태가 있어 전에 어떻게 사용 되었는지 기억하는 경우
      • SUT에서 데이터베이스를 사용할 때
      • SUT에서 클래스 변수에 데이터를 저장하는 경우
  • 테스트케이스 클래스에서 다른 1회용 신선한 픽스처가 테스트 메소드 실행 이후에도 유지되게 갖고 있을 경우

지속되는 신선한 픽스처로 인해 생기는 문제

  • 반복 안 되는 테스트가 될 수 있다.
    • 기존의 자원과 새로 생성된 자원 간에 충돌 발생
      • 데이터베이스의 유일 키 제약 위반이 대표적
  • 반복 안 되는 테스트를 피하는 방법
    • 테스트 끝날 때마다 픽스처 해체
    • 모든 id 값에 별개의 생성 값을 쓰는 것

지속되는 신선한 픽스처 해체하기

  • 테스트의 의도를 애매하게 만들기 쉬우므르 해체 코드는 최대한 작성하지 않는게 좋다.
    • 가비지 컬렉션 해체

수동 해체

  • 사용한 픽스처를 삭제하는 확실한 방법은 테스트 메소드 코드 안에 해체 코드를 집어 넣는 것
  • tearDown 메소드
    • 모든 테스트 메소드가 성공이든 실패는 끝날 때마나 호출
    • 주의점
      • 픽스처를 인스턴스 변수, 클래스 변수, 전역 변수에 둬야 함
        • tearDown 메소드에서 픽스처에 접근할 수 있어야 함
      • 테스트에서 어떤 픽스처를 설치하더라도 tearDown 메소드가 동작해야 함

설치 코드 방식과 해체 코드 방식 짝 맞추기

  인라인 해체 위임 해체 암묵적 해체
인라인 설치 권장하지 않음 사용 가능 권장
위임 설치 권장하지 않음 사용 가능 권장
암묵적 설치 권장하지 않음 권장하지 않음 권장

자동 해체

  • 매번 테스트 코드나 테스트케이스 클래스에서 직접 해체 코드 작성하지 않아도 됨
  • 자동해체 메커니즘은 3부분으로 구성
    1. 삭제 할 객체 목록을 돌면서 각 객체에 대한 삭제 실행, 이때 발생한 에러를 보고할 수 있는 잘 테스트된 메커니즘
    2. 삭제 할 객체 종류에 따라 적당한 삭제 코드를 실행시킬 수 있는 디스패치 메커니즘 -> 객체에 delete를 호출하거나 객체 클래스에 따라 switch문을 쓰는 식으로 간단하게 구현 가능
    3. 새로 생성된 객체를 삭제 할 객체 목록에 등록해주는 메커니즘
  • 자동 해체 메커니즘을 구축하고 나면
    • 생성 메소드에서 등록 메소드 호출
    • tearDown 메소드에서 삭제 메소드 호출

데이터베이스 해체

  • 테이블 삭제 해체
  • 트랜잭션 롤백 해체

해체 코드를 아예 필요 없게 만들기

픽스처 충돌 피하기

  • 픽스처 해체해야 하는 이유
    1. 픽스처 객체로 버려진 채로 쌓이면 테스트가 느려질 수 있다.
    2. 버려진 픽스처 객체는 SUT의 오작동 및 단언문의 다른 결과 유발 할 수 있다.
    3. 버려진 픽스처는 신선한 픽스처를 생성하지 못하게 한다.

픽스처 지속 피하기

  • 지속되게 만드는 메커니즘을 테스트 대역으로 변경하기
  • 가짜 데이터베이스 만들기

느린 테스트에 대처하기

  • 공유 픽스처 사용
    • 픽스처를 여러 테스트에서 재사용 하기
    • 부작용 있음..
      • 서로 반응하는 테스트, 외로운(변뎍스러운) 테스트, 반복 안되는 테스트 등등
  • 디스크 기반 데이터 베이스를 메모리 데이터베이스나 가짜 데이터베이스로 바꾸기

공유 픽스처 관리

  • 지속되는 신선한 픽스처 관리와 비슷함
  • 다른점은 테스트가 끝날 때마다 픽스처를 해체할지 말지를 결정해 등 ㅁ테스트에서도 픽스처를 재사용 하는 것
    • 픽스처를 다른 테스트에서도 접근할 수 있게 해줘야 함
    • 픽스처 생성과 해체 둘 다 부를 수 있는 방법이 필요

공유 픽스처 접근하기

  • 재사용하려는 테스트 픽스처를 얻어낼 방법 필요
  • 의도가 드러나는 이름이 붙은 찾기 메서드로 픽스처에 접근
  • 클래스 변수에 저장해서 사용
  • 테스트 픽스처 레지스트리에 두는 것
    • 레지스트리 객체는 테스트 데이터베이스 일 수도 있고 하나의 클래스 일 수도 있다.

공유 픽스처 생성자 호출하기

  • 지연 설치 - 테스트케이스 클래스의 setUp 메서드에서 픽스처 생성
    • 테스트 스위트에서 어떤 테스트가 마지막 테스트인지 알 수 없음
    • 반복 안 되는 테스트가 될 수 있음
  • 테스트케이스 클래스 밖에서 같은 픽스처를 공유 하는 방법
    • 설치 데코레이터로 픽스처의 setUp, tearDown 실행과 테스트 스위트의 실행을 하나로 묶어 줄 수 있다.
      • 설치 데코레이터의 단점 - 단독으로 실행 될 수 없어 외로운 테스트가 됨
  • 미리 만든 픽스처 - 테스트가 실행되기 전에 픽스처 생성
    • 신선한 픽스처와 같이 조합해 불변 공유 픽스처 만드는데 사용
    • 완벽한 상태의 데이터베이스를 복사하거나 데이터 생성 프로그램을 돌려 수동으로 픽스처를 설치 할 수 있다.
      • 단점
        • 반복 안 되는 테스트가 있다면 테스트 돌리기 전에 수동 조정을 해줘야 한다.