Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

14. 테스트 및 벤치마킹 패턴 🟢

학습 목표:

  • Rust의 세 가지 테스트 계층: 단위(Unit), 통합(Integration), 문서(Doc) 테스트를 마스터합니다.
  • **속성 기반 테스트(Property-based testing)**인 proptest로 예상치 못한 엣지 케이스를 찾아냅니다.
  • Criterion 라이브러리를 사용해 통계적으로 신뢰할 수 있는 성능 벤치마킹을 수행합니다.
  • 무거운 프레임워크 없이 트레이트 기반의 모킹(Mocking) 전략을 구축합니다.

세 가지 테스트 계층

Rust는 언어 차원에서 강력한 테스트 도구를 제공합니다.

  1. 단위 테스트(Unit Tests): 비즈니스 로직과 같은 파일에 작성하며, mod tests#[cfg(test)]를 사용합니다. 비공개 함수도 테스트할 수 있습니다.
  2. 통합 테스트(Integration Tests): tests/ 디렉토리에 위치하며, 라이브러리의 공개 API만 테스트합니다. 외부 사용자의 관점에서 테스트를 진행합니다.
  3. 문서 테스트(Doc Tests): 문서 주석(///) 내의 코드 예제를 실제로 실행합니다. 문서와 실제 코드가 일치함을 보장합니다.

속성 기반 테스트 (Proptest)

특정 입력값 하나하나를 테스트하는 대신, "임의의 입력에 대해 항상 만족해야 하는 성질(Property)"을 테스트합니다.

#![allow(unused)]
fn main() {
proptest! {
    #[test]
    fn test_reverse_twice_is_identity(v in prop::collection::vec(any::<i32>(), 0..100)) {
        // 성질: 두 번 뒤집으면 원래와 같아야 함
        assert_eq!(reverse(&reverse(&v)), v);
    }
}
}

장점: 수백 개의 랜덤한 입력을 자동으로 생성하며, 실패 시 최소한의 재현 케이스로 데이터를 축소(Shrink)해 줍니다.


Criterion을 이용한 정밀 벤치마킹

cargo bench보다 훨씬 정밀한 성능 측정이 가능합니다. 통계적 유의미함을 검사하고 HTML 리포트를 생성해 줍니다.

#![allow(unused)]
fn main() {
fn bench_fibonacci(c: &mut Criterion) {
    c.bench_function("fibonacci 20", |b| b.iter(|| fibonacci(black_box(20))));
}
}

: black_box를 사용하여 컴파일러가 벤치마크 함수를 아예 생략하거나 상수화해 버리는 과도한 최적화를 방지하세요.


프레임워크 없는 모킹(Mocking) 전략

Rust에서는 복잡한 모킹 프레임워크 대신 트레이트 기반의 의존성 주입을 권장합니다.

#![allow(unused)]
fn main() {
trait Clock { fn now(&self) -> Instant; }

// 실무용 구현체
struct RealClock;
// 테스트용 가짜 구현체
struct MockClock { fixed_time: Instant }
}

이러면 테스트할 구조체에 Clock 트레이트만 요구하면 실제 환경과 테스트 환경에서 각각 다른 객체를 넣어줄 수 있습니다.


📝 연습 문제: 속성 기반 테스트 실습 ★★ (~25분)

SortedVec<T>라는 항상 정렬 상태를 유지하는 래퍼를 만드세요. proptest를 사용하여 다음 성질들을 검증해 보세요:

  1. 어떤 값을 넣어도 내부 벡터는 항상 정렬되어 있는가?
  2. contains() 결과가 표준 Vec::contains()와 일치하는가?
  3. 삽입한 만큼 길이가 늘어났는가?

📌 요약

  • 문서 테스트를 적극 활용해 살아있는 문서를 만드세요.
  • 복잡한 엣지 케이스가 걱정된다면 속성 기반 테스트가 정답입니다.
  • Criterion 리포트를 통해 성능 변화를 시각적으로 추적하세요.
  • 모킹보다는 트레이트 설계를 통해 테스트 가능한 구조를 만드세요.