Skip to content

일반적인 범위에서 벗어나도록 재현하기

개발을 하다 보면 외부에서 들어오는 값을 그대로 믿기 어려운 상황이 자주 생겨요. 값이 너무 작거나 너무 커서 예상을 벗어나면, 시스템이 오작동하거나 예외가 발생할 수 있어요. 또 값 자체는 문제없지만, 경계 조건을 제대로 처리하지 않아서 에러로 이어지는 경우도 많아요.

이번에 소개할 방법은 이런 상황을 일부러 유도해서 문제를 드러내는 디버깅 기법이에요. 문제 상황을 강제로 만들 수 있기 때문에, 버그를 빠르게 재현할 수 있어요.

크게 세 가지 범위에 대해 이야기해볼게요.

  1. 경계값 설정: 정상과 비정상의 경계에서 ±1에 있는 값을 테스트해서 오류를 찾는 전략이에요.
  2. 예상 범위를 벗어나는 값 설정: 정상 범위를 벗어난 값으로 테스트해서 오류를 찾는 전략이에요.
  3. 극단적인 값 설정: 아주 큰 값이나 아주 작은 값으로 테스트해서 오류를 찾는 전략이에요.

경계값 설정

먼저 경계값 설정에 대해 이야기해볼게요. 경계값 설정 테스트는 정상 입력의 양 끝 지점을 중심으로 발생할 수 있는 문제를 발견하는 데 효과적인 전략이에요. 주로 범위의 끝에 위치한 값들, 즉 경계에서 ±1 정도의 값을 넣어 테스트해요.

예를 들어, 아래처럼 이름을 최대 10자까지 입력할 수 있는 입력창이 있다고 할 때 다음 세 가지 경우를 테스트하는 게 좋아요.

  • 입력 0자 (빈 문자열)
  • 정확히 10자
  • 11자 (제한 초과)
tsx
function NameInput() {
  const [name, setName] = React.useState("");

  const handleChange = (e) => {
    if (e.target.value.length > 10) return;
    setName(e.target.value);
  };

  return (
    <>
      <input value={name} onChange={handleChange} />
      <p>{name.length}/10</p>
    </>
  );
}

예상 범위를 벗어나는 값 설정

이번에는 예상 범위를 벗어나는 값 설정으로 테스트하는 방법을 소개할게요. 코드가 정상적으로 작동하리라 가정하고 넘어가기 쉬운 부분이지만, 실제 사용자 입력은 언제든 예외적인 값을 포함할 수 있어요.

예를 들어, 양수만 입력된다고 가정하고 음수 처리를 빠뜨리는 경우가 있어요. 아래 코드는 가격이 음수일 때 에러를 발생시키도록 처리한 예시예요.

tsx
function calculateDiscount(price) {
  if (price < 0) {
    throw new Error("가격은 음수일 수 없습니다");
  }
  return price > 10000 ? 0.2 : 0.1;
}

calculateDiscount(-500);

극단적인 값 설정

숫자의 최대값, 최소값 같은 극단적인 값 설정으로도 테스트해볼 수 있어요. 이런 값을 테스트하면, 숫자 오버플로우(overflow)나 정밀도 손실 같은 문제가 발생하는지 확인할 수 있어요.

tsx
const numbers = [Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER];
calculateDiscount(Math.max(...numbers));

자바스크립트에서 Number.MAX_SAFE_INTEGER 범위를 벗어나면 끝자리 정밀도가 깨져 값이 바뀌는 현상이 발생할 수 있어요.

tsx
const x = Number.MAX_SAFE_INTEGER + 1;
const y = Number.MAX_SAFE_INTEGER + 2;

console.log(Number.MAX_SAFE_INTEGER);
// Output: 9007199254740991

console.log(x);
// Output: 9007199254740992

console.log(y);
// Output: 9007199254740992

"이 값은 절대 안 들어올 거야"라고 생각하는 순간, 버그는 그 틈을 타고 들어와요. 예상보다 작은 값이나 큰 값을 미리 테스트해두면, 에러를 미리 차단하고 더 튼튼한 시스템을 만들 수 있어요.