问题描述
from hypothesis import given,example
import hypothesis.strategies as st
import unittest
class SomeObject():
def __init__(self,symbol,value):
self.__symbol = symbol
self.__value = value
@st.composite
def sheet_names(draw,cnt=1,cnt_min_value=0):
if (not cnt):
cnt = draw(st.integers(min_value=cnt_min_value,max_value=3))
return (cnt,draw(st.lists(st.text(min_size=1).filter(lambda x: '\n' not in x),min_size=cnt,max_size=cnt,unique=True)))
@st.composite
def get_objects(draw,min_cnt=0):
cnt = draw(st.integers(min_value=min_cnt,max_value=3))
symbols = draw(st.lists(st.text(min_size=1),unique=True))
values = draw(st.lists(st.one_of(st.integers(),st.floats(allow_nan=False),st.text()),max_size=cnt))
objects = list()
for i in range(len(symbols)):
objects.append(SomeObject(symbols[i],values[i]))
return objects
class TestClass(unittest.TestCase):
@given(sheet_names=sheet_names(cnt=False,cnt_min_value=1),specs=get_objects(min_cnt=1))
@example(sheet_names=sheet_names(cnt=2),specs=get_objects(min_cnt=1))
def test_example(self,sheet_names,specs):
for i in range(len(sheet_names)):
pass
错误消息是:
TypeError:“ LazyStrategy”类型的对象没有len()
,出现在函数test_example中(在for循环中)。如果我删除@ example-line,则代码可以正常运行,但不能确定@example中提到的情况是否已解决。
问题:如何一方面编写通用测试(为此我需要len函数)并同时为假设命名明确的示例?
解决方法
正如Azat Ibrakov所说,您的问题是@example
装饰器采用值,而不是策略。例如:
# Bad - strategies don't work here!
@example(sheet_names=sheet_names(cnt=2),specs=get_objects(min_cnt=1))
# Good - passing values which could be generated.
@example(
sheet_names=(2,["sheet1","sheet2]),specs=[<SomeObject ...>,<SomeObject ...>,<SomeObject ...>]
)
假设在version 5.36.1中添加了关于@example
中的策略的明确警告。