高效测试 Python 结构模式匹配

Efficient Testing of Python Structural Pattern Matching

提问人:rhelmstedter 提问时间:11/6/2023 更新时间:11/9/2023 访问量:20

问:

我正在使用 python 3.10 构建命令行界面。该命令根据传递的选项调用不同的函数。假设可能的选项是 。save"A", "B", "C", "D", "E"

在 python 3.10 中使用结构模式匹配,我有类似于以下内容的代码:

# __main__.py

from my_module import func_A, func_B, func_C, func_D, func_E, get_from_cache

@cli.command()
def save(option):
    match option:
        case "A":
            to_save = func_A()
        case "B":
            to_save = func_B()
        case "C":
            to_save = func_C()
        case "D":
            to_save = func_D()
        case "E":
            to_save = func_E()
        case None:
            to_save = get_from_cache()
        case _:
            print("Not an Option")
            return

    # rest of save command

我分别为每个函数编写了测试。但是,Pytest Coverage 报告文件中缺少模式匹配语句。有没有一种pythonic(有效)的方法来测试传递给定选项会导致调用正确的函数?__main__.py

我能想到的唯一解决方案是模拟每个函数并为选项 A-E 编写测试。然后,随着选项的增加,我将不得不添加新的模拟和新的测试。

pytest 模式匹配 python-3.10

评论


答:

0赞 rhelmstedter 11/9/2023 #1

我已经想通了。我实际上可以使用参数化和模拟。由于模拟只是字符串,我只是连接了适当的字符串并使用内置的 typer 测试运行程序。

from unittest import mock
import pytest



@pytest.mark.parametrize(
    "func, option",
    [
        ("func_A", "A"),
        ("func_B", "B"),
        ("func_C", "C"),
        ("func_D", "D"),
        ("func_E", "E"),
        ("get_from_cache", None),
    ],
)
def test_matching(func, option):
    with mock.patch("src.__main__." + func) as save_mock:
        runner.invoke(cli, ["save", "--option", option])
        save_mock.assert_called_once()