Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wire up cls.setUpTestData for class level fixtures #972

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions pytest_django/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,21 @@ class PytestDjangoTestCase(test_case_class): # type: ignore[misc,valid-type]
if _databases is not None:
databases = _databases

if VERSION >= (3, 2):
from django.test.testcases import TestData
# If the test class has defined a Django-style setUpTestData,
# arrange for it to be called by the DjangoTestCase classmethods that we're calling here.
if request.cls and hasattr(request.cls, 'setUpTestData'):
def wrappedSetUpTestData(klass):
pre_attrs = request.cls.__dict__.copy()
request.cls.setUpTestData()
for name, value in request.cls.__dict__.items():
if value is not pre_attrs.get(name):
setattr(request.cls, name, TestData(name, value))

# Re-bind our new classmethod to the class we're attaching it to using the function's descriptor.
PytestDjangoTestCase.setUpTestData = wrappedSetUpTestData.__get__(PytestDjangoTestCase, PytestDjangoTestCase)

PytestDjangoTestCase.setUpClass()
if VERSION >= (4, 0):
request.addfinalizer(PytestDjangoTestCase.doClassCleanups)
Expand Down
18 changes: 18 additions & 0 deletions tests/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,21 @@ def test_db_access_in_test_module(self, django_testdir) -> None:
'or the "db" or "transactional_db" fixtures to enable it.'
]
)


# TODO: If this is omitted, the error is confusing:
# AttributeError: 'TestDatabaseClassAutoCaching' object has no attribute 'item_1'
@pytest.mark.django_db
class TestDatabaseClassAutoCaching:

@classmethod
def setUpTestData(cls):
cls.item_1 = Item.objects.create()

# But it's not idiomatic for pytest:
def test_foo_c(self):
self.item_1.name = 'foo'
self.item_1.save()

def test_bar_c(self):
assert not self.item_1.name