我有一个包含嵌套函数的 Python 函数。我想使用 PyTest 为嵌套函数编写单元测试,但我不想修改嵌套函数的定义方式或其行为。我也不想调用或测试外部函数本身,只想调用或测试嵌套函数。
这是我的代码的简化示例:
# example.py
def outer_function(a, b):
"""
Example outer function that performs some operations.
"""
def inner_function(x, y):
"""
Nested function that I want to test.
"""
return x + y
# Some operations using inner_function
result = inner_function(a, b)
return result
我想创建一个 PyTest 测试函数,仅使用参数化测试
inner_function
,确保它涵盖各种场景,例如:
如何以测试独立于
outer_function
的方式实现这一目标?
# test_example.py
import pytest
@pytest.mark.parametrize("x, y, expected", [
(1, 2, 3), # Adding two positive numbers
(1, -1, 0), # Adding positive and negative numbers
(-1, -2, -3), # Adding two negative numbers
(0, 5, 5), # Adding zero to a number
(3, 0, 3) # Adding a number to zero
])
def test_inner_function(x, y, expected):
"""
Describe how to test the inner_function here.
"""
# Code to test inner_function goes here.
任何有关如何正确构建和实施这些测试的指导或示例将不胜感激!
正如@Mark的评论中所述,如果一个函数是嵌套的,那么它不应该与外部函数分开。这就是嵌套函数的全部意义。如果没有外部函数(想想非局部变量),大多数内部函数甚至可能无法工作。但是,如果您确实想这样做,有多种方法,但所有方法都至少需要对外部函数的代码进行一些修改。第一种方法是在外部函数中返回内部函数以及外部函数可能返回的任何其他原始值:
def outer_function(a, b):
"""
Example outer function that performs some operations.
"""
def inner_function(x, y):
"""
Nested function that I want to test.
"""
return x + y
# Some operations using inner_function
result = inner_function(a, b)
return result, inner_function
res, inner = outer_function(1, 2)
inner = pytest.mark.parametrize("x, y, expected", [
(1, 2, 3), # Adding two positive numbers
(1, -1, 0), # Adding positive and negative numbers
(-1, -2, -3), # Adding two negative numbers
(0, 5, 5), # Adding zero to a number
(3, 0, 3) # Adding a number to zero
])(inner)
在上面的代码中,我用函数调用替换了装饰器。第二种方法是将外部函数的属性设置为内部函数:
def outer_function(a, b):
"""
Example outer function that performs some operations.
"""
def inner_function(x, y):
"""
Nested function that I want to test.
"""
return x + y
# Some operations using inner_function
result = inner_function(a, b)
outer_function.inner = inner_function
return result
res, inner = outer_function(1, 2), outer_function.inner
inner = pytest.mark.parametrize("x, y, expected", [
(1, 2, 3), # Adding two positive numbers
(1, -1, 0), # Adding positive and negative numbers
(-1, -2, -3), # Adding two negative numbers
(0, 5, 5), # Adding zero to a number
(3, 0, 3) # Adding a number to zero
])(inner)
请记住,Python 中的函数是一流的,因此您可以将它们视为可以附加新属性的简单对象。在本例中,我将内部函数的引用附加到外部函数,因此不需要像第一种方法那样返回内部函数。在外部函数之外,只需在先调用外部函数后使用点表示法来获取内部函数对象(此处必需,因为如果不先调用外部函数,则
outer_function.inner
属性将不会被初始化)。
注意:在这两种方法中,都必须手动调用 pytest 装饰器,因为我们外部的对象是对内部函数的引用。装饰器必须出现在函数处,而不仅仅是函数对象处。