Search code examples
pythonpython-hypothesis

Hypothesis tests: how to sample_from values from another strategy?


I have to test some function with a sample data:

data = [
    [[10, 20, 30], 10],
    [[20, 30], 20],
    [[40], 30],
]

where the first element in each row, lists, contains N=(1 to 5) random integer elements generated via:

st.lists(
          st.integers(min_value=10),
          min_size=2,
          max_size=5,
          unique=True)

Second elements in each row contain a random sample from a set of all unique integers from all generated lists.

So for my data example:

  • lists contains values from unique set (10,20,30,40);
  • second elements in each row contain a random integer sample from that set;

How do I implement such a strategy with Hypothesis testing framework?

This one does not works:

int_list = st.integers(min_value=10)

@given(st.lists(
    elements=st.tuples(
        int_list, 
        st.sampled_from(int_list))

Solution

  • Check out the docs on adapting strategies - you can do this with .flatmap(...), but defining a custom strategy with @composite might be simpler.

    # With flatmap
    elem_strat = lists(
        integers(), min_size=2, max_size=5, unique=True
    ).flatmap(
        lambda xs: tuples(just(xs), sampled_from(xs)).map(list)
    )
    
    # With @composite
    @composite
    def elem_strat_func(draw):
        xs = draw(lists(
            integers(), min_size=2, max_size=5, unique=True
        )
        an_int = draw(sampled_from(xs))
        return [xs, an_int]
    elem_strat = elem_strat_func()
    
    # then use either as
    @given(lists(elem_strat))
    def test_something(xs): ...