我正在使用假设进行测试,并且我想在测试的两个参数之间建立关系。我知道assume
,但是当我事先知道约束时,这似乎很浪费。
这是一个最小的例子:
from datetime import date
import pytest
from hypothesis import given, assume, strategies as st
def get_daterange_filter(start, end):
"""`start` and `end` are dates of the format: YYYYMMDD"""
if int(start) > int(end):
raise ValueError(f"{start} comes after {end}")
else:
pass
dt_strategy = st.dates(min_value=date(2019, 4, 1),
max_value=date(2019, 7, 31))
@given(dt_strategy, dt_strategy)
def test_daterange_filter(dt1, dt2):
assume(dt1 > dt2)
start, end = dt1.strftime("%Y%m%d"), dt2.strftime("%Y%m%d")
with pytest.raises(ValueError):
get_daterange_filter(start, end)
上述统计信息摘要报告以下内容:
hypo.py::test_daterange_filter:
- 100 passing examples, 0 failing examples, 68 invalid examples
- Typical runtimes: 0-1 ms
- Fraction of time spent in data generation: ~ 47%
- Stopped because settings.max_examples=100
那是很多浪费的尝试。这是一个非常简单的情况,但是在一个典型的数据密集型项目中,我可以预见到许多此类情况。所以我想知道,是否有一种简单的方法可以说出两个参数满足某种关系(在这种情况下,一个大于另一个)的假设。我无法在文档中找到任何内容。
答案 0 :(得分:1)
如果您需要相互依赖的策略,请使用策略共享:
dates = st.shared(st.dates(min_value=date(2019, 4, 1), max_value=date(2019, 7, 31)))
@st.composite
def later_dates(draw):
return draw(st.dates(min_value=draw(dates)))
# or, if you need the strict inequality for passing
# the test in its given form, add a day to min_value:
# return draw(st.dates(min_value=draw(dates) + timedelta(days=1)))
@given(start=later_dates(), end=dates)
def test_daterange_filter(start, end):
fstart, fend = start.strftime("%Y%m%d"), end.strftime("%Y%m%d")
with pytest.raises(ValueError):
get_daterange_filter(fstart, fend)
运行更多示例并记录时间:
...
collected 2 items
test_spam.py::test_daterange_filter PASSED
test_spam.py::test_daterange_filter_shared_date_strategy PASSED
======================================== Hypothesis Statistics =========================================
test_spam.py::test_daterange_filter:
- 10000 passing examples, 0 failing examples, 10050 invalid examples
- Typical runtimes: < 1ms
- Fraction of time spent in data generation: ~ 44%
- Stopped because settings.max_examples=10000
test_spam.py::test_daterange_filter_shared_date_strategy:
- 10000 passing examples, 0 failing examples, 0 invalid examples
- Typical runtimes: < 1ms
- Fraction of time spent in data generation: ~ 50%
- Stopped because settings.max_examples=10000
======================================== slowest test durations ========================================
12.55s call test_spam.py::test_daterange_filter
6.27s call test_spam.py::test_daterange_filter_shared_date_strategy
(0.00 durations hidden. Use -vv to show these durations.)
====================================== 2 passed in 18.86 seconds =======================================