단위 테스트가 많은 시간을 절약하는 이유

5830 단어 javajunittddtesting
개발자로서 단위 테스트를 작성해야 한다는 말을 들으면 처음에는 더 많은 노력이 필요한 것처럼 들립니다.
작성한 코드는 이미 시도하여 보았듯이 작동합니다.

그러나 주변 세계는 끊임없이 변화하고 있습니다.
그리고 외부의 변경에도 불구하고 코드가 여전히 작동하는지 어떻게 확신할 수 있습니까?

날짜 형식?



프로그램에 문자열을 날짜로 파싱하는 함수가 있다고 가정해 봅시다.

/**
 * @param input a date with format "dd.MM.yy HH:mm"
 */
public static Date parseDate(String input) throws ParseException {
    return DateFormat.getInstance().parse(input);
}


여기에서는 JDK의 클래스를 사용하고 Javadoc에서 input 매개변수의 형식을 설명합니다.
일단 이것을 시도하면 또 무엇이 잘못될 수 있습니까?
확실히 이것은 영원히 작동합니다.

Java 8에서 Java 11로 업데이트한 후에도 모든 사람이 함수가 설명대로 여전히 작동한다고 가정할 것입니다.
결국 우리는 JDK의 클래스만 사용하고 있습니다.

테스트를 해보자:

@Test
void parseDate_should_parse_String_to_Date() throws ParseException {
    Date parsed = parseDate("14.02.09 00:31");
    assertThat(parsed).hasYear(2009).hasMonth(2).hasDayOfMonth(14).hasHourOfDay(0).hasMinute(31);
}


Java 8을 사용하면 테스트가 성공적입니다.
모든 사람은 아마도 Java 11에서도 같은 것을 기대할 것입니다.
그러나 결과는 다음과 같습니다.

java.text.ParseException: Unparseable date: "14.02.09 00:31"

    at java.base/java.text.DateFormat.parse(DateFormat.java:395)
    at org.example.Dummy.parseDate(Dummy.java:31)
    at org.example.DummyTest.parseDate_should_parse_String_to_Date(DummyTest.java:36)


Java 11에서는 DateFormat의 기본 패턴이 "dd.MM.yy HH:mm"에서 "dd.MM.yy, HH:mm"으로 변경되었습니다.
이제 개발자로서 선택해야 합니다. 인터페이스(Javadoc 참조)가 다시 충족되도록 parseDate 구현을 조정하시겠습니까?
아니면 인터페이스(Javadoc)와 모든 호출자를 새 동작에 맞게 조정하시겠습니까?

통화 형식?!?



Java 8에서 Java 11로의 업데이트에서 영감을 받은 두 번째 예입니다.
프로그램에 숫자를 통화 형식으로 지정하는 기능이 있다고 가정해 보겠습니다.
간단히 하기 위해 JDK에서 클래스를 다시 살펴보겠습니다.

/**
 * Formats 13.37 as "13,37 €"
 */
public static String formatCurrency(double input) {
    return NumberFormat.getCurrencyInstance(Locale.GERMANY).format(input);
}


그럼 테스트를 해보자:

@Test
public void formatCurrency_should_format_double_to_String() {
    String formatted = formatCurrency(13.37);
    assertThat(formatted).isEqualTo("13,37 €");
}


Java 8을 사용하면 테스트가 성공적입니다.
그러나 Java 11에서는 다음 오류가 발생합니다.

Expecting:
 <"13,37 €">
to be equal to:
 <"13,37 €">
but was not.


해결책: Java 8에서는 숫자와 통화 기호 사이에 일반 공백(ASCII 코드 0x20)이 있습니다.
Java 11에서는 끊기지 않는 공백(ASCII 코드 0xA0)이 사용됩니다.
둘 다 똑같아 보이지만 같지 않습니다.

JDK의 이러한 변경은 formatCurrency(13.37).replace(" €", "")가 여전히 "13.37 €" 문자열을 반환하는 효과가 있습니다.

결론



이러한 특정 사례는 시스템에 깊숙이 숨겨져 있습니다.
Java 업데이트 후에는 아무도 로컬 테스트나 고객의 테스트 시스템에서 이러한 변경 사항을 알아차리지 못했을 것입니다.
이것은 "프로덕션 시스템에서 처음으로 보이는 버그"의 전형적인 후보가 될 것입니다.
다행히 두 경우 모두 영향을 받는 부분에 대한 단위 테스트가 있었습니다.

단위 테스트는 함수가 개발자가 기대한 대로 작동하는지 확인하는 좋은 방법입니다.
단위 테스트가 없으면 무언가가 예상대로 작동하지 않는 경우에만 매우 늦거나 너무 늦게 알 수 있습니다.

그건 그렇고, 당신이 작성한 코드를 시험해 보면 이 "시도"를 직접 테스트로 변환할 수 있지 않습니까?
그러면 다른 개발자가 무언가를 시도하고 싶어도 테스트가 훨씬 빨라집니다.

좋은 웹페이지 즐겨찾기