Py.test: parametrize test cases from classes Py.test: parametrize test cases from classes python python

Py.test: parametrize test cases from classes


If you subclass from unittest.TestCase, your test methods cannot have additional arguments. If you simply subclass from object, it will work (though you'll have to use regular assert statements instead of the TestCase.assertEqual methods.

import unittestimport pytestclass TestCase(object):    @pytest.mark.parametrize("test_input,expected", [    ("3+5", 8),    ("2+4", 6),    ("6*9", 42),    ])    def test_1(self, a, b):        assert eval(a) == b

At that point though, it kind of begs the question why you're using classes instead of just defining functions, since the test will essentially be the same, but require less overall boilerplate and code.


Finally and considering the reply by @Brendan Abel and comments I managed to succeed in what I was intended to do by doing:

class TestCase(object):    @parameterized.expand([    ("negative", -1.5, -2.0),    ("integer", 1, 1.0),    ("large fraction", 1.6, 1),    ])    def test_floor(self, name, input, expected):        assert_equal(math.floor(input), expected)    @parameterized.expand([    ("3+5", 8),    ("2+4", 6),    ("6*9", 42),    ])    def test_1(self, a, b):        assert_equal(eval(a), b)

Then I am able to execute the tests by the nosetests command:

  nosetests -v --with-id class.py


I don't know if this was the case 5 years ago, but these days you can use parameterized (https://pypi.org/project/parameterized/) with pytest to decorate test methods on a test class, yes including unittest.TestCase, without having to resort to nose. E.g.:

from unittest import TestCasefrom parameterized import parameterizedclass SomeTestCase(TestCase):    @parameterized.expand([        (1, 2),        ('a', 'b')    ])    def test_something(self, param1, param2):        ...

The only gotcha, but you better remember this, is that the decorator will generate new test methods for each listed input parameter, so you will not be able to run your original test method directly by specifying it on the command line. E.g. pytest some_test.py::SomeTestCase::test_something won't work anymore (because your test method now expects two parameters). However, you can call the generated methods directly, for which you can get the name from either the pytest error output when you run the whole TestCase or by doing a pytest --collect-only.