如何在 pytest 的整个测试过程中将用户的函数作为测试变量?

问题描述 投票:0回答:1

我是

pytest
的新手,我一直在努力实现我自己的库的这一部分:从用户那里获取一个函数并将该函数保存为变量,以便可以在整个测试过程中使用和访问它。我试图将我在
playground.py
中定义的函数(假装我是随机用户)传递给
sortoy.py
。我听说不建议使用
global_variable
。有推荐的方法吗?

我的整个图书馆结构如下所示:

my_library
-my_library
    -__init__.py
    -sortoy.py
-LICENSE
-playground.py --> This is where I am testing my code
-README.md
-setup.py

这是代码

playground.py

import my_library.sortoy

# The defined array
def bubbleSort(arr): 
    n = len(arr)
    for i in range(n): 
        for j in range(0, n-i-1): 
            if arr[j] > arr[j+1] : 
                arr[j], arr[j+1] = arr[j+1], arr[j] 
    return arr

my_library.sortoy.sort_function(bubbleSort) # Taking user defined function


这是代码

sortoy.py

import pytest

small_cases = [([1], [1]), ([2, 1], [1, 2]), ([2, 2], [2, 2])]

@pytest.fixture # I was trying to use this for taking user function (It does not work however).
def sort_function(f):
    return f

# The test I am trying to run
@pytest.mark.parametrize("test_case, sorted", small_cases)
def test_one_element(sort_function, test_case, sorted):
    assert sort_function(test_case) == sorted

# Script version of pytest so that I could run the test_case above once I have got the user-defined function.
pytest.main(["-v"])

仅供参考,我试图实现的库是在用户传入他们创建的

sort_function
(如排序)时测试用户定义的函数。当调用
my_library.sortoy.sort_function(bubblesort)
时,该库应该自动执行测试(在本例中为
test_one_element()
),并在控制台上显示是否失败或通过测试。

python testing structure pytest
1个回答
0
投票

我认为有两种主要方法可以解决你想要解决的问题,因为它看起来有点像“框架”问题。

我明白你想用

my_library.sortoy.sort_function(bubbleSort)
做什么,但它不会按照你想要的方式工作,因为就哪个文件正在做哪件事而言,它是“向后”的。

  1. 强制用户将其函数命名为特定的名称,然后您可以轻松导入

  2. 创建一个装饰器,以便用户能够指定他们的排序函数是什么

使用特定名称

在这种情况下你修改

@pytest.fixture # I was trying to use this for taking user function (It does not work however).
def sort_function(f):
    return f

看起来更像这样:

@pytest.fixture
def sort_function():
    from ..playground import bubbleSort as f
    return f

创建装饰器

基本要点是您希望用户编写如下内容:

from mylibrary import sortfunc

@sortfunc
def bubbleSort(arr): 
    n = len(arr)
    for i in range(n): 
        for j in range(0, n-i-1): 
            if arr[j] > arr[j+1] : 
                arr[j], arr[j+1] = arr[j+1], arr[j] 
    return arr

然后,您可以使用注册到库的函数执行某些操作,然后可以在 pytest 文件中使用这些函数。

mylibrary.py

SORT_FUNCS = {}

def sortfunc(f):
    global SORT_FUNCS
    SORT_FUNCS[f.__name__] = f
    return f

然后从您的测试框架文件中,您可以执行以下操作:

@pytest.fixture
def sort_functions():
    from mylibrary import SORT_FUNCS
    return SORT_FUNCS # returns the dict of names, function handles

在这种情况下,您可能会使用此

sort_functions
作为您可以参数化的东西,因为用户完全有可能装饰多个函数。

奖励:pytest 方法

您还可以告诉人们使用特定的模块名称,然后导入并搜索该模块以查找名称中带有“sort”的任何内容,并假设该模块中名称中带有“sort”的所有内容都是排序函数。

@pytest.fixture
def sort_functions():
    import ..playground
    sort_funcs = []
    for attr in dir(playgound):
        if "sort" in attr.lower():
            sort_funcs.append(getattr(playground, attr))
    return sort_funcs
© www.soinside.com 2019 - 2024. All rights reserved.