如何使用 PyTest 对嵌套函数进行单元测试而不修改外部函数

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

我有一个包含嵌套函数的 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
,确保它涵盖各种场景,例如:

  1. 两个正数相加
  2. 正负数相加
  3. 两个负数相加
  4. 数字加零

如何以测试独立于

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.

任何有关如何正确构建和实施这些测试的指导或示例将不胜感激!

python function unit-testing nested pytest
1个回答
0
投票

正如@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 装饰器,因为我们外部的对象是对内部函数的引用。装饰器必须出现在函数
定义

处,而不仅仅是函数对象处。

© www.soinside.com 2019 - 2024. All rights reserved.