python 使用st.deferred()使用具有已知键的假设生成字典值,特定值策略无法按预期工作

fdbelqdn  于 2023-11-16  发布在  Python
关注(0)|答案(1)|浏览(101)

我试图生成复杂的树一样的字典测试我的代码。字典基本上是复合类,包含结构和更简单的字段列表。
我使用hypothesis strategies deferred方法,通过lambda函数实现,我想将某个生成的“key”Map到为该“key”制定的特定策略。出于某种原因,看起来我的Map不像预期的那样工作,不同的“key”得到不同的策略。
希望你能帮忙。谢谢。
这就是我所尝试的:

name_strategy = st.text(min_size=0, max_size=10)
fanout_ref_strategy = st.lists(st.booleans())

MyClass_keys = [
    "name",
    "fanout_ref",
]  

MyClass_strategy_mapping = {
    "name": name_strategy,
    "fanout_ref": fanout_ref_strategy,
}
MyClass_value_strategy = st.deferred(lambda: MyClass_key_strategy.map(MyClass_strategy_mapping.get) | MyClass_key_strategy)
MyClass_key_strategy = st.sampled_from(MyClass_keys)
MyClass_strategy = st.dictionaries(keys=MyClass_key_strategy, values=MyClass_value_strategy)

@given(specific_dict=MyClass_strategy)
def test_specific_dictionary(specific_dict):
    # Your test code here
    print(specific_dict)

字符串
这是我看到的生成的输出:

{}
{}
{'name': text(max_size=10)}
{'fanout_ref': 'name', 'name': text(max_size=10)}
{'fanout_ref': text(max_size=10), 'name': text(max_size=10)}
{'fanout_ref': lists(booleans())}
{'fanout_ref': lists(booleans()), 'name': lists(booleans())}
{'fanout_ref': text(max_size=10), 'name': lists(booleans())}
{'name': lists(booleans()), 'fanout_ref': lists(booleans())}
{'name': lists(booleans()), 'fanout_ref': 'fanout_ref'}
{'name': text(max_size=10)}
{'name': text(max_size=10)}


我希望有字典,以'name'和'fanout_ref'作为键,以字符串和布尔值列表作为值。

lx0bsm1f

lx0bsm1f1#

使用st.fixed_dictionaries()的惯用方法是:

MyClass_strategy = st.fixed_dictionaries(
    {"name": st.text(min_size=0, max_size=10),
     "fanout_ref": st.lists(st.booleans())}
)

字符串
另外,您可能想了解为什么示例代码不起作用。
一个错误是st.dictionaries()keys=values=策略是 * 完全独立的 * -如果您需要每个键的特定值,则需要使用fixed_dictionaries(),或者为共享值策略的每组键生成并合并字典。
另一个bug是在st.deferred(lambda: MyClass_key_strategy.map(MyClass_strategy_mapping.get) | MyClass_key_strategy)中,

  • st.deferred()没有做任何事情
  • | MyClass_key_strategy说明您可以从keys策略生成值
  • .map()将策略作为值返回;要从返回的策略中提取,您需要.flatmap()。这里是文档;它看起来像= MyClass_key_strategy.flatmap(MyClass_strategy_mapping.get)

最后,st.dictionaries()并不总是生成所有可能的键-您需要为此设置min_size=2,尽管相对于fixed_dictionaries,从一组固定的键生成确实是一种糟糕的方式。

相关问题