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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With