【问题标题】:Strategy for dictionary with optional keys带有可选键的字典策略
【发布时间】:2018-05-30 11:06:28
【问题描述】:

目前我正在使用假设 fixed_dictionaries 策略来生成具有特定键和数据类型的字典,这些键和数据类型被认为对我的应用程序有效。我需要一种策略来生成此固定字典以及删除特定键的其他字典。或者是一个字典,其中包含一组最小的键和可选的附加键,最好是产生这些可选键的各种组合。

这是一个需要验证的 json 架构示例,带有 2 个可选字段。我想为此架构生成所有可能的有效数据。

'user_stub': {
    '_id':        {'type': 'string'},
    'username':   {'type': 'string'},
    'social':     {'type': 'string'},
    'api_name':   {'type':     'string',
                   'required': False},
    'profile_id': {'type':     'integer',
                   'required': False},
}

这是我想出的,但它是不正确的,因为它保留了键但使用 None 作为值,而我希望删除键。

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()),
})

编辑:更新的复合策略 ->

似乎最好根据返回的数据类型分离额外的可选字典,否则可能会得到值不匹配的键。

@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

【问题讨论】:

    标签: python python-3.x unit-testing testing python-hypothesis


    【解决方案1】:

    fixed_dictionaries 策略中提取所需条目,从dictionaries 策略中提取可选条目。然后通过merging他们将它们组合成一本字典。

    您可以在测试中执行此操作,也可以创建一个 composite strategy 来为您执行此操作。

    【讨论】:

    • 感谢您的快速回复,我忽略了常规字典策略,我是否正确理解它会减少为没有键的字典?这正是我需要的谢谢你
    • “我是否正确理解它会简化为没有键的字典?”这也是我的理解,但我没有尝试过,只是阅读文档。
    【解决方案2】:

    das-g 提供了一个可行的解决方案!

    另一种方法是

    fixed_dictionaries(dict(
        required=text(),
        optional=none()|text(),  # note None first, for shrinking
    )).map(
        lambda d: {k: v for k, v in d.items() if v is not None}
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-05
      • 2020-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-14
      相关资源
      最近更新 更多