[Rust 시리즈 17편] 테스트와 문서화

English version

이번 글에서 다룰 내용

테스트와 문서화는 코드 신뢰도를 높이는 가장 직접적인 방법입니다. cargo test 명령 흐름, #[test] 함수 작성법, 문서 주석으로 예제를 남기는 법을 차근차근 따라갑니다.

cargo test 살펴보기

Rust 프로젝트를 생성했다면 별도 설정 없이도 cargo test를 실행할 수 있습니다.

cargo new calculator
cd calculator
cargo test

기본 템플릿에는 자동으로 하나의 예시 테스트가 들어 있어서, 위 명령을 실행하면 바로 테스트 러너가 동작하는 것을 확인할 수 있습니다. 실패 메시지가 아니라면 러닝타임, 테스트 개수, 패키지 이름이 출력됩니다.

#[test] 함수 작성하기

src/lib.rs에 기능 함수를 추가하고 함께 테스트를 작성해 보겠습니다.

pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn adds_two_numbers() {
        assert_eq!(add(2, 3), 5);
    }
}
  • #[cfg(test)] 모듈은 cargo test일 때만 컴파일되어 바이너리 크기를 줄입니다.
  • #[test] 속성이 붙은 함수는 반환값이 없어도 되며, 패닉이 발생하면 실패로 기록됩니다.

assert_eq! 매크로는 기대값과 실제 값을 비교합니다. 실패 시 양쪽 값과 소스 위치를 함께 보여 주므로 디버깅이 빠릅니다.

문서 주석 안 코드도 사실상 테스트의 한 형태입니다. 즉, 문서 예제는 "설명"이면서 동시에 "실제로 돌아가는 검증 코드"라는 점이 Rust의 큰 장점입니다.

경계 조건 테스트

한 함수에 대한 여러 테스트를 작성할 때는 명확한 시나리오 이름을 붙여야 이후 리팩토링에서도 의미가 유지됩니다.

#[test]
fn add_handles_negative() {
    assert_eq!(add(-3, 1), -2);
}

#[test]
fn add_with_zero_returns_other() {
    assert_eq!(add(0, 7), 7);
}

테스트 이름만 보고 어떤 입력을 검증하는지 유추할 수 있도록 작성하면 나중에 실패 로그만 보고도 상황을 이해할 수 있습니다.

문서 주석과 예제

앞으로 만들 라이브러리가 다른 사람에게도 쓰이려면 문서 주석(///)이 필요합니다. 문서 주석 안에 ``` 코드 블록을 넣으면, cargo test가 해당 예제를 직접 실행해 검증합니다.

/// 두 정수의 합을 반환합니다.
///
/// # Examples
///
/// ```
/// use calculator::add;
/// assert_eq!(add(2, 2), 4);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

도큐먼트 테스트는 실제 사용 예제를 유지보수하는 데 큰 도움이 됩니다. 코드가 바뀌면 주석 속 예제도 함께 실패하므로, 문서와 구현의 괴리가 줄어듭니다.

cargo doc --open

작성한 문서를 HTML로 미리보기 하려면 다음 명령을 실행합니다.

cargo doc --open

이 명령은 프로젝트의 공개 API를 문서화하고, 시스템 기본 브라우저로 문서를 열어 줍니다. pub이 아닌 항목은 기본적으로 표시되지 않으므로 공개 범위를 의도적으로 관리해야 합니다.

자주 막히는 부분

  • #[test] 함수에 인자를 선언하면 컴파일 오류가 납니다. 테스트 함수는 인자를 받을 수 없습니다.
  • 비동기 테스트를 작성하려면 #[tokio::test]와 같은 별도 런타임이 필요합니다. 이번 편에서는 동기 테스트만 다룹니다.
  • cargo test -- --nocapture를 사용해야 println! 출력이 보입니다. 기본 설정은 테스트 통과 시 출력을 숨깁니다.
  • 출력 순서가 섞여 헷갈리면 cargo test -- --test-threads=1로 테스트를 하나씩 순차 실행할 수 있습니다.

CodeSandbox로 이어서 실습하기

아래 샌드박스는 CodeSandbox의 Rust starter입니다. 이번 글의 핵심 코드를 src/main.rs에 옮기고, cargo checkcargo run 결과를 나란히 보면서 컴파일 메시지와 실행 출력을 비교해 보세요.

Live Practice

Rust Practice Sandbox

CodeSandbox

Run the starter project in CodeSandbox, compare it with the lesson code, and keep experimenting.

Rust startercargoterminal
  1. starter를 fork한 뒤 src/main.rs를 연다
  2. 본문 예제를 붙여 넣고 cargo check와 cargo run을 차례로 실행한다
  3. 타입, 값, 참조 흐름을 바꿔 컴파일 피드백과 출력 차이를 비교한다

Rust 실습은 브라우저 미리보기보다 터미널 피드백이 더 중요합니다. 여러 파일 구조나 추가 crate가 필요한 예제는 파일 배치를 조금 더 손봐야 할 수 있습니다.

연습 과제

  1. subtract 함수를 추가하고 양수·음수 입력 각각을 검사하는 테스트 2개를 작성해 보세요.
  2. cargo test add_handles_negative -- --nocapture처럼 특정 테스트만 실행하고 로그를 확인해 보세요.
  3. 문서 주석 # Panics 절을 추가해 언제 패닉이 발생하는지 설명해 보세요.

마무리

테스트와 문서 주석은 러스트 코드베이스를 신뢰할 수 있게 만드는 첫 장치입니다. cargo test는 별도 설정 없이도 실행되며, /// 주석 안 예제는 실제 테스트로 돌아갑니다. 다음 편에서는 이러한 코드를 여러 스레드에서 안전하게 실행하는 동시성 기초를 다룹니다.

💬 댓글

이 글에 대한 의견을 남겨주세요