[英]Create hypothesis strategy that returns unique values
I'm trying to create a hypothesis
strategy which produces integers with no repeats.我正在尝试创建一个
hypothesis
策略,它产生没有重复的整数。 Here's my code:这是我的代码:
import hypothesis
import hypothesis.strategies as strategies
def unique(strat):
previous = set()
@strategies.composite
def new_strategy(draw):
while True:
value = draw(strat)
if value not in previous:
previous.add(value)
return value
return new_strategy
strategy = unique(strategies.integers(min_value=0, max_value=1000))
@hypothesis.given(num=strategy)
def test_unique(num):
pass
However, when I run pytest
, I get但是,当我运行
pytest
时,我得到
@check_function
def check_strategy(arg, name="")
if not isinstance(arg, SearchStrategy):
hint = ""
if isinstance(arg, (list, tuple)):
hint = ", such as st.sampled_from({}),".format(name or "...")
if name:
name += "="
raise InvalidArgument(
"Expected a SearchStrategy%s but got %s%r (type=%s)"
% (hint, name, arg, type(arg).__name__)
)
E hypothesis.errors.InvalidArgument: Expected a SearchStrategy but got mapping['num']=<function accept.<locals>.new_strategy at 0x7f30622418b0> (type=function)
@st.composite
def unique(draw, strategy):
seen = draw(st.shared(st.sets()))
return draw(
strategy
.filter(lambda x: x not in seen)
.map(lambda x: seen.add(x) or x)
)
There's a couple of cute tricks here:这里有几个可爱的技巧:
st.shared()
to create a new seen
cache for each distinct example.st.shared()
为每个不同的示例创建一个新的seen
缓存。 This fixes your "what if you run out of values" problem, but also fixes your critical "the test can't replay failures" problem which would make the whole thing horribly flaky.key=
argument to `shared, or having it construct a dictionary.key=
参数,或者让它构造一个字典。.filter(...)
to exclude already-seen items. .filter(...)
排除已经看到的项目。 This is better than a loop because it means Hypothesis can more effectively avoid and report on futile attempts to generate a not-yet-seen example..map(...)
call to add it to the set is a blatant abuse of the facts that set.add()
returns None
after mutating the object, and that or
evaluates to the second item if the first is falsey..map(...)
调用是对set.add()
在改变 object 后返回None
的事实的公然滥用,并且如果第一个是假的,则它or
评估为第二个项目。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.