2016-01-07 12 views
13

パラメータに依存するテストケースを記述したいと思います。私のテストケースは各パラメータに対して実行されるべきであり、各パラメータについて成功か失敗かを調べたいと思います。Rustでパラメータ化されたテストを作成するにはどうすればよいですか?

私はJavaでそのようなことを書くことに慣れている:

@RunWith(Parameterized.class) 
public class FibonacciTest { 
    @Parameters 
    public static Collection<Object[]> data() { 
     return Arrays.asList(new Object[][] {  
       { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } 
      }); 
    } 

    private int fInput; 

    private int fExpected; 

    public FibonacciTest(int input, int expected) { 
     fInput= input; 
     fExpected= expected; 
    } 

    @Test 
    public void test() { 
     assertEquals(fExpected, Fibonacci.compute(fInput)); 
    } 
} 

どのように私は錆と似た何かを達成することができますか?シンプルなテストケースは正常に動作していますが、十分でない場合があります。

#[test] 
fn it_works() { 
    assert!(true); 
} 

注:だから、ハードコードされたマクロが十分ではないかもしれません、それらをファイルから読み込み、または入力などの特定のディレクトリなどからのすべてのファイルを使用します。私は、例えば、可能な限り柔軟なパラメータをしたいです。

答えて

15

組み込みテストフレームワークはこれをサポートしていません。

macro_rules! fib_tests { 
    ($($name:ident: $value:expr,)*) => { 
    $(
     #[test] 
     fn $name() { 
      let (input, expected) = $value; 
      assert_eq!(expected, fib(input)); 
     } 
    )* 
    } 
} 

fib_tests! { 
    fib_0: (0, 0), 
    fib_1: (1, 1), 
    fib_2: (2, 1), 
    fib_3: (3, 2), 
    fib_4: (4, 3), 
    fib_5: (5, 5), 
    fib_6: (6, 8), 
} 

これは名前fib_0fib_1& Cとの個々のテストを生成します。使用される最も一般的なアプローチは、このようなマクロを使用して、各ケースについてのテストを、生成することです。

+0

これはほとんど私が探していることです...私はディレクトリ内のファイルのリストに基づいて私のケースを生成したいと思います。おそらくマクロではうまくいかないかもしれませんが、何かを考え出すことができるかどうかがわかります。 – Peanut

7

おそらくあなたが求めているものではありませんが、TestResult::discardquickcheckとすると、ランダムに生成された入力のサブセットで関数をテストできます。

extern crate quickcheck; 

use quickcheck::{TestResult, quickcheck}; 

fn fib(n: u32) -> u32 { 
    match n { 
     0 => 0, 
     1 => 1, 
     _ => fib(n - 1) + fib(n - 2), 
    } 
} 

fn main() { 
    fn prop(n: u32) -> TestResult { 
     if n > 6 { 
      TestResult::discard() 
     } else { 
      let x = fib(n); 
      let y = fib(n + 1); 
      let z = fib(n + 2); 
      let ow_is_ow = n != 0 || x == 0; 
      let one_is_one = n != 1 || x == 1; 
      TestResult::from_bool(x + y == z && ow_is_ow && one_is_one) 
     } 
    } 
    quickcheck(prop as fn(u32) -> TestResult); 
} 

私はthis Quickcheck tutorialからフィボナッチ試験を受けました。


P.S.もちろん、マクロやクイックチェックがなくても、テストにパラメータを含めることができます。 "単純にする"。

#[test] 
fn test_fib() { 
    for &(x, y) in [(0, 0), (1, 1), (2, 1), (3, 2), (4, 3), (5, 5), (6, 8)].iter() { 
     assert_eq!(fib(x), y); 
    } 
} 
3

これは、任意の複雑なパラメータとa build scriptで(ファイルから読み込むことができるものを含む)ビルド時に知られている任意の情報に基づいてテストを構築することが可能です。

私たちは、ビルドスクリプトがどこにある貨物を教えて:ビルドスクリプトで

Cargo.toml

[package] 
name = "test" 
version = "0.1.0" 
build = "build.rs" 

、我々は我々のテストロジックを生成し、環境変数を使用してファイルに配置OUT_DIR

build.rs

fn main() { 
    let out_dir = std::env::var("OUT_DIR").unwrap(); 
    let destination = std::path::Path::new(&out_dir).join("test.rs"); 
    let mut f = std::fs::File::create(&destination).unwrap(); 

    let params = &["abc", "fooboo"]; 
    for p in params { 
     use std::io::Write; 
     write!(
      f, 
      " 
#[test] 
fn {name}() {{ 
    assert!(true); 
}}", 
      name = p 
     ).unwrap(); 
    } 
} 

最後に、テストディレクトリに、生成されたファイルのコードを含むファイルを作成します。それだ

テスト/ generated_test.rs

include!(concat!(env!("OUT_DIR"), "/test.rs")); 

$ cargo test 
    Compiling test v0.1.0 (...) 
    Finished debug [unoptimized + debuginfo] target(s) in 0.26 secs 
    Running target/debug/deps/generated_test-ce82d068f4ceb10d 

running 2 tests 
test abc ... ok 
test fooboo ... ok 
関連する問題