
在Python中,函数经常会定义带有默认值的参数,例如:
def get_user(user_id, adults_only=False):
"""
根据用户ID获取用户信息,可选地限制为成人用户。
:param user_id: 用户ID
:param adults_only: 布尔值,如果为True则只返回成人用户,默认为False。
"""
# 实际实现细节未展示
if user_id == 1:
return "none" if adults_only else "child"
elif user_id == 2:
return "adult" if adults_only else "adult"
return None当我们需要测试adults_only参数的不同值(True、False)以及其默认行为时,通常会遇到一些挑战。使用unittest配合parameterized.expand可以很好地处理参数化测试,但对于默认参数的测试,直接的参数化往往无法覆盖。
例如,一个典型的参数化测试可能如下:
import unittest
from parameterized import parameterized
# 假设 get_user 函数已定义如上
# 为了测试方便,我们模拟一个 child 对象
class MockChild:
def __init__(self, id):
self.id = id
class TestGetUser(unittest.TestCase):
def setUp(self):
self.child = MockChild(1) # 模拟一个ID为1的用户
@parameterized.expand([
(True, "none"),
(False, "child")
])
def test_get_child_explicit_args(self, adults_only, expected):
"""测试显式传递 adults_only 参数的情况。"""
actual = get_user(self.child.id, adults_only=adults_only)
self.assertEqual(expected, actual)然而,上述测试并未直接测试adults_only参数使用其默认值(即不传递该参数)的情况。为了覆盖这个场景,我们可能需要额外编写一个独立的测试方法:
立即学习“Python免费学习笔记(深入)”;
def test_get_child_default_arg(self):
"""测试 adults_only 参数使用默认值的情况。"""
actual = get_user(self.child.id) # 不传递 adults_only 参数
self.assertEqual("child", actual)这种分离的测试方式虽然有效,但引入了代码重复,并且当测试场景增多时,会使得测试套件变得冗长且不易维护。理想情况下,我们希望能够将所有相关测试场景(包括默认参数)合并到一个参数化测试中。
为了解决上述问题,我们可以采用一种策略:在parameterized.expand中引入一个“哨兵值”(sentinel value),例如None,来表示我们希望测试函数使用其默认参数的情况。然后,在测试方法内部,根据这个哨兵值动态地构建传递给目标函数的关键字参数。
以下是具体的实现:
import unittest
from parameterized import parameterized
# 假设 get_user 函数和 MockChild 类已定义如上
class TestGetUserUnified(unittest.TestCase):
def setUp(self):
self.child = MockChild(1) # 模拟一个ID为1的用户
@parameterized.expand([
(True, "none"), # 显式传递 adults_only=True
(False, "child"), # 显式传递 adults_only=False
(None, "child") # 使用 None 作为哨兵值,表示测试默认参数
])
def test_get_child_unified(self, adults_only_param, expected):
"""
统一测试 get_user 函数,包括 adults_only 参数的显式值和默认值。
"""
user_id = self.child.id
kwargs = {}
# 如果 adults_only_param 不是哨兵值 None,则将其添加到关键字参数字典中
if adults_only_param is not None:
kwargs["adults_only"] = adults_only_param
# 调用目标函数,使用 **kwargs 解包动态参数
actual = get_user(user_id, **kwargs)
self.assertEqual(expected, actual)
# 运行测试
if __name__ == '__main__':
unittest.main(argv=['first-arg-is-ignored'], exit=False)在这个统一的测试方法中:
通过采用这种结合哨兵值和动态关键字参数的策略,我们能够有效地将函数默认参数的测试场景整合到参数化测试中,从而提高测试代码的简洁性、可维护性和可扩展性,使得测试套件更加精炼和高效。
以上就是Python函数默认参数的统一测试策略的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号