gpt4 book ai didi

Python 测试 : How to test correct function calls of downstream functions?

转载 作者:行者123 更新时间:2023-12-04 16:45:29 27 4
gpt4 key购买 nike

TLDR:使用错误的参数顺序调用上游函数。我如何确保这是通过测试捕获的?
这是我的设置的最小示例:

# functions.py

def inner(age, name):
if age > 18:
return f'{name} is an adult.'
else:
return f'{name} is a child.'

def outer(name, age):
info = inner(name, age)
return f'This is {name}. {info}'


# tests.py

from functions import inner, outer
from unittest.mock import Mock, patch

def test_inner():
name, age = "John", 43
info = inner(age, name)
expected = "John is an adult."
assert info == expected

def test_outer():
name, age = "John", 43

mock_get_info = Mock()
mock_get_info.return_value = "Info"
patch_get_info = patch("functions.inner", new=mock_get_info)

with patch_get_info:
info = outer(name, age)
expected = 'This is John. Info'
assert info == expected
mock_get_info.assert_called_once_with(name, age)
功能:
  • 两个函数及其对应的测试。
  • inner函数生成一个字符串,由 test_inner 检查其正确性功能。
  • outer函数调用 inner函数并将其连接到它自己的字符串。正确的连接和 inner函数调用由 test_outer 检查功能。
  • 此外,除了这个最小的例子,inner函数可能会产生一个非常大的字符串,我不想在 test_outer 中明确检查它这就是为什么 inner返回值被模拟。

  • 您可能已经注意到, outer函数实际上将参数传递给 inner以错误的方式运行。这是因为我本可以决定改变 inner 的参数顺序。功能并更改了 test_inner相应地,但忘记了 outer函数调用 inner功能。这不是被 test_outer 捕获的,因为它是内部一致的。我们只在生产中发现, inner函数抛出错误。
    我如何确保下游函数的所有测试都能捕获修改后的函数定义?

    最佳答案

    我认为你在正确的轨道上。我相信您的测试没有捕获它,因为您断言了错误的顺序。mock_get_info.assert_called_once_with(name, age)应该:mock_get_info.assert_called_once_with(age, name)匹配 inner(age, name)签名。
    尽管如此,我认为更强大的方法是使用关键字参数,然后断言调用 args 是预期的字典。
    例如:

    # functions.py

    def outer(name, age):
    info = inner(age=age, name=name)
    return f'This is {name}. {info}'

    # tests
    def test_outer():
    name, age = "John", 43

    mock_get_info = Mock()
    mock_get_info.return_value = "Info"
    patch_get_info = patch("functions.inner", new=mock_get_info)

    with patch_get_info:
    info = outer(name, age)
    expected = 'This is John. Info'
    assert info == expected
    _, actual_kwargs = mock_get_info.call_args
    assert actual_kwargs == {'name': name, 'age': age}
    如果想更严格,可以强制执行 inner使用 * 只接受关键字参数[1]。但这也意味着您必须提供默认值,这取决于您的用例可能没有意义。
    例子:
    def inner(*, age=0, name='default'):
    if age > 18:
    return f'{name} is an adult.'
    else:
    return f'{name} is a child.'
    如果有人在不使用关键字参数的情况下调用它,Python 将在运行时引发异常。
    Traceback (most recent call last):
    File "/home/user/projects/so-test/functions.py", line 14, in <module>
    outer('user', 32)
    File "/home/user/projects/so-test/functions.py", line 9, in outer
    info = inner(age, name)
    TypeError: inner() takes 0 positional arguments but 2 were given
    IMO,犯这样的错误要困难得多 inner(age=name, name=age)比这个 inner(age, name) .
    [1] https://www.python.org/dev/peps/pep-3102/

    关于Python 测试 : How to test correct function calls of downstream functions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69130033/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com