如何创建使用 `builds()` 的可配置自定义假设策略?
How can I create configurable custom hypothesis strategies which use `builds()`?
我使用 builds()
and @composite
(the design is inspired by this example from the docs) 创建了自定义假设策略。这些策略的设计类似于下面的伪代码:
# strategies.py
from hypothesis.strategies import builds, composite, draw, floats, integers
class SutConfiguration:
""" Data which represents the configuration of the system under test. """
def __init__(self, integer, float):
self.integer = integer
self.float = float
# custom strategy which uses builds()
SutConfigurationStrategy = builds(
SutConfiguration,
integer=integers(min_value=APP_SPECIFIC_INT_MIN, max_value=APP_SPECIFIC_INT_MAX),
float=floats(min_value=APP_SPECIFIC_FLOAT_MIN, max_value=APP_SPECIFIC_FLOAT_MAX),
)
@composite
def overall_test_configuration(draw, sut_st=SutConfigurationStrategy, env_st=SutEnvironmentStrategy):
"""Custom strategy which uses draw."""
sut_config = draw(sut_st)
env_config = draw(env_st)
return (sut_config, rc_stereomatching_config, env_config)
该策略照常使用,例如使用 unittest
作为测试运行器:
# test.py
import unittest
from <package>.strategies import overall_test_configuration
class TestSut(unittest.TestCase):
"""Class containing several tests for the system under test."""
@given(overall_test_configuration())
def test_something():
"""Test which uses overall_test_configuration"""
...
现在我想让策略可配置到实际应用程序来定义例如min_value
in integers(min_value=APP_SPECIFIC_INT_MIN, ...)
定义测试函数时。这可以通过 done here 等参数为 @composite
策略完成。但是如何使使用 builds()
的策略可配置?
您可以定义一个函数,returns 像任何其他策略一样的策略:
def some_custom_strategy(a, b):
return builds(foo, bar(a, b))
当你有额外的参数时,这就是 composite 发生的所有事情 - composite 正在定义一个函数,returns 一个策略,这些额外的参数通过函数传递给底层装饰函数。
应用于上述伪代码的解决方案,例如SUT 配置 SutConfigurationStrategy
可配置的整数值如下所示:
# strategies.py
from hypothesis.strategies import builds, composite, draw, floats, integers
class SutConfiguration:
""" Data which represents the configuration of the system under test. """
def __init__(self, integer, float):
self.integer = integer
self.float = float
# custom strategy which uses builds()
def SutConfigurationStrategy(min_int_config, max_int_config):
return builds(SutConfiguration,
integer=integers(min_value=min_int_config, max_value=max_int_config),
float=floats(min_value=APP_SPECIFIC_FLOAT_MIN, max_value=APP_SPECIFIC_FLOAT_MAX),
)
@composite
def overall_test_configuration(draw, sut_min_int_config, sut_max_int_config, sut_st=SutConfigurationStrategy, env_st=SutEnvironmentStrategy):
"""Custom strategy which uses draw."""
sut_config = draw(sut_st(sut_min_int_config, sut_max_int_config))
env_config = draw(env_st)
return (sut_config, rc_stereomatching_config, env_config)
策略整数值然后可以例如配置为 10
的最小值和 100
的最大值(再次:unittest
作为测试运行器):
# test.py
import unittest
from <package>.strategies import overall_test_configuration
class TestSut(unittest.TestCase):
"""Class containing several tests for the system under test."""
@given(overall_test_configuration(min_int_config=10, max_int_config=100))
def test_something():
"""Test which uses overall_test_configuration"""
...
旁注:这里使用class SutConfiguration
来封装数据并不是最优的。 Namedtuple 在这里是更好的选择...
我使用 builds()
and @composite
(the design is inspired by this example from the docs) 创建了自定义假设策略。这些策略的设计类似于下面的伪代码:
# strategies.py
from hypothesis.strategies import builds, composite, draw, floats, integers
class SutConfiguration:
""" Data which represents the configuration of the system under test. """
def __init__(self, integer, float):
self.integer = integer
self.float = float
# custom strategy which uses builds()
SutConfigurationStrategy = builds(
SutConfiguration,
integer=integers(min_value=APP_SPECIFIC_INT_MIN, max_value=APP_SPECIFIC_INT_MAX),
float=floats(min_value=APP_SPECIFIC_FLOAT_MIN, max_value=APP_SPECIFIC_FLOAT_MAX),
)
@composite
def overall_test_configuration(draw, sut_st=SutConfigurationStrategy, env_st=SutEnvironmentStrategy):
"""Custom strategy which uses draw."""
sut_config = draw(sut_st)
env_config = draw(env_st)
return (sut_config, rc_stereomatching_config, env_config)
该策略照常使用,例如使用 unittest
作为测试运行器:
# test.py
import unittest
from <package>.strategies import overall_test_configuration
class TestSut(unittest.TestCase):
"""Class containing several tests for the system under test."""
@given(overall_test_configuration())
def test_something():
"""Test which uses overall_test_configuration"""
...
现在我想让策略可配置到实际应用程序来定义例如min_value
in integers(min_value=APP_SPECIFIC_INT_MIN, ...)
定义测试函数时。这可以通过 done here 等参数为 @composite
策略完成。但是如何使使用 builds()
的策略可配置?
您可以定义一个函数,returns 像任何其他策略一样的策略:
def some_custom_strategy(a, b):
return builds(foo, bar(a, b))
当你有额外的参数时,这就是 composite 发生的所有事情 - composite 正在定义一个函数,returns 一个策略,这些额外的参数通过函数传递给底层装饰函数。
应用于上述伪代码的解决方案,例如SUT 配置 SutConfigurationStrategy
可配置的整数值如下所示:
# strategies.py
from hypothesis.strategies import builds, composite, draw, floats, integers
class SutConfiguration:
""" Data which represents the configuration of the system under test. """
def __init__(self, integer, float):
self.integer = integer
self.float = float
# custom strategy which uses builds()
def SutConfigurationStrategy(min_int_config, max_int_config):
return builds(SutConfiguration,
integer=integers(min_value=min_int_config, max_value=max_int_config),
float=floats(min_value=APP_SPECIFIC_FLOAT_MIN, max_value=APP_SPECIFIC_FLOAT_MAX),
)
@composite
def overall_test_configuration(draw, sut_min_int_config, sut_max_int_config, sut_st=SutConfigurationStrategy, env_st=SutEnvironmentStrategy):
"""Custom strategy which uses draw."""
sut_config = draw(sut_st(sut_min_int_config, sut_max_int_config))
env_config = draw(env_st)
return (sut_config, rc_stereomatching_config, env_config)
策略整数值然后可以例如配置为 10
的最小值和 100
的最大值(再次:unittest
作为测试运行器):
# test.py
import unittest
from <package>.strategies import overall_test_configuration
class TestSut(unittest.TestCase):
"""Class containing several tests for the system under test."""
@given(overall_test_configuration(min_int_config=10, max_int_config=100))
def test_something():
"""Test which uses overall_test_configuration"""
...
旁注:这里使用class SutConfiguration
来封装数据并不是最优的。 Namedtuple 在这里是更好的选择...