소프트웨어 개발에서 비결정적 코드(Non-deterministic Code)는 동일한 입력에도 실행할 때마다 다른 결과를 내놓을 수 있는 코드를 의미한다. 이는 테스트나 디버깅을 어렵게 만들고, 예상치 못한 동작을 초래할 가능성이 있다. 그래서 비결정적 코드를 결정적(Deterministic)으로 만들어야 할 필요성이 있다.
이번 글에서는 비결정적 코드의 문제를 해결하는 방법을 간단한 예시와 함께 살펴보겠다.
1. 비결정적 코드의 문제점
비결정적 코드는 다음과 같은 문제를 일으킬 수 있다.
- 테스트 불안정성: 동일한 테스트가 실행 환경이나 시간에 따라 다른 결과를 낼 수 있다.
- 디버깅 어려움: 문제가 발생했을 때 원인을 재현하기 어렵다.
- 예측 불가능한 동작: 의도하지 않은 동작이 발생할 가능성이 높아진다.
2. 예시를 통해 살펴보는 해결 방법
(1) 난수 생성(Randomness)
비결정적 코드
이 코드는 실행할 때마다 다른 난수를 출력한다. 테스트 중에 동일한 값이 나오지 않으므로 디버깅과 테스트가 어려워질 수 있다.
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random random = new Random();
int randomNumber = random.nextInt(100); // 0부터 99 사이의 난수
System.out.println("Random Number: " + randomNumber);
}
}
결정적 코드
고정된 시드 값을 사용하면 항상 동일한 결과를 얻을 수 있다. 이 방식은 테스트와 디버깅을 훨씬 더 쉽게 만들어준다.
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random random = new Random(42); // 고정된 시드 값
int randomNumber = random.nextInt(100);
System.out.println("Random Number: " + randomNumber);
}
}
(2) 현재 시간 사용
비결정적 코드
LocalDateTime.now()를 직접 호출하면 실행 시점마다 다른 결과를 출력한다. 이 코드는 테스트 시마다 값이 달라져 예측하기 어렵다.
import java.time.LocalDateTime;
public class TimePrinter {
public String formatTime() {
return "Current Time: " + LocalDateTime.now();
}
}
결정적 코드
시간 값을 외부에서 주입받도록 수정하면, 특정 입력에 대해 항상 동일한 출력이 나온다. 이를 통해 시간에 의존하지 않는 테스트가 가능해진다.
import java.time.LocalDateTime;
public class TimePrinter {
public String formatTime(LocalDateTime dateTime) {
return "Formatted Time: " + dateTime.toString();
}
}
3. 비결정적 코드를 결정적 코드로 만드는 일반적인 원칙
- 외부 의존성 주입: 현재 시간, 난수 생성기 등 외부 의존성을 직접 코드 내부에서 생성하지 말고 주입받도록 설계한다.
- Mock 활용: 외부 시스템 호출을 Mocking하여 테스트 환경을 제어한다.
- 테스트 격리: 테스트는 서로 영향을 미치지 않도록 독립적으로 실행해야 한다.
4. 테스트 코드에서 비결정적 코드를 제어하기
비결정적 코드를 결정적으로 만드는 것은 특히 테스트 코드에서 중요하다. 예를 들어, 네트워크 연결, 파일 입출력, 데이터베이스 접근 등 외부 시스템에 의존하는 코드를 Mocking하거나 Stub으로 대체하면, 테스트의 안정성과 신뢰성을 크게 높일 수 있다.
5. 마무리
비결정적 코드를 결정적으로 만드는 것은 디버깅과 테스트 효율성을 높이는 중요한 실천이다. 난수, 시간, 외부 의존성과 같은 비결정적 요소를 다룰 때는 항상 고정된 시드 값, 외부 의존성 주입 등의 원칙을 적용해보자. 이는 코드 품질을 한 단계 높이는 데 크게 기여할 것이다.
'배움 조각 (Computer Science)' 카테고리의 다른 글
Exception 사용 팁: 효과적으로 예외를 다루는 방법 (2) | 2024.11.19 |
---|---|
[구글엔지니어는 이렇게 일한다] 테스트 크기와 범위 (0) | 2023.12.22 |
[구글엔지니어는 이렇게 일한다] 테스트 코드가 주는 혜택 (0) | 2023.12.12 |