단위 테스트란

  • 단위 테스트는 다음 세 가지 속성을 만족하는 테스트를 의미한다
    • 작은 코드 조각(단위) 를 검증하고
    • 빠르게 수행하고
    • 격리된 방식으로 처리하는 자동화된 테스트
  • 위의 두 개는 이견의 여지가 거의 없지만, 격리된 방식으로 처리하는 자동화된 테스트 는 각 분파마다 이견의 여지가 있다
  • 위의 이견이 있는 분파 분파는 고전파런던파 로 나뉜다

단위 테스트의 분파

고전파(classical school)

  • 테스트는 협력자를 대체하지 않고 운영용 인스턴스를 사용한다.
  • 협력자의 내부에 버그가 있으면 테스트는 실패한다. 즉, 두 테스트는 서로 격리되어 있지 않다
  public void openSuccessfully_whenCustomerHasEnoughMoney() {
    // given
    Customer customer = new Customer();
    Store store = new Store();
    customer.addMoney(MoneyType.WON, 1000);
 
    // when
    boolean success = store.open(customer);
 
    // then
    assertThat(success).isEqualTo(true);
    assertThat(store.isOpen()).isEqualTo(true);
    assertThat(customer.usedMoney()).isEqualTo(1000)
  }

런던파(London school)

  • 테스트 대상을 협력자(collaborator) 에게서 격리하는 것을 일컫는다.
  • 하나의 클래스가 다른 클래스, 또는 여러 클래스에 의존하면 이 모든 의존성을 테스트 대역(test double) 으로 격리시킨다
  public void openSuccessfully_whenCustomerHasEnoughMoney() {
	// given
	Customer customer = mock(Customer.class);
	given(customer.hasEnoughMoney()).thenReturn(true);
	Store store = new Store();
	
	// when
	boolean success = store.open(customer);
	
	// then
	assertThat(success).isEqualTo(true);
	verify(customer, times(1)).hasEnoughMoney();
  }
  • 준비 단계에서 테스트는 실제 인스턴스를 생성하지 않고, Customer 의 mock 클래스를 생성함
  • 테스트가 완료된 다음에는 mock 의 메서드가 실제로 호출되었는지 verify 로 확인

장점

  • 테스트가 실패하면 코드베이스의 어떤 부분이 고장난 것인지 바로 알 수 있다
  • 객체 그래프를 분할할 수 있다
    • 하나의 메서드가 다양한 객체와 의존성을 맺고 있을 때, 각각의 객체를 모두 생성할 필요 없이 사용할 수 있다

차이점

  • 고전파에서는 verify 시에 실제로 store 의 상태를 확인할 수 있다
  • 런던파에서는 해당 객체를 어떻게 호출하는지 확인할 수 있다

통합 테스트

  • 단위 테스트의 기준 중 하나 이상을 충족하지 못하는 테스트
  • 고전파의 관점에서 단위 테스트를 다시 정의할 수 있음
    • 단일 동작 단위를 검증하고
    • 빠르게 수행하고
    • 다른 테스트와 별도로 처리한다(공유 의존성과 프로세스 외부 의존성을 모킹한다)
  • 공유 의존성에 접근하는 테스트
    • 다른 테스트와 분리하여 실행할 수 없다
    • 데이터베이스에 접근하게 되면 데이터베이스의 상태 변경이 병렬로 진행될 때, 의존하는 다른 모든 테스트의 결과가 변경될 것임
  • 프로세스 외부 의존성에 접근하는 테스트
    • 테스트가 느려진다 -> 데이터베이스 호출은 실행 시간에 수백 밀리초를 추가하는데, 테스트 스위트가 커지면 이는 큰 값이 된다
  • 둘 이상의 동작 단위를 검증하는 테스트
    • 이는 다른 테스트와 별도로 처리되는게 아니라 통합 테스트이다.

엔드 투 엔드 테스트

  • 통합 테스트의 일부
  • 코드가 프로세스 외부 종속성과 함께 어떻게 작동하는지 검증한다
  • 일반적으로 통합 테스트보다 의존성을 더 많이 포함한다
    • 프로세스 외부 의존성을 전부, 또는 대다수를 가지고 작동한다