이번 주 우테코 프리코스의 목표는 함수를 분리하고, 함수별로 테스트를 작성하는 것이다. 함수를 분리하는 것과 관련해서는 저번주에 느꼈던 객체지향과 관련해서 고민을 해 볼 예정이다. 오늘은 함수별로 테스트를 작성하는 것에 대해 생각해보려고 한다!
단위 테스트란, 애플리케이션 안에 있는 개별적인 코드 단위가 의도한 대로 작동하는지 확인하는 행위를 말한다.
더 쉽게 설명하자면, 개별적인 기능이 우리가 의도한대로 작동하는지 확인하는 행위이다.
@Test
@DisplayName("자동차는 명령을 받은 만큼 이동거리가 증가한다. given/when/then 패턴 적용")
void car_moves_as_ordered() {
// given (주어진 값)
int orderCount = 10;
Car car = new Car("pobi");
// when (기능 작동)
car.moveCar(orderCount);
int distanceResult = car.getDistance();
// then (기능 작동 후 검증)
assertThat(distanceResult).isEqualTo(orderCount);
}
private void validatePermittedOrderCount(final int orderCount) {
if (orderCount < 1 || orderCount > 10) {
throw new IllegarlArgumentException("이동 시킬 거리는 1 이상 10 이하의 수만 가능합니다.");
}
}
이 메서드를 테스트 하기 위해 orderCount에 넣고자 하는 값만 변경하여 코드를 중복 작성할 수 있다. 나는 이전에 이처럼 하나의 메서드를 여러 값을 넣어 테스트하기 위해 동일한 코드에 값만 바뀌는 테스트 코드를 작성했었다.
예)
@Test
void isInNameRange_전달받은_이름이_5글자_이상인_경우_false_반환() {
boolean nineLength = Validator.isInNameRange("123456789");
boolean sixLength = Validator.isInNameRange("123456");
assertThat(nineLength).isFalse();
assertThat(sixLength).isFalse();
}
그러나 이 코드를 @ParameterizedTest
와 @ValueSource
를 이용해 더 효과적으로 작성 가능하다!
@ParameterizedTest
@ValueSource(ints = {-1, 0, 11, 12})
@DisplayName("사용자를 이동 시킬 거리가 1 이상 10 이하의 수가 아니면 예외가 발생한다.")
void throws_exception_when_order_count_invalid(int givenOrderCount) {
// given
String expectedErrorMessage = "이동 시킬 거리는 1 이상 10 이하의 수만 가능합니다.";
Car car = new Car();
// when & then
assertThatThrownBy(() -> car.moveAsOrdered(givenOrderCount))
.isInstanceOf(IllegarArgumnetException.class)
.hasMessageContaining(expectedErrorMessgae);
}
@ValueSource
에는 boolean, String, double 등 여러가지 타입을 사용할 수 있다.
@ValueSource
에 작성한 값이 int givenOrderCount
에 들어가게 된다.
JUnit 테스트를 실행할 때 마다 이 애노테이션이 붙은 메서드를 먼저 실행한다. 따라서, 이 애노테이션을 이용해 모든 메서드 실행 이전에 객체를 초기화할 수 있다.
public class ProfileTest {
private Profile profile;
private BooleanQuestion question;
privte Citeria citeria;
@Before
public void create() {
profile = new Profile("Bull Hockey, Inc.");
question = new BooleanQuestion(1, "Got bonuses?");
criteria = new Criteria();
}
...
}
'클린 코드' 책의 저자 Bob Martin이 제시한 규칙으로, 효율적이고 좋은 단위 테스트를 하기 위한 5가지 요소로 이루어진 규칙이다.
테스트를 하는데 과도하게 많은 시간이 소요된다면 잘못된 방향으로 나아가고 있음을 의미할 수 있다. 설계가 깨끗하다면 테스트는 빠르게 유지된다. 느린 테스트를 점검하고, 테스트를 빠르게 유지하자!
테스트 코드는 어떤 순서나 시간에 관계없이 실행할 수 있어야 한다. 각 테스트가 작은 양의 동작에만 집중하면 테스트 코드를 집중적이고 독림적으로 유지하기 쉬워진다. 만약 테스트 메서드가 하나 이상의 이유로 깨진다면 테스트를 분할하는 것도 고려해야 한다.
테스트는 통제 아래에 있어야 하며, 결과가 어떻게 나올지에 대해 단언할 수 있어야 한다. 테스트를 반복실행하더라도, 내가 예상한 결과가 동일하게 나와야만 한다.
사실 단위테스트는 언제든 작성할 수 있다. 단위 테스트는 좋은 습관이라 양치질 처럼 "이번 한번만"이라며 미루고 싶을 수 있다. 단위 테스트로 코드를 미룰 수록 충치(결함)이 늘어날 수 있다.