테스트 속성
테스트 속성
다음 속성들은 테스트를 수행할 함수를 지정할 때 쓰여요. 크레이트를 "테스트" 모드로 컴파일하면 테스트 함수들과, 테스트를 실행하기 위한 테스트 하니스(test harness)를 함께 빌드해요. 테스트 모드를 켜면 test 조건부 컴파일 옵션도 함께 활성화돼요.
출처: Rust Reference
본문
test 속성
test 속성은 함수를 테스트로 실행되도록 표시해요.
#![allow(unused)]
fn main() {
pub fn add(left: u64, right: u64) -> u64 { left + right }
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
test 속성은 MetaWord 문법을 사용해요.
test 속성은 **단형(monomorphic)이고, 인자를 받지 않으며, 반환 타입이 Termination 트레이트를 구현하는 자유 함수(free function)**에만 적용할 수 있어요.
참고:
Termination트레이트를 구현하는 타입에는()와,T: Termination이고E: Debug인Result<T, E>가 포함돼요.
함수에 test를 처음 쓴 것만 효과가 있어요. 처음 이후의 사용은 rustc가 린트로 잡아요. (이것은 나중에 에러가 될 수도 있어요.)
test 속성은 표준 라이브러리 prelude에서 std::prelude::v1::test로 내보내져요. 그리고 이 함수들은 테스트 모드에서만 컴파일돼요.
참고: 테스트 모드는 rustc에
--test인자를 넘기거나cargo test를 써서 활성화할 수 있어요.
테스트 하니스는 반환된 값의 report 메서드를 호출해서, 결과 ExitCode가 성공적인 종료를 나타내는지에 따라 테스트를 passed 또는 failed로 분류해요. 구체적으로는 다음과 같아요.
()를 반환하는 테스트는 종료하고 패닉만 하지 않으면 통과해요.Result<(), E>를 반환하는 테스트는Ok(())를 반환하면 통과해요.ExitCode::SUCCESS를 반환하면 통과하고,ExitCode::FAILURE를 반환하면 실패해요.- 종료하지 않는 테스트는 통과도 실패도 아니에요.
#![allow(unused)]
fn main() {
use std::io;
fn setup_the_thing() -> io::Result<i32> { Ok(1) }
fn do_the_thing(s: &i32) -> io::Result<()> { Ok(()) }
#[test]
fn test_the_thing() -> io::Result<()> {
let state = setup_the_thing()?; // expected to succeed
do_the_thing(&state)?; // expected to succeed
Ok(())
}
}
ignore 속성
ignore 속성은 test 속성과 함께 쓰여, 테스트 하니스에게 그 함수를 테스트로 실행하지 말라고 알려줘요.
#![allow(unused)]
fn main() {
#[test]
#[ignore]
fn check_thing() {
// …
}
}
참고: rustc 테스트 하니스는
--include-ignored플래그로 무시된 테스트를 강제로 실행할 수 있게 해줘요.
ignore 속성은 MetaWord와 MetaNameValueStr 문법을 사용해요. MetaNameValueStr 형태는 그 테스트를 왜 무시하는지 이유를 지정하는 방법을 제공해요.
#![allow(unused)]
fn main() {
#[test]
#[ignore = "not yet implemented"]
fn mytest() {
// …
}
}
ignore 속성은 test 속성이 붙은 함수에만 적용할 수 있어요. 다른 위치에서 쓰면 rustc가 무시하지만 린트로 잡아요. (이것은 나중에 에러가 될 수도 있어요.) 그리고 ignore를 함수에 처음 쓴 것만 효과가 있어요.
무시된 테스트는 테스트 모드에서 여전히 컴파일되지만 실행되지는 않아요.
should_panic 속성
should_panic 속성은 그 속성이 붙은 테스트 함수가 패닉할 때만 테스트가 통과하도록 해요.
#![allow(unused)]
fn main() {
#[test]
#[should_panic(expected = "values don't match")]
fn mytest() {
assert_eq!(1, 2, "values don't match");
}
}
should_panic 속성은 다음과 같은 형태가 있어요.
MetaWord— 패닉 여부만 확인해요.
#![allow(unused)]
fn main() {
#[test]
#[should_panic]
fn mytest() { panic!("error: some message, and more"); }
}
MetaNameValueStr— 주어진 문자열이 패닉 메시지 안에 나타나야 테스트가 통과해요.
#![allow(unused)]
fn main() {
#[test]
#[should_panic = "some message"]
fn mytest() { panic!("error: some message, and more"); }
}
MetaListNameValueStr—MetaNameValueStr문법처럼, 주어진 문자열이 패닉 메시지 안에 나타나야 해요.
#![allow(unused)]
fn main() {
#[test]
#[should_panic(expected = "some message")]
fn mytest() { panic!("error: some message, and more"); }
}
should_panic 속성은 test 속성이 붙은 함수에만 적용할 수 있어요. 다른 위치에서 쓰면 rustc가 무시하지만 린트로 잡아요. (이것은 나중에 에러가 될 수도 있어요.) 그리고 처음 쓴 것만 효과가 있어요.
MetaNameValueStr 형태나 expected 키가 있는 MetaListNameValueStr 형태를 쓰면, 주어진 문자열이 패닉 메시지 어딘가에 나타나야 테스트가 통과해요.
should_panic이 붙은 테스트 함수의 반환 타입은 **()**이어야 해요.
더 알아보기
Termination트레이트와ExitCode를 살펴보면 테스트의 성공/실패 분류가 어떻게 이뤄지는지 더 명확해져요.#[test]설정을cargo test와 함께 쓰는 방식과 예외 케이스(--include-ignored)를 확인해 보세요.