【问题标题】:local variable for unit testing in python to verify functionality of test function用于在 python 中进行单元测试的局部变量以验证测试功能的功能
【发布时间】:2018-11-09 09:42:13
【问题描述】:

我是单元测试和 python 的新手。我开始在 python 中对不同模块(用 c 开发)进行单元测试。在某些情况下,我发现该函数不会返回任何值并且不会修改任何全局变量的值。

在这种情况下,我将如何根据一些局部变量值来验证函数的功能。由于 local 在函数之外不可用,我无法验证局部变量的值。单元测试这些功能的正确方法应该是什么?

我通过下面的链接询问这个问题,这表明我们不应该对局部变量执行单元测试。

override python function-local variable in unittest

在这里,我可以看到一些可用于在函数执行结束时测试局部变量的方法。 https://coderanch.com/t/679691/engineering/test-local-variable-method-junit

有什么方法可以导出局部变量以用于单元测试该函数?

【问题讨论】:

  • 如果一个函数没有返回或修改任何全局变量......这个函数到底在做什么?
  • @RishikeshRaje 执行 IO?
  • 是的,它正在修改内部控制器寄存器并在某些情况下调用静态函数。调用其他已经被存根的外部函数。
  • 当然,在调用其他函数的情况下,您可以创建一个模拟对象并验证以下内容:a) 模拟被调用的次数,b) 模拟对象的参数调用。
  • @kapilddit:在此处查看模拟文档:docs.python.org/3/library/unittest.mock.html 特别是查找“call_count”部分。

标签: python c unit-testing


【解决方案1】:

在 python 中没有“开箱即用”的解决方案,尽管我坚信能够模拟和检查局部变量发生的情况在开发更高级的测试时非常重要。我已经通过一个新类来模拟一个函数并获取本地值来实现这一点,我希望它对你有所帮助。

import inspect
from textwrap import dedent
import re


class MockFunction:
    """ Defines a Mock for functions to explore the details on their execution.
    """
    def __init__(self, func):
        self.func = func

    def __call__(mock_instance, *args, **kwargs):
        # Add locals() to function's return
        code = re.sub('[\\s]return\\b', ' return locals(), ', dedent(
            inspect.getsource(mock_instance.func)))
        code = code + f'\nloc, ret = {mock_instance.func.__name__}(*args, **kwargs)'
        loc = {'args': args, 'kwargs': kwargs}
        exec(code, mock_instance.func.__globals__, loc)
        # Put execution locals into mock instance
        for l,v in loc['loc'].items():
            setattr(mock_instance, l, v)
        return loc['ret']

使用它:

import unittest
from unittest import mock

# This is the function you would like to test. It can be defined somewhere else
def foo(param_a, param_b=10):
    param_a = f'Hey {param_a}'  # Local only
    param_b += 20  # Local only 
    return 'bar'

# Define a test to validate what happens to local variables when you call that function
class SimpleTest(unittest.TestCase):

    @mock.patch(f'{__name__}.foo', autospec=True, side_effect=MockFunction(foo))
    def test_foo_return_and_local_params_values(self, mocked):
        ret = foo('A')
        self.assertEqual('Hey A', mocked.side_effect.param_a)
        self.assertEqual(30, mocked.side_effect.param_b)
        self.assertEqual('bar', ret)

正如我们所见,您可以使用模拟函数中的 side_effect 检查局部变量发生了什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    相关资源
    最近更新 更多