Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A pythonic way to code self writing test methods

I have the following test class defined. It uses exec which generally I dislike.

class FubarTest(unittest.TestCase):
    lst = [(True, True),
           (False, False)]
    for t in lst:
        function = """def test_{}_is_{}(self):
        self.assertTrue({} is {})
        """.format(t[0], t[1], t[0], t[1])
        exec function

When I run it (via py.test but that should not matter), I get this:

============================= test session starts ==============================
platform linux2 -- Python 2.7.3 -- pytest-2.3.4 -- /usr/bin/python
plugins: capturelog, cov, twisted, xdist

model/test/test_hframe5.py <- <string>:1: HFrame5Test.test_False_is_False PASSED
model/test/test_hframe5.py <- <string>:1: HFrame5Test.test_True_is_True PASSED
=========================== 2 passed in 0.49 seconds ===========================

So that the test are automatically created and have sensible names so if something fails, you know by the name of the method what has failed.

Clearly this is a much simplified example of what I want to do. I have a lot of test that will look like "do X, check that Y is True and Z is False" which could be easily coded with the above method. I could write three dozen copy-and-pasted methods but that just feels wrong -- breaking DRY.

Is there a more pythonic way of writing this code?

like image 774
Sardathrion - against SE abuse Avatar asked Sep 10 '26 23:09

Sardathrion - against SE abuse


1 Answers

You want parametrized tests. For example, with parameterizedtestcase:

from parameterizedtestcase import ParameterizedTestCase

class MyTests(ParameterizedTestCase):
    @ParameterizedTestCase.parameterize(
        ("value", "expected"),
        [
            (True, True),
            (False, False),
        ]
    )
    def test_identical(self, value, expected):
        self.assertTrue(value is expected)

Using py.test's parametrization framework:

import pytest

@pytest.mark.parametrize(
    ("value", "expected"),
    [
        (True, True),
        (False, False),
    ]
)
def test_identical(value, expected):
    assert value is expected
like image 175
ecatmur Avatar answered Sep 13 '26 15:09

ecatmur