I am using pytest 3.2.2 and Django 1.11.5 on Python 3.6.2 on Windows.
The following code
import django.test
import pytest
class ParametrizeTest:
@pytest.mark.parametrize("param", ["a", "b"])
def test_pytest(self, param):
print(param)
assert False
works as expected:
scratch_test.py::ParametrizeTest::test_pytest[a] FAILED scratch_test.py::ParametrizeTest::test_pytest[b] FAILED
But as soon as I change it to use Django's SimpleTestCase
,
like this:
class ParametrizeTest(django.test.SimpleTestCase):
...
it fails with
TypeError: test_pytest() missing 1 required positional argument: 'param'
Can anybody explain why? And what to do against it?
(I actually even need to use django.test.TestCase
and access the database.)
I have the following pytest plugins installed:
plugins: random-0.2, mock-1.6.2, django-3.1.2, cov-2.5.1
but turning any one of them (or all of them) off via -p no:random
etc. does not help.
Setting Up pytest for a Django ProjectThe pytest-django plugin is maintained by the pytest development team. It provides useful tools for writing tests for Django projects using pytest .
pytest.mark. django_db([transaction=False, reset_sequences=False, databases=None]) This is used to mark a test function as requiring the database. It will ensure the database is set up correctly for the test. Each test will run in its own transaction which will be rolled back at the end of the test.
parametrize : parametrizing test functions. Parameter values are passed as-is to tests (no copy whatsoever). For example, if you pass a list or a dict as a parameter value, and the test case code mutates it, the mutations will be reflected in subsequent test case calls.
The Django test class is a unittest.TestCase
subclass.
Parametrization is unsupported and this is documented under the section pytest features in unittest.TestCase
subclasses:
The following pytest features do not work, and probably never will due to different design philosophies:
If you need parametrized tests and pytest runner, your best bet is to abandon the unittest style - this means move the setup/teardown into fixtures (pytest-django
plugin has already implemented the hard parts for you), and use module level functions for your tests.
Thanks, wim, for that helpful answer. RTFM, once again.
For clarity, here is the formulation that will work (equivalent to a test inheriting from TestCase
, not just SimpleTestCase
).
Make sure you have pytest-django
installed and then do:
import pytest
@pytest.mark.django_db
class ParametrizeTest:
@pytest.mark.parametrize("param", ["a", "b"])
def test_pytest(self, param):
print(param)
assert False
(BTW: Funnily, one reason why I originally decided to use pytest
was that
the idea of using plain test functions instead of test methods appealed to me;
I like lightweight approaches.
But now I almost exclusively use test classes and methods anyway,
because I prefer the explicit grouping of tests they provide.)
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