우아한 테크코스를 진행하면서 1번째 미션에 받은 피드백을 토대로 기록하고자 한다.
1. 랜덤 번호 테스트
첫 번째로 피드백을 받은 것은 아래와 같다
Q. “로또에 필요한 List<Integer> numbers 로또 번호들을 랜덤으로 생성하는 메소드를 테스트를 어떻게 해야 할 것인가?”
아래의 코드를 예로 들었다.

사람들은 보통 위 코드를 테스트하기 어렵다고 한다. 하지만, 어떤 문제점을 가졌기에 테스트가 어려웠을까?
코드를 보면 Random클래스로 랜덤 번호를 생성하고 있다. 단순히 랜덤한랜덤 한 요소가 있으니까 테스트가 어렵다고 말하는 것은 부족하다. 덧붙여 말하면 테스트가 어려운 이유는 랜덤 한 요소를 우리가 컨트롤하지 못하기 때문이다.
컨트롤하지 못하는 코드는 우리가 예측하지 못하고, 예측하지 못한다면 테스트 작성이 어렵다.
🙇♂️ 그렇다면 해결 방법은?
- 사용하는 Random 클래스의 seed를 고정한다.
Random 클래스는 눈으로 보기에, 랜덤으로 생성하는 것 같지만, 이것도 사람이 구현했기에 일정한 규칙이 있게 결과물을 만들어 낸다.
아래는 Random클래스의 기본 생성자 코드이다.
코드를 보면 알 수 있듯이, 매번 거의 unique한 seed를 생성하여 값을 만들어내는 것을 볼 수 있다.

하지만, 아래의 seed를 매개변수로 받는 생성자를 사용한다면 Random클래스는 일정한 값을 반환할 것이다.

위처럼 seed를 정해 일정한 값을 반환하도록 설정해놓는다면 값을 예측할 수 있어 테스트가 가능하게 된다.
하지만, 이 해결방법은 본질적인 문제를 해결하지 못한다.
그 이유는 위 Random클래스가 아닌 다른 컨트롤하지 못한는 클래스를 사용할 경우 컨트롤할 방법을 모두 알아놓기 힘들기 때문이다.
2. 인터페이스로 분리하여 외부에서 주입한다
첫 번째로 우리의 목표는 로또 번호들을 생성하는 getRandomNumbers()를 테스트하는 것이 목적이므로, 해당 메소드 내의 컨트롤 할 수 없는 것은 외부로 옮겨야 한다.
아래의 사진은 컨트롤할 수 없는 요소를 외부에서 주입받도록 고친 코드이다.

위 코드에서는 비즈니스 로직과 관련없이 단순히 랜덤 한 숫자를 생성하는 코드를 외부에서 주입받도록 하였다. 랜덤 한 숫자를 생성하는 로직은 인터페이스 구현 로직으로 추가하면 된다.
사용하는 예시는 아래와 같을 것 같다.

그렇다면 또 의문점이 들 수 있다. “정말 랜덤으로 숫자가 생성되는지 테스트하고 싶은데요?”
이 테스트는 우리의 비즈니스 로직을 테스트하는 것이 아닌 자바에서 제공하는 라이브러리가 제대로 동작하고 있는지 테스트하고 싶다는 것이다. 그것을 확인하고 싶다면 직접 Random클래스가 어떤 식으로 구현되어 있는지 코드를 보거나, 그것 또한 의문이라면 공식문서를 보면 된다. 끝!
(나는 자바에서 제공하는 라이브러리이기에 충분한 테스트를 거쳐서 제공되었다고 생각한다.)
이제 위 코드의 테스트를 작성한다면,
아래와 같이 NumberGenreator를 반환값이 일정하도록 구현하여 테스트를 진행하면 된다.

이것도 구현된 클래스에 의존했다면, 테스트하기 어려웠을 것이다. 인터페이스로 추상화된 메소드를 사용하니 테스트가 쉬워진 것 같다.
구현 객체에 의존하지 말고 추상화된 객체에 의존하라는 말이 와닿았던 문제같다.
2. 테스트 작성범위
두 번째로 피드백을 받은 것은 아래와 같다.
Q. “테스트는 어느 범위까지 작성해야 하는가?”
이전부터 정말 많은 고민이 들었던 부분이었다. 하지만 이런 부분에는 항상 명확한 정답이 없다고 들었기에 프로젝트의 인원끼리 범위를 정하여 테스트를 작성하곤 했다. 이 방법이 가장 괜찮았던 것 같다.
이번 피드백에서는 조금은 이해하기 쉽게 답을 내려주셨다.
테스트 작성 범위로 중요한 것은 신뢰도라고 하였다.
내가 작성한 코드를 믿는가? 어떻게 동작하는지 정확하게 이해하고 있는가?
예를 들어 3 * 3 = 9라는 것을 3을 3번 더하는 등의 테스트를 하지 않아도 내가 알고 있고 신뢰하기 때문에 테스트를 작성할 필요가 없다는 것이다.
그러므로 내가 구현하고 있는 코드의 도메인에 대한 이해도가 높을수록 테스트를 작성하지 않아도 괜찮고, 역량이 높을수록 테스트를 하지 않아도 괜찮다고 하였다.
하지만, 조금의 불신이 남아있다면 테스트를 작성해야 한다고 했다. 불신이 남아있지만 그것을 속이고 나는 신뢰한다며 테스트를 작성하지 않는 것은 잘못된 것이다.
Q의문점. 프로젝트를 한다면, 개인의 역량이 모두 다른데 테스트 작성을 나의 기준으로 맞춰도 되는 건가? 내가 코드를 작성했지만, 다른 사람이 내 코드를 보고 이해가 부족하다면 그 사람이 테스트를 작성해야 하는 건가?
이에 대한 답변은 아래와 같았다.
먼저 회사인 경우에는 최소한의 가이드라인이 있을 것이라고 하였다. 회사에서는 규칙을 따라야 한다고 말했다.
그렇다면 프로젝트인 경우는 모두가 납득하는 테스트를 작성해야 한다고 했다. 우리가 했던 페어프로그래밍일 경우 두 사람이 모두 납득하는 테스트를 작성해야 한다. 다른 사람이 불안하다면, 작성해야 하는 것이 맞다.
즉, 자신의 코드에 대해 다른 사람의 신뢰를 얻기 위해서는 말로 설명하기 힘드니까 테스트 코드를 작성하는 것이 가장 편하다고 한다.
그렇다면 나는 또 이런 의문이 든다……
다른 사람을 어디까지 이해시켜야 할까..? 어느 정도까지 신뢰를 시켜야 하는 걸까..?
조금은 테스트 범위에 대해 이해했지만, 아직도 어려운 것 같다.
[Reference]
- 네오의 1차 피드백
'우아한 테크코스' 카테고리의 다른 글
[LEVEL 1] 블랙잭 미션 회고 (0) | 2025.03.26 |
---|---|
[LEVEL 1] 출석 미션 회고(TDD) - (2) (0) | 2025.03.09 |
[LEVEL 1] 출석 미션 회고 - (1) (2) | 2025.02.25 |
[LEVEL 1] 로또 미션 회고 (0) | 2025.02.19 |
도메인과 서비스 그리고 개발자 마음가짐 (0) | 2025.02.16 |