标签: python-hypothesis

Python假设:如何组成相互依赖的生成器?

我有一个使用 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 python-hypothesis

5
推荐指数
1
解决办法
1287
查看次数

生成带有假设的随机对象列表

我需要在python中测试一个函数,该函数接受具有任何类型的数据的列表,从整数到字符串再到用户组成的任何对象。假设中是否有一种方法可以生成带有随机对象的列表?我知道我可以使用生成随机浮动列表

@given(strategies.lists(strategies.floats()))
Run Code Online (Sandbox Code Playgroud)

等等,包括整数,字符等。但是,如何使它成为随机列表却具有多个数据类型呢?

python testing python-hypothesis

5
推荐指数
1
解决办法
623
查看次数

如何使用假设库创建日期时间索引的 Pandas DataFrame?

我正在尝试使用以下代码创建一个用于代码测试目的pandas DataFramehypothesis库:

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库来实现我的目标。

谁能告诉我代码有什么问题以及解决方案是什么?

python pytest pandas python-hypothesis

5
推荐指数
1
解决办法
561
查看次数

为什么我的简单的有限假设检验永远不会停止?

我正在使用假设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分钟的测试后,我将其杀死了。)

如果我中断测试,追溯记录似乎表明它只是不断产生新的例子。

我在这里做错了什么?

python pytest python-hypothesis

5
推荐指数
1
解决办法
133
查看次数

如何在@given 中参数化假设策略

我正在测试一个 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))?或者我应该随机生成带有日期和无日期的请求并通过测试?

python python-hypothesis

5
推荐指数
1
解决办法
550
查看次数

假设 - 在测试之间重用 @given

我已经使用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块的最佳方法是什么?

python python-hypothesis

5
推荐指数
2
解决办法
141
查看次数

如何更改假设生成的最大测试用例数?

著名的基于属性的测试框架假设能够生成大量的测试用例。

但有没有办法限制假设生成的测试用例的数量,从而缩短测试周期呢?

例如,将特定的关键字参数提供给@given装饰器?

python automated-tests property-based-testing python-hypothesis

5
推荐指数
1
解决办法
1740
查看次数

如何设置假设中数据帧的最小和最大长度?

我有以下使用基因组数据创建数据框的策略:

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,平均尺寸为大?

python-hypothesis

4
推荐指数
1
解决办法
443
查看次数

使用 pytest 和假设进行异常处理和测试

我正在编写带有假设的统计分析测试。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),但在这里我不能这样做,因为相同的测试可以通过良好的输入。

像这样的东西是理想的:

  1. 但是,对大多数输入照常继续测试
  2. 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)

python expected-exception pytest python-hypothesis

4
推荐指数
1
解决办法
1316
查看次数

pytest:使用假设时的monkeypatch

在单元测试中,我使用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)

monkeypatching pytest hypothesis-test python-hypothesis

3
推荐指数
2
解决办法
1288
查看次数