Django test FileField using test fixtures
django, django-testing, filefield, python, unit-testing
Solution
Django provides a great way to write tests on FileFields without mucking about in the real filesystem - use a SimpleUploadedFile.
from django.core.files.uploadedfile import SimpleUploadedFile
my_model.file_field = SimpleUploadedFile('best_file_eva.txt', b'these are the contents of the txt file')
It's one of django's magical features-that-don't-show-up-in-the-docs :). However it is referred to here.
Problem
I'm trying to build tests for some models that have a FileField. The model looks like this: ``` class SolutionFile(models.Model): ''' A file from a solution. ''' solution = models.ForeignKey(Solution) file = models.FileField(upload_to=make_solution_file_path) ``` I have encountered two problems: When saving data to a fixture using `./manage.py dumpdata`, the file contents are not saved, only the file name is saved into the fixture. While I find this to be the expected behavior as the file contents are not saved into the database, I'd like to somehow include this information in the fixture for tests. I have a test case for uploading a file that looks like this: ``` def test_post_solution_file(self): import tempfile import os filename = tempfile.mkstemp()[1] f = open(filename, 'w') f.write('These are the file contents') f.close() f = open(filename, 'r') post_data = {'file': f} response = self.client.post(self.solution.get_absolute_url()+'add_solution_file/', post_data, follow=True) f.close() os.remove(filename) self.assertTemplateUsed(response, 'tests/solution_detail.html') self.assertContains(response, os.path.basename(filename)) ``` While this test works just fine, it leaves the uploaded file in the media directory after finishing. Of course, the deletion could be taken care of in `tearDown()`, but I was wondering if Django had another way of dealing with this. One solution I was thinking of was using a different media folder for tests which must be kept synced with the test fixtures. Is there any way to specify another media directory in `settings.py` when tests are being run? And can I include some sort of hook to dumpdata so that it syncs the files in the media folders? So, is there a more Pythonic or Django-specific way of dealing with unit tests involving files?