支撑测试:生成向量向量的策略

我想用proptest生成DAG。我选择的算法为this。我已经在下面编写了简单的算法-但我需要帮助将其转换为 protest strategy

与以下代码相同但不使用随机数生成器的策略需要看起来像什么? (不用说,随机数生成器对于基于属性的测试不利。)

没有抗议策略的标准代码: (https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2de4a757a96d123bf83b5157e0633d33

use rand::Rng;

fn main() {
    println!("{:?}",random_vec_of_vec());
}

fn random_vec_of_vec() -> Vec<Vec<u16>> {
    const N: u16 = 30;
    const K: usize = 3;
    let mut rng = rand::thread_rng();

    let length: u16 = rng.gen_range(0,N);
    let mut outer = vec![];
    for index in 1..length {
        let mut inner = vec![0u16; rng.gen_range(0,K)];
        for e in &mut inner {
            *e = rng.gen_range(0,index);
        }
        // De-duplicate elements. Particularly a problem with `index < K`.
        inner.sort();
        inner.dedup();
        outer.push(inner);
    }
    outer
}

以前的工作

我尝试使用vec函数,但是我需要嵌套两个vec函数。而且,内部vec函数只能生成直到外部向量中的索引为止的值。

use proptest::collection::vec;
// INDEX should be the value of the position of the inner vector
// in the outer vector. How could the be found?
let strategy = vec(vec(1..INDEX,0..K),0..N);

index方法没有帮助,因为正确的大小仍然未知。

iCMS 回答:支撑测试:生成向量向量的策略

一种解决方法是用策略替换每个rng.gen_range()调用。然后,嵌套策略必须与prop_flat_map相关联。

在下面的代码中,我替换了我的模式 let length = rng.gen_range(0,N); for i in 1..length { .. },带有一个新功能vec_from_length(length: usize),该函数将返回一个策略。

#[cfg(test)]
mod tests {
    use super::*;
    use proptest::collection::hash_set;
    use proptest::prelude::*;
    use std::collections::HashSet;

    proptest! {
        #[test]
        fn meaningless_test(v in vec_of_vec()) {
            let s = sum(&v);  // sum of the sum of all vectors.
            prop_assert!(s < 15);
        }
    }

    fn vec_of_vec() -> impl Strategy<Value = Vec<Vec<u16>>> {
        const N: u16 = 10;

        let length = 0..N;
        length.prop_flat_map(vec_from_length).prop_map(convert)
    }

    fn vec_from_length(length: u16) -> impl Strategy<Value = Vec<HashSet<u16>>> {
        const K: usize = 5;
        let mut result = vec![];
        for index in 1..length {
            // Using a hash_set instead of vec because the elements should be unique.
            let inner = hash_set(0..index,0..K);

            result.push(inner);
        }
        result
    }

    /// Convert Vec<HashSet<T>> to Vec<Vec<T>>
    fn convert(input: Vec<HashSet<u16>>) -> Vec<Vec<u16>> {
        let mut output = vec![];
        for inner in input {
            output.push(inner.into_iter().collect())
        }
        output
    }
}

另一件事:impl Strategy<Value=Vec<T>>可以从vec函数(矢量的策略)或策略的矢量中生成!在上面的代码中,我是通过将resultpush hash_set(..)(这是一种策略)一起实现的。因此,类型类似于Vec<Strategy<T>>而不是Strategy<Vec<T>>(古怪的:策略不是类型)。

本文链接:https://www.f2er.com/1562329.html

大家都在问