画像ファイルをローカルに置いてもアップロードのテストできるが、テストコード内で完結させるため。
サンプルアプリ作成
(python2.7, django1.6)
$ django-admin.py startproject core
$ mv core photo_book
$ cd photo_book
$ python manage.py startapp photos
$ mkdir -p static/upload # 画像を保存するディレクトリ
core/
settings.py
# 追加箇所のみ
IINSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'photos', # 追加
)
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/') # 追加
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
from photos.views import ImageCreateView
urlpatterns = patterns(
'',
url(r'^images/$', ImageCreateView.as_view(), name='images'),
url(r'^admin/', include(admin.site.urls)),
)
photos/
モデル
models.py
from django.db import models
class Photo(models.Model):
image = models.ImageField(upload_to='upload')
フォーム
forms.py
from django import forms
class PhotoForm(forms.Form):
image = forms.ImageField()
ビュー
views.py
from django.views.generic.edit import CreateView
from photos.models import Photo
class ImageCreateView(CreateView):
model = Photo
success_url = '/'
テスト
test.py
from StringIO import StringIO
from django.core.urlresolvers import reverse
from django.test import TestCase
from photos.models import Photo
class CreateImageTest(TestCase):
def test_post(self):
url = reverse("images")
dummy_image = StringIO(
'GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00'
'\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;'
)
dummy_image.name = 'dummy_image.gif'
dummy_image.content_type = 'image/gif'
response = self.client.post(url, {'image': dummy_image})
self.assertEqual(response.status_code, 302)
# dbに保存されたか確認
self.assertEqual(Photo.objects.count(), 1)
# 保存された画像とアップロードしたダミー画像が同じか確認
uploaded_image = StringIO(open(Photo.objects.last().image._get_path(), 'rb').read())
self.assertEqual(uploaded_image.getvalue(), dummy_image.getvalue())
テスト実行
$ python manage.py test
Creating test database for alias 'default'...
.
----------------------------------------------------------------------
Ran 1 test in 0.042s
OK
Destroying test database for alias 'default'...