Django ImageField Testing
One of the puzzles of testing in Django are models who have an ImageField(). In Odeon we use ImageKit (with some custom spec handling), so tests should cover all the other images derived from the original uploaded one.
Starting from:
- #models.py
- class ProfileAvatar(IKImage):
- original_image = models.ImageField(upload_to=AVATAR_PATH)
- class IKOptions:
- spec_module = 'mymodule.specs'
- cache_dir = MY_CACHE_PATH
- image_field = 'original_image'
-
- #forms.py
- class AjaxAvatarForm(forms.Form):
- image = forms.ImageField()
-
- #views.py
- def upload(request):
- form = UploadImageForm(request.POST, request.FILES)
- if not form.is_valid():
- #Return some error
- image = form.cleaned_data.get('image')
- ProfileAvatar.objects.create(image = image)
Let's test it:
First of all, using a separate folder for testing prevents from mixing test content with production content.
- from django.test import TestCase
- class UserprofileTest(TestCase):
- def test_upload(self):
- count = ProfileAvatar.objects.count()
- image_path = settings.MEDIA_ROOT + 'testdata/image.png'
- f = open(image_path, "r")
- resp = self.client.post(url, {'image': f})
- f.close()
- self.assertEquals(count, 1)
Second of all, check that all the image specs are generated successfully. _ik.specs is an generated list of all these specs, each spec having a .name() method which returns the actual spec name.
- # check validity
- avatar = ProfileAvatar.objects.all()[0]
- for spec in avatar._ik.specs:
- spec_name = spec.name()
- img_url = getattr(avatar, spec_name).url
- self.assertTrue(img_url.find('_' + spec_name) > -1)
Last step: Your mom was right to say "Clean your room!", so remove test data.
- # clean images
- avatar.delete()
- self.assertEquals(count, 0)
The end result is less headache and chasing after faulty images. If, for some rare reason, one image can't be converted, put it in /testdata/ and run the test with it, tweaking your logic to cater for that.
Category: Django



Leave a Comment :
Leave a Comment