故事:
目前,我有一个测试功能,需要一个包含以下规则的整数列表:
N)可以是1到50N样本有效输入:
[[0]]
[[2, 1], [2, 0], [3, 1], [1, 0]]
[[1], [0]]
Run Code Online (Sandbox Code Playgroud)
示例无效输入:
[[2]] # 2 is more than N=1 (total number of sublists)
[[0, 1], [2, 0]] # 2 is equal to N=2 (total number of sublists)
Run Code Online (Sandbox Code Playgroud)
我试图用接近它基于属性的测试,并产生不同的有效输入hypothesis库,并试图绕到我的头lists()和integers(),但不能使其工作:
lists()和min_size和max_size参数Chaining strategies togetherrectangle_lists上面的例子,我们没有引用里面的"父"列表的长度integers() …python testing unit-testing property-based-testing python-hypothesis
我正在使用假设来测试一个将两个长度相等的列表作为输入的函数。
import hypothesis.strategies as st
from hypothesis import assume, given
@given(st.lists(ints, min_size=1),
st.lists(ints, min_size=1),
)
def test_my_func(x, y):
assume(len(x) == len(y))
# Assertions
Run Code Online (Sandbox Code Playgroud)
这给了我错误信息:
FailedHealthCheck:看起来您的策略正在过滤掉大量数据。健康检查发现了 50 个过滤的示例,但只有 4 个很好的示例。
len(x) == len(y)过滤掉太多输入的假设。所以我想产生一个随机正数和使用,作为两者的长度x和y。有没有办法做到这一点?
故事:
我目前正在使用单元测试函数hypothesis和自定义生成策略试图找到一个特定的输入来"打破"我当前的解决方案.以下是我的测试结果:
from solution import answer
# skipping mystrategy definition - not relevant
@given(mystrategy)
def test(l):
assert answer(l) in {0, 1, 2}
Run Code Online (Sandbox Code Playgroud)
基本上,当answer()函数没有返回0或1或2 时,我正在寻找可能的输入.
以下是我当前工作流程的样子:
hypothesis找到一个产生以下内容的输入AssertionError:
$ pytest test.py
=========================================== test session starts ============================================
...
------------------------------------------------ Hypothesis ------------------------------------------------
Falsifying example: test(l=[[0], [1]])
Run Code Online (Sandbox Code Playgroud)使用此特定输入调试函数,尝试了解此输入/输出是否合法,并且函数正常工作
问题:
如何跳过这个伪造生成的例子([[0], [1]]在这种情况下)并要求hypothesis生成另一个?
问题也可以解释为:hypothesis如果找到伪造的例子并且生成更多伪造的例子,我可以要求不终止吗?
python testing unit-testing property-based-testing python-hypothesis
我维护一个开源库xarray,它使用pytest在Travis-CI上运行集成测试.我们使用stack conda安装科学Python.
今天早些时候,我们的五个测试版本中的两个(Python 3.5和3.6,但不是Python 2.7或3.4)开始失败,没有明显的原因.pytest本身失败了,带着神秘的引用:
$ py.test xarray --cov=xarray --cov-config ci/.coveragerc --cov-report term-missing --verbose $EXTRA_FLAGS
Traceback (most recent call last):
File "/home/travis/miniconda/envs/test_env/bin/py.test", line 6, in <module>
sys.exit(py.test.main())
File "/home/travis/miniconda/envs/test_env/lib/python3.6/site-packages/_pytest/config.py", line 49, in main
config = _prepareconfig(args, plugins)
File "/home/travis/miniconda/envs/test_env/lib/python3.6/site-packages/_pytest/config.py", line 168, in _prepareconfig
pluginmanager=pluginmanager, args=args)
File "/home/travis/miniconda/envs/test_env/lib/python3.6/site-packages/_pytest/vendored_packages/pluggy.py", line 745, in __call__
return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
File "/home/travis/miniconda/envs/test_env/lib/python3.6/site-packages/_pytest/vendored_packages/pluggy.py", line 339, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "/home/travis/miniconda/envs/test_env/lib/python3.6/site-packages/_pytest/vendored_packages/pluggy.py", line 334, in <lambda>
_MultiCall(methods, kwargs, hook.spec_opts).execute()
File …Run Code Online (Sandbox Code Playgroud) 此示例是文档中示例的变体:
import hypothesis.strategies as st
from hypothesis import given
@st.composite
def s(draw):
x = draw(st.text(), min_size=1)
y = draw(st.text(alphabet=x))
return (x, y)
@given(s1=s, s2=s)
def test_subtraction(s1, s2):
print(s1, s2)
assert 0
Run Code Online (Sandbox Code Playgroud)
它失败:
E hypothesis.errors.InvalidArgument: Expected SearchStrategy but got <function accept.<locals>.s at 0x7fd7e5c05620> (type=function)
/mnt/work/unfuncat/software/anaconda/lib/python3.6/site-packages/hypothesis/internal/validation.py:40: InvalidArgument
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
正如文档和本文所述,应该可以在同一测试中使用假设策略和 pytest 装置。
但是执行本文的示例代码:
from hypothesis import given, strategies as st
from pytest import fixture
@fixture
def stuff():
return "kittens"
@given(a=st.none())
def test_stuff(a, stuff):
assert a is None
assert stuff == "kittens"
Run Code Online (Sandbox Code Playgroud)
产生以下错误:
FAILED [100%]
test_with_fixture.py:9 (test_stuff)
item = <Function test_stuff>
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_call(item):
if not (hasattr(item, "obj") and "hypothesis" in sys.modules):
yield
return
from hypothesis import core
from hypothesis.internal.detection import is_hypothesis_test
core.running_under_pytest = True
if not is_hypothesis_test(item.obj):
# If @given was not applied, check …Run Code Online (Sandbox Code Playgroud) 我有许多单元测试利用了@composite我编写的策略。该策略非常慢(它生成复杂的对象),并且有时其中一个测试无法通过too_slow运行状况检查。当这种情况发生时,我深深地叹了一口气,然后补充道
@settings(suppress_health_check=(HealthCheck.too_slow,))
Run Code Online (Sandbox Code Playgroud)
进行测试。
有没有办法HealthCheck.too_slow一劳永逸地抑制所有使用慢速策略的测试?
使用假设库并执行单元测试时,如何查看该库在我的代码上尝试的实例?
例
from hypothesis import given
import hypothesis.strategies as st
@given(st.integers())
def silly_example(some_number):
assert some_number > 0
Run Code Online (Sandbox Code Playgroud)
问题是:如何打印/查看some_number库生成的变量?
为了测试添加两个非常相似的数据行时数据库的行为方式,我需要为每个参数组合设置一个新数据库。我还使用假设的策略来生成“相似”的数据行。
测试工作流程应如下:
for example in hypothesis-given-examples: # @given
for combination in pytest-parametrized-combinations: # @pytest.mark.parametrize
db = setup_db(example, combination) # should be a fixture with `yield` but I can't parametrize it
do_test_1(db) # using the setup database
do_test_2(db) # using the setup database
do_test_3(db) # using the setup database
teardown(db)
Run Code Online (Sandbox Code Playgroud)
我开始于:
@mark.parametrize('different_properties', [False, 'entirekeys', 'crop', 'addkeys', 'overwritekeys'])
@mark.parametrize('different_identproperties', [False, 'entirekeys', 'crop', 'addkeys', 'overwritekeys'])
@mark.parametrize('different_labels', [False, 'entirekeys', 'crop', 'addkeys', 'overwritekeys'])
class TestMerge:
@classmethod
@given(node1=node_strategy, sampler=data())
def setup_class(cls, node1, sampler, different_labels, different_properties, different_identproperties): …Run Code Online (Sandbox Code Playgroud) 我正在使用Hypothesis包用 Python 编写一个简单的测试代码。有没有办法对同一个函数参数使用多种策略?例如,使用integers()和floats()来测试我的values参数而不编写两个单独的测试函数?
from hypothesis import given
from hypothesis.strategies import lists, integers, floats, sampled_from
@given(
integers() ,floats()
)
def test_lt_operator_interval_bin_numerical(values):
interval_bin = IntervalBin(10, 20, IntervalClosing.Both)
assert (interval_bin < values) == (interval_bin.right < values)
Run Code Online (Sandbox Code Playgroud)
上面的代码不起作用,但它代表了我想要实现的目标。
注意:我已经尝试过使用两种不同策略创建两个不同测试的简单解决方案:
def _test_lt(values):
interval_bin = IntervalBin(10, 20, IntervalClosing.Both)
assert (interval_bin < values) == (interval_bin.right < values)
test_lt_operator_interval_bin_int = given(integers())(_test_lt)
test_lt_operator_interval_bin_float = given(floats())(_test_lt)
Run Code Online (Sandbox Code Playgroud)
然而我想知道是否有更好的方法来做到这一点:当策略的数量变大时,它作为代码是相当冗余的。