Given an object I'm trying to construct:
from dataclasses import dataclass
@dataclass
class Thing:
thing_id: str
a: int
b: float
# other attributes
For property-based testing I need to generate lists of Thing
such that
item_id
is unique over the lista
andb
are paired values from a list[(a0, b0), (a1, b1), ...]
- from that list of
(a, b)
every value is drawn at least once
This is what I've come up with:
from hypothesis import strategies as st
def thing_lists(ab):
# ab = [(a0, b0), (a1, b1), ...]
vals = (
# list that has at least all values from ab
st.lists(st.sampled_from(ab))
.flatmap(lambda sample: st.permutations(sample + ab))
# add ids
.flatmap(
# get unique ids
lambda abs: st.lists(
st.text(), min_size=len(abs), max_size=len(abs), unique=True
# zip with abs
).map(lambda ids: [(id, *ab) for id, ab in zip(ids, abs)])
)
)
return vals.flatmap(
lambda idabs: st.tuples(
*[
st.builds(
Thing,
st.just(id),
st.just(a),
st.just(b),
# other attributes by free choice of hypothesis
)
for (id, a, b) in idabs
]
).map(list)
)
This works but it's a bit convoluted drawing a tuple and then mapping that over to a list; am I missing a different technique that's clearer about what's going on?