원문: https://testing.googleblog.com/2013/08/testing-on-toilet-test-behavior-not.html (Translated by Google Gemini)


여러분의 신뢰할 수 있는 Calculator 클래스는 많은 행복한 사용자를 보유한 가장 인기 있는 오픈소스 프로젝트 중 하나입니다:

public class Calculator {
    public int add(int a, int b) {
        return a + b;  
    }
}

또한 제대로 작동하는지 확인하는 테스트도 있습니다:

public void testAdd() {
    assertEquals(3, calculator.add(2, 1));
    assertEquals(2, calculator.add(2, 0));
    assertEquals(1, calculator.add(2, -1));
}

그러나 새로운 멋진 라이브러리는 덧셈 연산자 대신 사용하면 코드에서 몇 배의 속도 향상을 약속합니다. 여러분은 이 라이브러리를 사용하기 위해 들뜬 마음으로 코드를 변경합니다:

public class Calculator {

    private AdderFactory adderFactory;

    public Calculator(AdderFactor adderFactory) { this.adderFactory = adderFactory; }

    public int add(int a, int b) {
        Adder adder = adderFactory.createAdder();  
        ReturnValue returnValue = adder.compute(new Number(a), new Number(b));  
        return returnValue.convertToInteger();  
    }
}

그것은 쉬웠지만, 이 코드에 대한 테스트는 어떻게 해야 할까요? 코드의 구현만 변경하고 사용자에게 보여지는 동작은 변경되지 않았으므로 기존 테스트는 변경할 필요가 없습니다. 대부분의 경우 테스트는 코드의 공개 API를 테스트하는 데 중점을 두어야 하며, 코드의 구현 세부 사항은 테스트에 노출될 필요가 없습니다.

구현 세부 사항에 독립적인 테스트는 유지 관리가 더 쉽습니다. 구현을 변경할 때마다 변경할 필요가 없기 때문입니다. 또한 이해하기도 더 쉽습니다. 클래스 메서드를 사용할 수 있는 모든 방법을 보여주는 코드 샘플처럼 작동하므로 구현에 익숙하지 않은 사람도 테스트를 읽고 클래스 사용법을 이해할 수 있습니다.

구현 세부 사항을 테스트하려는 많은 경우가 있지만 (예: 구현이 데이터 저장소 대신 캐시에서 읽는지 확인하려는 경우), 대부분의 경우 테스트가 구현에 독립적이어야 하므로 이러한 경우는 덜 일반적입니다.

구현이 변경되면 테스트 설정은 변경되어야 할 수 있지만 (예: 클래스가 생성자에서 새로운 의존성을 갖도록 변경하는 경우, 테스트는 클래스를 생성할 때 이 의존성을 전달해야 함), 코드의 사용자에게 보여지는 동작이 변경되지 않으면 실제 테스트 자체는 일반적으로 변경할 필요가 없습니다.