Rust

[Rust] 테스트

dev_dean 2022. 4. 29. 09:44

작성한 코드를 배포하기 전에 테스트를 해보는 것은 매우 중요한 작업입니다.

테스트 함수의 본체는 통상적으로 다음의 세 가지 동작을 수행합니다.

  • 필요한 데이터 혹은 상태를 설정하기
  • 우리가 테스트하고 싶은 코드를 실행하기
  • 그 결과가 우리 예상대로인지 단언하기(assert)

러스트에서 테스트 함수는 테스트 속성이 주석으로 달린 함수입니다.

테스트 함수는 함수 선언 fn 전 라인에 #[test]를 추가하는 것으로 만들 수 있습니다.

테스트 함수가 작성된 후 cargo test 커맨드를 실행하면 프로젝트 내의 test속성이 달려있는 함수들을 실행하고 각 테스트 함수가 성공, 실패했는지를 나타냅니다. 

 

예시를 보겠습니다.

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}

실행 결과

테스트를 실행해보면 패스, 실패 등 테스트 결과를 나타내 주는 것을 확인할 수 있습니다.

 

이번엔 실패하는 코드를 추가해보겠습니다.

 

#[test]
    fn another() {
        panic!("Make this test fail");
    }

아까 작성했던 it_works는 패스하고 패닉을 일으키는 another는 실패했기 때문에 1 passed, 1 failed가 출력되는 것을 볼 수 있습니다. 

 

assert_eq! 이외에도 assert!, assert_ne! 등과 같은 메소드를 통해 값이 참이면 통과하고 아니라면 패닉을 일으키는 매크로를 사용하여 작성할 수 있습니다.  

 

should_panic

should_panic은 테스트를 실행했을 때 패닉을 일으켜야지만 통과하는 속성입니다. 테스트에서 #[should_panic]을 추가해서 사용할 수 있습니다. 

 

pub struct Guess {
    value: u32,
}

impl Guess {
    pub fn new(value: u32) -> 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);
    }
}

위의 코드는 Guess.value의 값이 1 미만 100 초과일 때 패닉을 일으키게 되어있습니다. greater_than_100 테스트 함수에서 Guess::new(200) 이므로 패닉을 일으키지만 #[should_panic] 속성으로 인해 테스트는 통과합니다.

running 1 test
test tests::greater_than_100 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

 

함수 결과 보여주기

테스트의 결과로써 보여주는 정보는 테스트 결과, 패닉 원인 등을 보여줄 뿐 println! 과 같은 출력내용을 보여주진 않습니다. 이를 보기 위해서는 --nocapture 속성을 추가할 수 있습니다.

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        println!("test1...");
        let result = 2 + 2;
        assert_eq!(result, 4);
    }

}

실행 결과

println! 의 내용인 "test 1..."이 출력되는 것을 확인할 수 있습니다.

 

 

일부 테스트만 실행하기

작성한 테스트 코드 중 일부분의 테스트만 실행시킬 수 있습니다.

 

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


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

    #[test]
    fn add_one() {
        println!("add_one...");
        let result = 5;
        assert_eq!(result, add(2, 3));
    }
    #[test]
    fn add_two() {
        println!("add_two...");
        let result = 10;
        assert_eq!(result, add(4, 6));
    }

}

두 숫자의 합이 같은지 확인하는 두 테스트 함수 중 하나만 실행시키기 위해서는 다음과 같이 입력합니다.

cargo test add_one

 

필터링 기능 또한 가능합니다. 테스트 함수명 앞이 add인 함수만을 실행시킬 수도 있습니다.

cargo test add

 

무시하기

#[ignore] 속성을 추가해서 테스트에 포함시키지 않을 수 있습니다.