我有一个使用 python 假设的生成器,如下所示:
@st.composite
def generate_network_fault_only(draw):
fault = {
"impaired": st.just(True), # need to detect if all faults are None to switch this back.
"limit": draw(NetworkFaultGen.generate_limit()),
"delay": draw(NetworkFaultGen.generate_delay()),
"loss_random": draw(NetworkFaultGen.generate_loss_random()),
"corrupt": draw(NetworkFaultGen.generate_corrupt()),
"duplicate": draw(NetworkFaultGen.generate_duplicate()),
"reorder": draw(NetworkFaultGen.generate_reorder()),
"rate": draw(NetworkFaultGen.generate_rate())
}
return draw(st.fixed_dictionaries(fault))
Run Code Online (Sandbox Code Playgroud)
上面的每个函数都会返回类似以下内容的内容:
@st.composite
def generate_reorder(draw):
"""
This must only happen if delay is applied
"""
return st.one_of(st.fixed_dictionaries(
{"percent": st.integers(min_value=0, max_value=100),
"correlation": st.integers(min_value=0, max_value=100),
"distance": st.integers(min_value=0)}),st.none())
Run Code Online (Sandbox Code Playgroud)
reorder我的值和重新排序中的值之间存在依赖关系,delay只有在延迟不是时才能指定None。
我不知道如何实现这一点。过滤似乎遇到了性能问题。此时代码中的delay值还不是具体值。
我需要在python中测试一个函数,该函数接受具有任何类型的数据的列表,从整数到字符串再到用户组成的任何对象。假设中是否有一种方法可以生成带有随机对象的列表?我知道我可以使用生成随机浮动列表
@given(strategies.lists(strategies.floats()))
Run Code Online (Sandbox Code Playgroud)
等等,包括整数,字符等。但是,如何使它成为随机列表却具有多个数据类型呢?
我正在尝试使用以下代码创建一个用于代码测试目的pandas DataFrame的hypothesis库:
from hypothesis.extra.pandas import columns, data_frames
from hypothesis.extra.numpy import datetime64_dtypes
@given(data_frames(index=datetime64_dtypes(max_period='Y', min_period='s'),
columns=columns("A B C".split(), dtype=int)))
Run Code Online (Sandbox Code Playgroud)
我收到的错误如下:
E TypeError: 'numpy.dtype' object is not iterable
Run Code Online (Sandbox Code Playgroud)
我怀疑这是因为当我构造DataFramefor时,index=我只传递一个datetime元素,而不是一个ps.Series带有类型的all datetime。即使是这种情况(我不确定),我仍然不确定如何使用hypothesis库来实现我的目标。
谁能告诉我代码有什么问题以及解决方案是什么?
我正在使用假设4.24.6和pytest-5.0.0运行测试套件。我的测试有一组有限的可能输入,但是假设从未完成测试。
我将其简化为以下最小示例,我将其作为 pytest test.py
from hypothesis import given
import hypothesis.strategies as st
@given(x=st.just(0)
| st.just(1),
y=st.just(0)
| st.just(1)
| st.just(2))
def test_x_y(x, y):
assert True
Run Code Online (Sandbox Code Playgroud)
我希望它在这里尝试所有六个组合然后再成功。或者可能是检查薄脆性的一小部分。相反,它会无限期运行(在大约15分钟的测试后,我将其杀死了。)
如果我中断测试,追溯记录似乎表明它只是不断产生新的例子。
我在这里做错了什么?
我正在测试一个 REST API,它可以处理不同的请求,例如过时的和无日期的。一个请求有一个名为 的字段request_type。我想知道在假设中编写测试的最佳方法是什么:
我可以写两个睾丸,一个是dateed,一个是dateless。
但是对于一个共同的属性,我可以编写一个与pytest.mark.parametrize. 问题是请求策略如何req_type在@given.
@pytest.mark.parameterize('req_type', ['dated', 'dateless'])
@given(req=requests())
def test_process_request(req, req_type):
# override the parameter req_type in req with input req_type
pass
Run Code Online (Sandbox Code Playgroud)
有没有办法参数化像@given(req=requests(req_type))?或者我应该随机生成带有日期和无日期的请求并通过测试?
我已经使用hypothesis了一段时间了。我想知道如何重用@given parts.
我拥有的一些代码大约有 20 行,我将整个@given部分复制到几个测试用例之上。
一个简单的测试示例
@given(
some_dict=st.fixed_dictionaries(
{
"test1": st.just("name"),
"test2": st.integers()
}
)
)
def test_that uses_some_dict_to_initialize_object_im_testing(some_dict):
pass
Run Code Online (Sandbox Code Playgroud)
重用@given块的最佳方法是什么?
著名的基于属性的测试框架假设能够生成大量的测试用例。
但有没有办法限制假设生成的测试用例的数量,从而缩短测试周期呢?
例如,将特定的关键字参数提供给@given装饰器?
python automated-tests property-based-testing python-hypothesis
我有以下使用基因组数据创建数据框的策略:
from hypothesis.extra.pandas import columns, data_frames, column
import hypothesis.strategies as st
def mysort(tp):
key = [-1, tp[1], tp[2], int(1e10)]
return [x for _, x in sorted(zip(key, tp))]
positions = st.integers(min_value=0, max_value=int(1e7))
strands = st.sampled_from("+ -".split())
chromosomes = st.sampled_from(elements=["chr{}".format(str(e)) for e in list(range(1, 23)) + "X Y M".split()])
genomics_data = data_frames(columns=columns(["Chromosome", "Start", "End", "Strand"], dtype=int),
rows=st.tuples(chromosomes, positions, positions, strands).map(mysort))
Run Code Online (Sandbox Code Playgroud)
我对空数据帧并不真正感兴趣,因为它们是无效的,而且我还想生成一些非常长的 dfs。如何更改为测试用例创建的数据帧的大小?即最小尺寸为 1,平均尺寸为大?
我正在编写带有假设的统计分析测试。ZeroDivisionError当传递非常稀疏的数据时,假设导致我在代码中出现 a 。所以我调整了我的代码来处理异常;就我而言,这意味着记录原因并重新引发异常。
try:
val = calc(data)
except ZeroDivisionError:
logger.error(f"check data: {data}, too sparse")
raise
Run Code Online (Sandbox Code Playgroud)
我需要通过调用堆栈向上传递异常,因为顶级调用者需要知道存在异常,以便它可以将错误代码传递给外部调用者(REST API 请求)。
编辑:我也无法为val;分配合理的值 本质上我需要一个直方图,当我根据数据计算合理的箱宽度时会发生这种情况。显然,当数据稀疏时,这会失败。如果没有直方图,算法就无法继续进行。
现在我的问题是,在我的测试中,当我做这样的事情时:
@given(dataframe)
def test_my_calc(df):
# code that executes the above code path
Run Code Online (Sandbox Code Playgroud)
hypothesis不断生成触发的失败示例ZeroDivisionError,并且我不知道如何忽略此异常。通常我会用 标记这样的测试pytest.mark.xfail(raises=ZeroDivisionError),但在这里我不能这样做,因为相同的测试可以通过良好的输入。
像这样的东西是理想的:
ZeroDivisionError引发时,将其视为预期失败而跳过。我怎样才能做到这一点?我还需要try: ... except: ...在测试主体中放入 a 吗?我需要在 except 块中做什么才能将其标记为预期失败?
编辑:为了解决@hoefling的评论,分离出失败的案例将是理想的解决方案。但不幸的是,hypothesis没有给我足够的句柄来控制它。我最多可以控制生成数据的总数和限制(最小值,最大值)。然而,失败案例的范围非常窄。我没有办法控制这一点。我想这就是假设的要点,也许我根本不应该为此使用假设。
这是我生成数据的方式(稍微简化):
cities = [f"city{i}" for i in range(4)]
cats = [f"cat{i}" for i in range(4)]
@st.composite
def …Run Code Online (Sandbox Code Playgroud) 在单元测试中,我使用monkeypatch来更改dict.
from hypothesis import given, strategies
test_dict = {"first": "text1", "second": "text2"}
given(val=strategies.text())
def test_monkeypath(monkeypatch, val):
monkeypatch.setitem(test_dict, "second", val)
assert isinstance(test_dict["second"], str)
Run Code Online (Sandbox Code Playgroud)
测试通过了,但在使用 执行以下测试代码时收到警告pytest。
=================================================================================================================== warnings summary ====================================================================================================================
.PyCharm2019.2/config/scratches/hypothesis_monkeypatch.py::test_monkeypath
c:\users\d292498\appdata\local\conda\conda\envs\pybt\lib\site-packages\hypothesis\extra\pytestplugin.py:172: HypothesisDeprecationWarning: .PyCharm2019.2/config/scratches/hypothesis_monkeypatch.py::test_monkeypath uses the 'monkeypatch' fixture, wh
ich is reset between function calls but not between test cases generated by `@given(...)`. You can change it to a module- or session-scoped fixture if it is safe to reuse; if not we recommend using a context …Run Code Online (Sandbox Code Playgroud)