원문: https://testing.googleblog.com/2014/10/testing-on-toilet-writing-descriptive.html (Translated by Google Gemini)


여러분은 테스트 이름을 어떻게 짓나요? 아래 코드 샘플을 한번 보세요. 이 테스트가 무엇을 하는지, 어떤 동작을 검증하는지 즉시 파악할 수 있나요?

public void testLogin() {
    // ...
}

이 테스트는 사용자가 성공적으로 로그인하는 시나리오를 테스트할 수도 있고, 잘못된 비밀번호를 입력했을 때의 시나리오를 테스트할 수도 있습니다. 테스트가 무엇을 하는지 이해하려면 테스트의 본문을 읽어야만 합니다. 이제 아래의 다른 테스트 이름을 보세요.

isUserLockedOut_lockOutUserAfterThreeInvalidLoginAttempts

이제 여러분은 테스트 본문을 읽지 않고도, 단지 테스트 이름만 읽는 것만으로 어떤 동작이 테스트되고 있는지 이해할 수 있어야 합니다.

위의 코드 샘플에 있는 테스트 이름은 테스트되는 시나리오(“invalidLogin”)에 대한 힌트를 주지만, 예상되는 결과가 무엇인지는 실제로 말해주지 않으므로, 그것을 알아내기 위해 코드를 읽어야 했습니다.

테스트 이름에 시나리오와 예상 결과를 모두 넣는 것은 여러 가지 다른 이점을 가집니다:

  • 클래스가 가진 모든 가능한 동작을 알고 싶다면, 테스트 코드를 파고들거나 심지어 클래스 자체를 파고들어 그 동작을 알아내려고 몇 분 또는 몇 시간을 소비하는 대신, 그 테스트 클래스의 테스트 이름들만 읽으면 됩니다. 그렇지 않으면 서로 다른 동작에 대한 단언문(assertion)들을 하나의 테스트에 쏟아부으려는 유혹에 빠질 수 있으며, 이는 시간이 지남에 따라 계속 커져서 이해하고 유지하기 어려운 테스트로 이어질 수 있습니다.

  • 테스트 코드만으로는 테스트되는 정확한 동작이 항상 명확하지 않을 수 있습니다. 만약 테스트 이름이 이에 대해 명시적이지 않다면, 때로는 테스트가 실제로 무엇을 테스트하는지 추측해야 할 수도 있습니다.

  • 어떤 기능이 테스트되고 있지 않은지 쉽게 알 수 있습니다. 만약 여러분이 찾고 있는 동작을 설명하는 테스트 이름을 볼 수 없다면, 그 테스트가 존재하지 않는다는 것을 알 수 있습니다.

  • 테스트가 실패했을 때, 테스트의 소스 코드를 보지 않고도 어떤 기능이 고장 났는지 즉시 알 수 있습니다.

테스트의 이름을 구조화하는 데는 몇 가지 일반적인 패턴이 있습니다 (한 가지 예는 “should"를 이름에 넣어 영어 문장처럼 이름을 짓는 것입니다. 예: shouldLockOutUserAfterThreeInvalidLoginAttempts). 어떤 패턴을 사용하든, 동일한 조언이 적용됩니다: 테스트 이름에 테스트되는 시나리오와 예상되는 결과를 모두 포함하도록 하세요.

때로는 테스트 대상 메서드의 이름만 명시하는 것으로 충분할 수 있습니다. 특히 메서드가 간단하고 그 이름에서 동작이 명백한 단일 동작만을 가지고 있는 경우입니다.