tools & libs/단위테스트(junit, spock)

[junit] jupiter 3. 단위테스트 작성 기법

  • -
반응형

이제 단정문까지 학습했으므로 쓸만한 테스트를 만들어보자. 

이번 포스트에서는 given-when-then 패턴을 이용한 간단한 단위 테스트를 실행해 본다.

 

given-when-then 패턴

 

흔히 사용되는 단위테스트 패턴으로 행동 주도 개발(Behavior Driven Development: BDD)이 있는데 여기서는 테스트 코드 작성 단계를 given - when - then 패턴으로 작성하기를 권장한다.

  • given: 테스트를 위해 필요한 상황 준비(이런 상황, 객체, 데이터가 주어졌을 때)
  • when: 테스트하는 메서드 실행(어떤 메서드를 실행했다면)
  • then: 테스트 결과 검증(어떠한 결과가 나와야 한다.)

JUnit은 애초에 BDD를 위해 만들어진 녀석은 아니기 때문에 이 패턴이 강제되는 내용은 아니다. 따라서 주석으로 "이 부분은 어떤 내용이다." 라고 표시해주면 된다.

 

일반 상황의 검증

b가 Integer 범위의 자연수일 경우 단위테스트는 간단히 다음과 같이 해볼 수 있다.

@Test
@DisplayName("정상: b가 0이 아닌 경우는 정상적인 값이 반환된다.")
public void seccessOld() {
	Calculator calc = new Calculator();
	assertEquals(calc.divide(10, 5), 10/5);
}

하지만 이 경우는 코드가 복잡해진다면 어떤 상황에서 테스트가 진행된 것인지 나중에 코드를 보면 또다시 분석이 필요해진다. 남이 짠 코드라면 더더욱 힘들어진다.

이번에는 given-when-then 패턴을 이용해 보자. given-when-then은 특별히 어떤 영역이 지정된 것은 아니고 주석을 통해서 각각 필요한 일을 나타내고 관련 작업을 진행해 주면 된다.

@Test
@DisplayName("정상: b가 0이 아닌 경우는 정상적인 값이 반환된다.")
public void seccess() {
  // given
  Calculator calc = new Calculator();
  int a = 10;
  int b = 5;
  // when
  int result = calc.divide(a, b);
  // then
  assertEquals(result, 10/5);
}

코드는 훨씬 길어졌지만 테스트 과정에서 무엇을 준비하고 동작시키고 검증하는지가 명확히 표현된다.

 

예외 상황의 검증

다음은 b가 0이어서 예외가 발생하는 상황에 대한 테스트 예이다.

@Test
@DisplayName("예외: b가 0이므로 ArithmeticException이 발생한다.")
public void error() {
	// given
	Calculator calc = new Calculator();
	int a = 10;
	int b = 0;
	// when
	ArithmeticException e = assertThrows(ArithmeticException.class, ()-> calc.divide(a, b));
	// then
	assertEquals(e.getMessage(), "/ by zero");
}

 

F.I.R.S.T

given-when-then과 함께 단위테스트에서 자주 언급되는 원칙 중 하나가 F.I.R.S.T이다. 

  • Fast: 단위테스트는 빠르게 동작해야 한다. 목적을 단순히 설정하고 외부 환경과 무관하게 작성하는 것이 좋다. @SpringBootTest편하기는 하지만 상당히 무거운 테스트임으로 지양하고 @DataJpaTest 등 슬라이스 테스트를 하는 것이 좋다.
  • Independent: 하나의 테스트는 이전 테스트에 의한 상태에 의존해서는 안된다. 따라서 어떤 순서로 테스트를 하더라도 언제나 테스트는 성공해야 한다. 만약 insert 테스트 후 select 테스트가 진행되어야 한다면 안된다. select를 테스트 하기 위해서는 setup에서 insert하고 select 테스트 후 다시 delete 처리 해서 다른 테스트에 영향을 주지 않도록 해야 한다.
  • Repeatable: 여러 번 반복해서 테스트를 진행하더라도 동일하게 동작해야 한다. 특히 DB와 연관된 테스트를 진행해야 한다면 rollback 시키는 과정이 반드시 필요하다.
  • Self-Validating: 테스트 자체만으로 검증이 완료되어야 한다. 작업 결과를 개발자가 직접 확인한다면 테스트 자동화가 아니다. 이를 위해 Assert 문장을 작성해야 한다.
  • Timely: TDD를 한다면 테스트는 production code 개발 전에 진행해야 한다.(모두가 TDD는 아니니까..)

https://dzone.com/articles/writing-your-first-unit-tests

 

Writing Your F.I.R.S.T Unit Tests - DZone

When writing unit tests in Java, stick to FIRST. Your tests should be fast, independent, repeatable, self-validating, and timely (unless you're using TDD).

dzone.com

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.