RUST 테스트

Alpha, Orderly·2024년 6월 2일

RUST

목록 보기
9/11

라이브러리 프로젝트 생성하기

cargo new adder --lib

내용

  • lib.rs
#[cfg(test)]
mod tests {
// 해당 함수가 테스트 함수임을 표시한다.
    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}
  • cargo test 를 통해 테스트를 실행할수 있다.
#[cfg(test)]
mod tests {
    #[test]
    fn exploration() {
        assert_eq!(2 + 2, 4);
    }

    #[test]
    fn another() {
        panic!("Make this test fail");
    }
}
  • 테스트 코드에서 panic! 매크로가 호출되면 테스트가 실패한다.

assert! 매크로

  • 테스트의 결과를 검사한다.
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
}

#[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));
    }
}
  • assert! 안에 값에 따라 panic 을 호출한다.

assert_eq!, assert_ne!

  • 각각 두개의 입력을 받아 같은가, 다른가를 확인한다.
pub fn add_two(a: i32) -> i32 {
    a + 2
}

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

    #[test]
    fn it_adds_two() {
        assert_eq!(4, add_two(2));
    }
}

커스텀 실패 메시지

pub fn greeting(name: &str) -> String {
    format!("Hello {}!", name)
}

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

     #[test]
    fn greeting_contains_name() {
        let result = greeting("Carol");
        assert!(
            result.contains("Carol"),
            "Greeting did not contain name, value was `{}`",
            result
        );
    }
}
  • assert! 에 추가한다.

should_panic

  • 반드시 panic 이 일어나야 하는 테스트를 확인한다.
  • 오히려 panic 이 일어나야 성공!
pub struct Guess {
    value: i32,
}

impl Guess {
    pub fn new(value: i32) -> Guess {
        if value < 1 || value > 100 {
            panic!("Guess value must be between 1 and 100, got {}.", value);
        }

        Guess { value }
    }
}

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

    #[test]
    #[should_panic]
    fn greater_than_100() {
        Guess::new(200);
    }
}
#[should_panic(expected = "less than or equal to 100")]
  • 패닉 문자열에 특정 부분 문자열이 포함되는지 위와 같이 검사할수도 있다.

Result<R, E> 를 이용한 예시

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() -> Result<(), String> {
        if 2 + 2 == 4 {
            Ok(())
        } else {
            Err(String::from("two plus two does not equal four"))
        }
    }
}

테스트 실행방법 제어

병렬 / 순차

$ cargo test -- --test-threads=1
  • test-threads 를 1로 정해 무조건 순차적으로 진행되게 한다.

함수출력 표시

cargo test -- --show-output
  • show_output 을 사용한다.

일부 테스트만 실행하기

cargo test one_hundred
  • 테스트 함수 이름을 전달해줄수 있다.

여러개의 테스트 실행하기

cargo test add
  • 테스트 이름의 일부만 지정시 해당 이름을 포함하는 모든 테스트가 실행된다.

일부 테스트 무시하기

#[test]
#[ignore]
fn expensive_test() {
    // code that takes an hour to run
}
  • ignore 붙히기
cargo test -- --ignored
  • 무시된 테스트만 실행할수 있다.

테스트 조직화

테스트 모듈, #[cfg(test)]

  • #[cfg(test)] 는 cargo test 명령시에만 실행되도록 러스트에게 전달한다.

비공개 함수 테스트하기

pub fn add_two(a: i32) -> i32 {
    internal_adder(a, 2)
}

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

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

    #[test]
    fn internal() {
        assert_eq!(4, internal_adder(2, 2));
    }
}
  • 그냥 하면 된다.

통합 테스트

  • 최상위 디렉터리에 tests 디렉터리를 생성한다.

  • 모듈을 가져와 테스트한다.
  • #[cfg(test)] 가 필요 없다
    • 자동으로 cargo test 시에만 컴파일 된다.

통합 테스트 서브모듈

  • 위와 같이 구성하고
use adder;

mod common;

#[test]
fn it_adds_two() {
    common::setup();
    assert_eq!(4, adder::add_two(2));
}
profile
만능 컴덕후 겸 번지 팬

0개의 댓글