I want to use django setUpTestData to prepare some heavy data shared between multiples unit tests. Instances of my Model are created with some file fields.
However, from one test to another, file contents are not renewed, it has side effects between my tests
here is a minimalist example :
models.py
from django.db import models
class MyModel(models.Model):
my_file = models.FileField(upload_to="tests/")
test.py
from django.core.files.base import ContentFile
from django.test import TestCase
from core.models import MyModel
class Test(TestCase):
@classmethod
def setUpTestData(cls):
cls.instance = MyModel()
cls.instance.my_file.save("file.txt", ContentFile("Hello from setUpTestData"))
def test_a(self):
with open(self.instance.my_file.path, "r") as fp:
self.assertEqual(fp.read(), "Hello from setUpTestData")
self.instance.my_file.save("file.txt", ContentFile("Modified data"))
def test_b(self):
with open(self.instance.my_file.path, "r") as fp:
self.assertEqual(fp.read(), "Hello from setUpTestData")
self.instance.my_file.save("file.txt", ContentFile("Modified data"))
Running any of the two test alone works, however running one after the other one fails:
AssertionError: 'Modified datatUpTestData' != 'Hello from setUpTestData'
- Modified datatUpTestData
Hello from setUpTestData
How to ensure that file are correctly reset? Am I concerned by theses lines from the documentation ?
Objects assigned to class attributes in setUpTestData() must support creating deep copies with copy.deepcopy()
I feel like fileField should be handled by default by Django but it doesn't work, what should I do? Should I try to override __deepcopy__
for my models? Modifying my code for testing purpose is a bad pattern.
CodePudding user response:
I've found a solution by using setUp and tearDown
def setUp(self) : # copy original files
shutil.copytree(settings.MEDIA_ROOT, "/tmp/tests", dirs_exist_ok=True)
def tearDown(self) : # restore original files
shutil.copytree("/tmp/tests", settings.MEDIA_ROOT, dirs_exist_ok=True)