2017-12-07 1 views
1

The Book에서 제안한대로 내 크레이트의 통합 테스트를 tests 디렉토리로 옮겼습니다. 이러한 테스트 중 일부는 상자 외부로 내보내고 싶지 않은 기능을 사용하지만 더 이상 통합 테스트 폴더에서 사용할 수 없습니다. 나는 비 테스트 목적으로도 이것을 사용하기 때문에 테스트 외부에서 컴파일해야한다.. 내가 pub(restricted)의 변종을 사용하여 시도했지만, 그것을 작동하게 만들 수 없습니다. 이상적으로 나는 pub(tests)과 같은 것을 갖고 싶습니다.통합 테스트 및/또는 벤치 마크 용으로 만 객체를 공개 할 수 있습니까?

디렉토리 트리 (관련 비트) :

my_crate 
|- src 
    |- parser.rs 
|- tests 
    |- parsing.rs 
|- benches 
    |- parsing.rs 

테스트/parsing.rs :

extern crate my_crate; 

use my_crate::parser::foo; 

#[test] 
fn temp() { 
    foo(); 
} 

벤치/parsing.rs :

#![feature(test)] 
extern crate test; 
extern crate my_crate; 

use test::Bencher; 
use my_crate::parser::foo; 

#[bench] 
fn temp(b: &mut Bencher) { 
    b.iter(|| { foo(); }); 
} 

나의 현재 해결 방법이다 문서 (#[doc(hidden)])에 관련 개체 pub을 표시하고 보이지 않게 설정합니다. 적절한 의도를 전달하지는 않습니다. 통합 테스트/벤치마킹 목적으로 객체를 공개 만 만들 수 있습니까?

+0

'# [cfg (test)]'을 시도해 보셨습니까? –

+0

@MatthieuM. 나는 또한 비 - 테스트 목적으로 그들을 필요합니다. – ljedrz

+0

Hum ... 'pub'에만 조건을 넣을 수 있는지 확실치 않습니다. 정의를 복제하는 것이 옵션이 아닌 것 같습니다 : x –

답변

1

통합 테스트와 단위 테스트의 차이점 중 하나는 통합 테스트가 크레이트의 "공개 API"만 테스트해야한다는 것입니다. 내부 함수에 대한 테스트는 src 트리의 함수 자체와 함께 유지하는 것이 좋습니다.

좀 더 분리 된 상태로 유지하려는 경우 테스트 할 함수가 포함 된 모듈에 테스트 하위 모듈을 사용할 수 있습니다. 비공개 부분은 하위 모듈에 사용할 수 있기 때문입니다.

tests 디렉토리의 테스트에서 여전히 내부/유닛 테스트를 원할 경우 기능 플래그를 사용하여 내부 기능의 공용 래퍼를 테스트하고 동일한 기능 플래그로 테스트를 표시 할 수 있습니다. 코드에서 이런 식으로 뭔가 :

#[cfg(feature = "testable_privates")] 
pub fn exposed_something(args) { 
    something_private(args) 
} 

이 그런 다음 시험 방법에, 당신이 가져 exposed_something를 호출 할 수 있습니다. 기능 testable_privates이 정의되어 있지 않으면 테스트를 컴파일 할 수 없습니다. 이를 해결하기 위해 기능 플래그를 사용하여 테스트를 조건 적으로 만들 수 있습니다. 또한

#[cfg(feature = "testable_privates")] 
#[test] 
fn test_something() { 
    assert_eq!(exposed_something(my_args), expected_result) 
} 

, 당신과 같이 당신의 Cargo.toml의 기능을 정의 할 필요가 있음을하기 전에 :

[features] 
testable_privates = [] 

(빈 배열이 기능은 어떤 다른 선택 종속성을 필요로하지 않는다는 것을 의미하는 것입니다) .

이제 cargo test을 실행하면 exposed_something과 test_something이 자동으로 무시되지만 cargo test --features testable_privates을 실행하면 컴파일되고 테스트됩니다.

여러분이 보시다시피, 다소 복잡해 지므로 tests에서 상자의 공개 측면을 테스트하고 그 방법 자체에 가까운 개인 테스트를 src에 두는 것이 더 좋은 아이디어라고 생각합니다.:-)

+0

래퍼 함수는 ('# [cfg (test)]'만으로도) 함수에 대한 유효한 해결책이지만'enum'이나'struct'에 대해서는 그렇지 않습니다. 'pub (specific_external_crate) '와 같은 것이 나오기 전까지는 테스트와 벤치 마크를 조금 재정렬해야 할 필요가 있습니다. :) – ljedrz

0

테스트 할 때만 존재하며 필요한 기호를 다시 내 보냅니다 공용 모듈을 추가하면됩니다. 다음과 같이 입력하십시오 :

#[cfg(test)] 
pub mod testing_parser { 
    pub use parser::foo; 
} 

그런 다음 use my_crate::testing_parser::foo 테스트하십시오.

+0

불행히도 나는'오류 [E0364] : 구문 분석은 개인적이고 다시 내보낼 수 없습니다'및'참고 : 가져온 모듈에서 구문 분석을 pub로 표시하는 것을 고려하십시오 '오류가 발생합니다. – ljedrz

+1

글쎄,'parse'를'pub'로 표시 할 수 있습니다. 개인용 모듈에 넣어두면 상자 외부에서 직접 액세스 할 수 없지만 다시 내보낼 수는 있습니다. 불행히도 통합 테스트 (즉,'tests' 폴더에있는 테스트)에 대해 아이템을 체크하고'# [cfg (test)]'항목을 사용할 수 없기 때문에'feature'를 사용해야 만 Rasmus Kaj가 제안한 것과 같이 -export 모듈. – Jmb