I want to generate a list of dicts where all the dicts have the same set of keys.
import json
import hypothesis
from hypothesis import strategies as st
@st.composite
def list_of_dicts_with_keys_matching(draw,dicts=st.dictionaries(st.text(), st.text())):
mapping = draw(dicts)
return st.lists(st.fixed_dictionaries(mapping))
@hypothesis.given(list_of_dicts_with_keys_matching())
def test_simple_json_strategy(obj):
dumped = json.dumps(obj)
assert isinstance(obj, list)
assert json.dumps(json.loads(dumped)) == dumped
TypeError: Object of type LazyStrategy is not JSON serializable
How can I fix this?
Edit: Second attempt:
import string
import pytest
import hypothesis
import hypothesis.strategies as st
@st.composite
def list_of_dicts_with_keys_matching(draw, keys=st.text(), values=st.text()):
shared_keys = draw(st.lists(keys, min_size=3))
return draw(st.lists(st.dictionaries(st.sampled_from(shared_keys), values, min_size=1)))
@hypothesis.given(list_of_dicts_with_keys_matching())
def test_shared_keys(dicts):
assert len({frozenset(d.keys()) for d in dicts}) in [0, 1]
# Falsifying example: test_shared_keys(dicts=[{'': ''}, {'0': ''}])
You are missing the draw(...)
in return draw(st.lists(st.fixed_dictionaries(mapping)))
.
However, this will lead you to the second problem - st.fixed_dictionaries
takes a mapping of keys to strategies for values , but mapping
here will be a Dict[str, str]
. Perhaps:
@st.composite
def list_of_dicts_with_keys_matching(draw, keys=st.text(), values=st.text()):
shared_keys = draw(st.lists(keys, min_size=3))
return draw(st.lists(st.dictionaries(st.sampled_from(shared_keys), values)))
Update: the snippet above will draw varied keys from a shared set. For identical keys for all dicts, I'd write:
@st.composite
def list_of_dicts_with_keys_matching(draw, keys=st.text(), values=st.text()):
shared_keys = draw(st.sets(keys))
return draw(st.lists(st.fixed_dictionaries(
{k: values for k in shared_keys}
)))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.