Currently I am using hypothesis fixed_dictionaries strategy to generate a dictionary with specific keys and data types that are considered valid for my application. I need a strategy which produces this fixed dictionary as well as others with specific keys removed. Or a dictionary with a certain minimal set of keys with optional additional ones, preferably in a way that produces the various combinations of these optional keys.
This is an example of the json schema that needs to be validated, with the 2 optional fields. I'd like to generate all possible valid data for this schema.
'user_stub': {
'_id': {'type': 'string'},
'username': {'type': 'string'},
'social': {'type': 'string'},
'api_name': {'type': 'string',
'required': False},
'profile_id': {'type': 'integer',
'required': False},
}
This is what I came up with but it is incorrect because it retains the keys but uses None as the value, and I want instead that the keys are removed.
return st.fixed_dictionaries({
'_id': st.text(),
'username': st.text(),
'social': st.text(),
'api_name': st.one_of(st.none(),
st.text()),
'profile_id': st.one_of(st.none(),
st.integers()),
})
EDIT: updated composite strategy ->
Seems like it would be best to separate the additional optional dictionaries based on the type of data being returned, otherwise might get keys with mismatched values.
@st.composite
def generate_data(draw):
base_data = st.fixed_dictionaries({
'_id': st.text(),
'username': st.text(),
'social': st.text(),
})
optional_strs = st.dictionaries(
keys=st.just('api_name'),
values=st.text()
)
optional_ints = st.dictionaries(
keys=st.just('profile_id'),
values=st.integers()
)
b = draw(base_data)
s = draw(optional_strs)
i = draw(optional_ints)
return {**b, **s, **i} # noice
Draw from a fixed_dictionaries strategy for the required entries and from a dictionaries strategy for the optional ones. Then combine them into one dictionary by merging them.
You can either do that in your test, or create a composite strategy that does that for you.