首页 > 解决方案 > Python 测试:如何测试下游函数的正确函数调用?

问题描述

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)

功能:

您可能已经注意到,该outer函数实际上以inner错误的方式将参数传递给函数。这是因为我本可以决定更改inner函数的参数顺序并相应地更改test_inner,但忘记了outer函数调用inner函数。这不会被 捕获test_outer,因为它是内部一致的。我们只在生产中发现该inner函数会引发错误。

如何确保下游函数的所有测试都能捕获修改后的函数定义?

标签: pythonunit-testingtestingmockingpytest

解决方案


您可能需要一些集成测试或功能/端到端测试来捕获此类错误。测试单个单元模拟外部的一切是好的,因为您的单元测试独立于其他单元的错误。但是,正如您所发现的,您可能会在函数接口上遇到问题,因为您没有测试它们是否正确使用(即您可以说您没有测试单元集成)。所以这是你可以引入某种集成测试的地方(或端到端,取决于测试策略,你可以在搜索测试金字塔中阅读更多关于它的信息)。

您的案例的示例测试:

import pytest

@pytest.mark.functional
@pytest.mark.parametrize("name,age,expected", [("John", 18, "This is John. John is an adult."), ("Dave", 17, "This is Dave. Dave is a child")])
def test_outer_functionality(name, age, expected):
    assert outer(name, age) == expected

然后您还可以考虑是否要始终运行此类测试,或者例如每晚运行,并且在构建过程中只运行单元测试(pytest -v -m "not functional")。


推荐阅读