IT Best Practise/Rust

11. 테스팅

GilliLab IT 2024. 11. 7. 19:21
728x90
반응형

11장. 테스팅

Rust는 내장된 테스팅 프레임워크를 제공하여 코드의 정확성을 검증할 수 있습니다. Rust의 테스팅 프레임워크는 단위 테스트, 통합 테스트, 문서화 테스트를 지원합니다.

단위 테스트 (Unit Tests)

단위 테스트는 개별 함수나 모듈을 테스트하여 올바르게 동작하는지 확인합니다. 단위 테스트는 일반적으로 테스트할 코드와 같은 파일에 작성되며, #[cfg(test)] 어트리뷰트를 사용하여 테스트 모듈을 정의합니다.

단위 테스트 예제

// src/lib.rs

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

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

    #[test]
    fn test_add() {
        assert_eq!(add(2, 3), 5);
    }

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

위 예제에서 add 함수는 두 정수를 더하는 함수입니다. tests 모듈 내에 두 개의 단위 테스트를 정의하여 add 함수가 올바르게 동작하는지 확인합니다. #[test] 어트리뷰트를 사용하여 테스트 함수를 표시합니다.

통합 테스트 (Integration Tests)

통합 테스트는 여러 모듈이 함께 동작하는지 확인합니다. 통합 테스트는 tests 디렉토리에 별도의 파일로 작성됩니다.

통합 테스트 예제

// src/lib.rs

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

// tests/integration_test.rs

extern crate my_crate;

use my_crate::add;

#[test]
fn test_add_integration() {
    assert_eq!(add(2, 3), 5);
}

위 예제에서 add 함수는 src/lib.rs 파일에 정의되어 있습니다. tests/integration_test.rs 파일에 통합 테스트를 작성하여 add 함수가 올바르게 동작하는지 확인합니다. extern crate를 사용하여 라이브러리를 가져오고, use를 사용하여 add 함수를 가져옵니다.

문서화 테스트 (Documentation Tests)

문서화 테스트는 코드 예제에 포함된 주석을 테스트합니다. 문서화 테스트는 주로 API 문서에 포함된 예제가 올바르게 동작하는지 확인하는 데 사용됩니다.

문서화 테스트 예제

/// Adds two integers.
///
/// # Examples
///
/// ```
/// let result = my_crate::add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

위 예제에서 add 함수의 문서 주석에 포함된 코드 블록은 문서화 테스트로 사용됩니다. cargo test 명령을 실행하면 이 코드 블록이 실제로 실행되어 올바르게 동작하는지 확인합니다.

테스트 실행

테스트를 실행하려면 cargo test 명령을 사용합니다. 이 명령은 프로젝트의 모든 테스트를 실행하고 결과를 출력합니다.

cargo test

위 명령을 실행하면 단위 테스트, 통합 테스트, 문서화 테스트가 모두 실행됩니다.

Rust의 테스팅 프레임워크를 사용하면 코드의 정확성을 검증하고, 버그를 조기에 발견하여 안정적인 소프트웨어를 개발할 수 있습니다.

테스팅 요약

  • 테스트 작성법

    • #[test] 어트리뷰트 사용하기
    • 테스트 함수 작성 규칙과 명명 규칙
    • 테스트 실패 메시지 커스터마이징
    #[test]
    fn greeting_contains_name() {
        let result = greeting("Carol");
        assert!(
            result.contains("Carol"),
            "인사말에 이름이 포함되어 있지 않습니다. 값: {}",
            result
        );
    }
  • 단위 테스트

    • 모듈 내부 테스트 작성과 cfg(test) 속성
    • private 함수 테스트하기
    • 테스트 조직화와 공유 설정
    #[cfg(test)]
    mod tests {
        use super::*;
    
        #[test]
        fn larger_can_hold_smaller() {
            let larger = Rectangle {
                width: 8,
                height: 7,
            };
            let smaller = Rectangle {
                width: 5,
                height: 1,
            };
            assert!(larger.can_hold(&smaller));
        }
    }
  • 통합 테스트

    • tests 디렉토리 구성
    • 외부 API 테스트 방법
    • 서브모듈 테스트
    // tests/integration_test.rs
    use adder;
    
    mod common;
    
    #[test]
    fn it_adds_two() {
        common::setup();
        assert_eq!(4, adder::add_two(2));
    }
  • 테스트 구성

    • 테스트 모듈과 #[cfg(test)] 사용
    • 테스트 헬퍼 함수 작성
    • 공통 테스트 설정과 해제
    pub struct Guess {
        value: i32,
    }
    
    impl Guess {
        pub fn new(value: i32) -> Guess {
            if value < 1 || value > 100 {
                panic!("값은 1과 100 사이여야 합니다.");
            }
            Guess { value }
        }
    }
    
    #[cfg(test)]
    mod tests {
        use super::*;
    
        #[test]
        #[should_panic(expected = "값은 1과 100 사이여야 합니다")]
        fn greater_than_100() {
            Guess::new(200);
        }
    }
  • 테스트 실행 제어

    • cargo test 옵션 활용
      • --test-threads=1: 병렬 실행 제어
      • --show-output: 성공한 테스트의 출력 표시
      • --ignored: 무시된 테스트만 실행
    • 테스트 필터링
    # 특정 테스트만 실행
    cargo test it_works
    
    # 여러 테스트 실행
    cargo test add
    
    # 무시된 테스트 실행
    cargo test -- --ignored
728x90
반응형