当前位置:  开发笔记 > 后端 > 正文

如何在Rust中创建参数化测试?

如何解决《如何在Rust中创建参数化测试?》经验,为你挑选了2个好方法。

我想编写依赖于参数的测试用例.我应该为每个参数执行我的测试用例,我想看看每个参数是成功还是失败.

我习惯在Java中写这样的东西:

@RunWith(Parameterized.class)
public class FibonacciTest {
    @Parameters
    public static Collection 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));
    }
}

我怎样才能实现与Rust相似的东西?简单的测试用例工作正常,但有些情况下还不够.

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

注意:我希望参数尽可能灵活,例如:从文件中读取它们,或者使用某个目录中的所有文件作为输入等.因此,硬编码的宏可能还不够.



1> Chris Morgan..:

内置的测试框架不支持这个; 最常用的方法是使用宏为每个案例生成一个测试,如下所示:

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_0,fib_1,&C.



2> ArtemGr..:

可能不是你问过相当的东西,但通过TestResult::discard与快速检查可以测试使用随机生成的输入子集的功能.

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);
}

我从这个Quickcheck教程中学习了Fibonacci测试.


PS当然,即使没有宏和快速检查,您仍然可以在测试中包含参数."把事情简单化".

#[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);
    }
}

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有