【问题标题】:How can I generate a boolean expression recursively in Python Hypothesis?如何在 Python 假设中递归地生成布尔表达式?
【发布时间】:2019-02-11 22:16:42
【问题描述】:

我通常是 Python 的假设库和基于属性的测试的新手。我想生成任意嵌套的策略表达式,语法如下:

((A 和 B) 或 C)

我觉得递归策略是我想要的,但我很难理解如何使用它。我拥有的代码似乎只生成一个“级别”的表达。这是我所拥有的:

import unittest

from hypothesis import given
from hypothesis.strategies import text, composite, sampled_from, characters, recursive, one_of


def policy_expressions():
    return recursive(attributes(), lambda base_strategy: one_of(base_strategy, policy_expression()))

@composite
def policy_expression(draw):
    left = draw(attributes())
    right = draw(attributes())
    gate = draw(gates())
    return u' '.join((left, gate, right))


def attributes():
    return text(min_size=1, alphabet=characters(whitelist_categories='L', max_codepoint=0x7e))


def gates():
    return sampled_from((u'or', u'and'))


class TestPolicyExpressionSpec(unittest.TestCase):

    @given(policy_expression=policy_expressions())
    def test_policy_expression_spec(self, policy_expression):
        print policy_expression
        assert policy_expression # not empty

如何使用 Hypothesis 生成任意嵌套的策略表达式?

【问题讨论】:

    标签: property-based-testing python-hypothesis


    【解决方案1】:

    我认为这可能会满足您的需求。

    import unittest
    
    from hypothesis import given
    from hypothesis.strategies import text, composite, sampled_from, characters, recursive, one_of
    
    
    def policy_expressions():
        return one_of(attributes(), policy_expression())
    
    @composite
    def policy_expression(draw):
        left = draw(policy_expressions())
        right = draw(policy_expressions())
        gate = draw(gates())
        return u' '.join((left, gate, right))
    
    
    def attributes():
        return text(min_size=1, alphabet=characters(whitelist_categories='L', max_codepoint=0x7e))
    
    
    def gates():
        return sampled_from((u'or', u'and'))
    
    
    class TestPolicyExpressionSpec(unittest.TestCase):
    
        @given(policy_expression=policy_expressions())
        def test_policy_expression_spec(self, policy_expression):
            print policy_expression
            assert policy_expression # not empty
    
    if __name__ == '__main__':
        unittest.main()
    

    【讨论】:

      【解决方案2】:

      我认为正确的方法是这样,将base_strategy 作为policy_expression 的参数:

      def policy_expressions():
          return recursive(attributes(), policy_expression)
      
      @composite
      def policy_expression(draw, base_strategy):
          left = draw(base_strategy)
          right = draw(base_strategy)
          gate = draw(gates())
          return u' '.join((left, gate, right))
      

      不使用recursive 的接受答案可能会遇到假设博客中Generating recursive data 帖子中描述的问题。

      【讨论】:

        猜你喜欢
        • 2021-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-09
        相关资源
        最近更新 更多