如何在不修改外部函数的情况下用PyTest测试嵌套函数
问题:测试Python嵌套函数,不修改原代码且不测试外部函数
我有一个包含嵌套函数的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测试函数,覆盖以下场景:
- 两个正数相加
- 正数与负数相加
- 两个负数相加
- 数字与零相加
且测试需独立于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.
解决方案
要在不修改原代码的前提下获取嵌套的inner_function,可以通过解析外部函数的字节码,提取嵌套函数的代码对象并重新构造函数。具体步骤如下:
- 导入
types模块和目标外部函数outer_function - 遍历
outer_function.__code__.co_consts,找到名为inner_function的代码对象 - 使用
types.FunctionType将代码对象重新构造为可调用的函数 - 在测试函数中调用构造好的
inner_function并断言结果
完整的测试代码如下:
# test_example.py import pytest import types from example import outer_function # 提前构造inner_function,避免每次测试重复执行 def get_inner_function(): # 遍历外部函数的常量,找到嵌套函数的代码对象 for const in outer_function.__code__.co_consts: if isinstance(const, types.CodeType) and const.co_name == "inner_function": # 构造嵌套函数,使用全局命名空间 return types.FunctionType(const, globals(), "inner_function") raise ValueError("Could not find inner_function") inner_function = get_inner_function() @pytest.mark.parametrize("x, y, expected", [ (1, 2, 3), # 两个正数相加 (1, -1, 0), # 正数与负数相加 (-1, -2, -3), # 两个负数相加 (0, 5, 5), # 零与数字相加 (3, 0, 3) # 数字与零相加 ]) def test_inner_function(x, y, expected): """测试嵌套函数inner_function的加法逻辑""" assert inner_function(x, y) == expected
说明
get_inner_function函数负责从outer_function的字节码中提取并构造嵌套函数,只需执行一次即可复用- 构造函数时使用
globals()作为命名空间,确保嵌套函数能正常访问所需的全局变量(此示例中无额外依赖,所以无需特殊处理) - 测试函数直接调用构造好的
inner_function,完全独立于outer_function的执行逻辑
内容的提问来源于stack exchange,提问作者edge selcuk
相关产品推荐
相关产品推荐

