Python假设组成彼此依赖的生成器

时间:2017-03-22 04:00:41

标签: python python-hypothesis

我有一个使用python Hypothesis的生成器,如下所示

@st.composite
def generate_network_fault_only(draw):
    fault = {
        "impaired": st.just(True),   # need to detect if all faults are None to switch this back.
        "limit": draw(NetworkFaultGen.generate_limit()),
        "delay": draw(NetworkFaultGen.generate_delay()),
        "loss_random": draw(NetworkFaultGen.generate_loss_random()),
        "corrupt": draw(NetworkFaultGen.generate_corrupt()),
        "duplicate": draw(NetworkFaultGen.generate_duplicate()),
        "reorder": draw(NetworkFaultGen.generate_reorder()),
        "rate": draw(NetworkFaultGen.generate_rate())
    }

    return draw(st.fixed_dictionaries(fault))

上面的每个函数都返回类似

的内容
@st.composite
def generate_reorder(draw):
    """
    This must only happen if delay is applied
    """
    return st.one_of(st.fixed_dictionaries({"percent": st.integers(min_value=0, max_value=100),
                                            "correlation": st.integers(min_value=0, max_value=100),
                                            "distance": st.integers(min_value=0)}),
                     st.none())

我在reorder值和delay值之间存在依赖关系,只有在延迟不是None的情况下才能指定该重新排序。

我不知道如何做到这一点。过滤似乎遇到了性能问题。在代码的这一点上,delay值还不是具体的值。

2 个答案:

答案 0 :(得分:1)

如果你想在每个例子中全局指定一次延迟(即每次调用你的测试函数固定为单个值,但在不同的调用之间可能有所不同),你可以使用共享来做到这一点吗? https://hypothesis.readthedocs.io/en/latest/data.html#hypothesis.strategies.shared

即。如果你做了像delay = shared(my_base_strategy,key ='network.delay')这样的事情,那么依赖于延迟的所有其他策略都可以从中获取并得到一个一致的值。

答案 1 :(得分:0)

我在reorder值和delay值之间有一个依存关系,因为只有在reorder不是delay的情况下才能指定None

您在这里:

@composite
def generate_delay(draw):
    return draw(one_of(fixed_dictionaries({"percent": integers(min_value=0, max_value=100),
                                      "correlation": integers(min_value=0, max_value=100),
                                      "distance": integers(min_value=0)}),
                  none()))

@composite
def generate_reorder(draw):
    return draw(one_of(fixed_dictionaries({"percent": integers(min_value=0, max_value=100),
                                      "correlation": integers(min_value=0, max_value=100),
                                      "distance": integers(min_value=0)}),
                  none()))

@composite
def generate_network_fault_only(draw):
    fault = {
        "impaired": just(True),   
        "delay": draw(generate_delay()),
    }

    if fault['delay']:
        fault['reorder'] = draw(generate_reorder())
    return fault


@given(network_fault=generate_network_fault_only())
def test_network_fault(network_fault):
    print(network_fault)