Я хочу тщательно протестировать реализацию пересечения двух BTreeSet
с. Я могу написать:
use self::proptest::prelude::*;
proptest! {
#[test]
fn intersect_this(s1: BTreeSet<i32>, s2: BTreeSet<i32>) {
// ...
}
}
Но это имеет плохое покрытие кода, потому что код специализируется в некоторых случаях, что случайные наборы вряд ли ударить. Одним из особых случаев являются наборы, диапазоны элементов которых почти не пересекаются (один набор имеет значения <= x, другой набор имеет значения> = x). В Python с гипотезой (в которой я немного меньше новичка), я бы написал:
from hypothesis import given
from hypothesis.strategies import builds, integers, sets
from typing import Set
def touching_ranges(elements: Set[int], split: int):
return {elt for elt in elements if elt < split}.union({split}), \
{elt for elt in elements if elt > split}.union({split})
@given(builds(touching_ranges, sets(integers()), integers()))
def test_touching_ranges(sets):
s1, s2 = sets
assert len(s1.intersection(s2)) == 1
В Rust я не получил ничего, кроме как засунуть все в тело:
#[test]
fn touching(mut s1: BTreeSet<i32>, split: i32) {
let mut s2 = s1.split_off(&split);
s1.insert(split);
s2.insert(split);
prop_assert_eq!(s1.intersection(&s2).count(), 1);
}
Как сохранить преобразование произвольных значений вне тела тестового примера? Я не мог понять ни одного примера кода, который нашел для стратегий, и у Stack Overflow есть несколько вопросов, связанных с протестами.