Efficient Testing of Python Structural Pattern Matching

64 Views Asked by At

I am building a command line interface using python 3.10. The save command, calls different functions based on the option passed. Let's say possible options are "A", "B", "C", "D", "E".

Using structural pattern matching in python 3.10 I have code similar to the following:

# __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

I have written tests for each function separately. However, Pytest Coverage reports that the pattern matching statements are missing in the __main__.py file. Is there a pythonic (efficient) way to test that passing a given option results in the correct function being called?

The only solution I can think of would be to mock each function and write a test for options A-E. Then as options increase, I would have to add a new mock and new test.

1

There are 1 best solutions below

0
On

I have figured it out. I can actually use parametrization and mocking. Since the mocking is just strings, I just concatenated the appropriate string and used the built-in typer test runner.

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()