Question

I'm learning pytest and I'm trying to use pytest.mark.parametrize for keyword arguments.

This is the simple example without pytest.mark.parametrize:

G = 10
H = 2

def f(g=G, h=H):
    return 5 * g + h

def test_f1():
    assert f(h=4) == 54
    assert f(g=20) == 102

And this is one of my unsuccessful trails using pytest.mark.parametrize. It doesn't work but it helps to understand what I would like to achieve:

import pytest

G = 10
H = 2

def f(g=G, h=H):
    return 5 * g + h  

@pytest.mark.parametrize("arg, expected", [
    ("h=4", 54),
    ("g=20", 102),
    ])

def test_f2(arg, expected):
    assert f(eval(arg)) == expected
Was it helpful?

Solution

The function f accepts keyword arguments, so you need to assign your test parameters to keywords. Luckily, Python provides a very handy way of passing keyword arguments to a function...the dictionary:

d = {'h': 4}
f(**d)

The ** prefix before d will "unpack" the dictionary, passing each key/value pair as a keyword argument to the function.

For your pytest example, this means you just need to replace the string parameter with a dictionary, and the eval in test_f2 with the keyword unpacker:

@pytest.mark.parametrize("arg,expected", [
    ({'h':4}, 54),
    ({'g':20}, 102),
    ])

def test_f2(arg, expected):
    assert f(**arg) == expected

OTHER TIPS

Extending Matthew's answer, for feeding both args and kwargs:

@pytest.mark.parametrize("args, kwargs, expecting", [
    ([100,10], {'is_test':True} , [90, 110]),
    ([100, .2], {'is_test':False} , [80, 120]),
])
def test_fn(args, kwargs, expecting):
    print(args, kwargs)
    assert fn(*args, **kwargs) == expecting

def fn(a, b, c=False):
   if c:
      return a-c, a+c
   else:
      return a - (a*c), a+ a*c
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top