Reputation: 325
I need to pass class members as parameters to pytest.mark.parametrize
.
The following code does not work (I've used simple members strings, but in my case they are complex and constructed):
import pytest
class TestSmth(object):
def setup_class(cls):
cls.a = "a"
cls.b = "b"
cls.c = "c"
@pytest.mark.parametrize("test_input,expected", [
(self.a, "a"),
(self.b, "b"),
(self.c, "c")
])
def test_members(test_input, expected):
assert test_input == expected
Is it possible to achieve such result? Or something similar?
Upvotes: 2
Views: 1406
Reputation: 325
Found solution in pytest docs -> "Parametrizing test methods through per-class configuration¶"
#!/usr/bin/env python
import pytest
def pytest_generate_tests(metafunc):
# called once per each test function
funcarglist = metafunc.cls.params[metafunc.function.__name__]
argnames = sorted(funcarglist[0])
metafunc.parametrize(argnames, [[funcargs[name] for name in argnames]
for funcargs in funcarglist])
class Complex(object):
def __init__(self):
self.a = "a"
class TestBase(object):
A = Complex()
params = {
'test_a' : [dict (test_input=A)]
}
def test_a(self, test_input):
assert test_input.a == "a"
It's ugly but it serves it's purpose.
Upvotes: 1
Reputation: 39370
This code doesn't work because Python decorators don't work that way. It is unrelated to the actual data in the test parameters. If you were the one writing the decorator, you could solve it by manually passing the instance, but this depends on the decorator itself doing the right thing.
As it stands, pytest decorators simply store the test data to be verified - and so you need to provide the data that's accessible by the time the desugared code is being ran, like so:
o = TestSmth()
o.setup_class()
@pytest.mark.parametrize("test_input,expected", [
(o.a, "a"),
(o.b, "b"),
(o.c, "c")
])
def test_members(test_input, expected):
assert test_input == expected
I don't believe there are any inherent limitations to the data types being passed to those functions. If you still find that too limiting, pytest has a substantial support for custom parametrization schemes. Without the details of your actual use (rather than a mock example), it's hard to tell what would fit the problem best.
Upvotes: 2