【问题标题】:How can I test a form with FileField in Django?如何在 Django 中使用 FileField 测试表单?
【发布时间】:2017-01-21 22:47:52
【问题描述】:

我有这个表格:

# forms.py

class BookForm(forms.ModelForm):

    class Meta:
        model = Book
        fields = ['book_title', 'language', 'author', 'release_year', 'genre', 'ages', 'cover']

字段类型: 其中book_titleauthorCharFieldlanguagegenre 也是CharField 但对于他们我有选择选项,release_yearagesIntegerField,最后一个@987654 @是FileField

选择选项:

# models.py
ENGLISH = 'english'
LANGUAGE_CHOICES = (
    (ENGLISH, 'English'),
)

ADVENTURE = 'adventure'
GENRE_CHOICES = (
    (ADVENTURE, 'Adventure'),
)

现在:我想测试这个表单,但我不知道如何测试cover,这是我的表单测试。

# test_forms.py
from .. import forms
from django.core.files import File


class TestBookForm:
    def test_form(self):
        form = forms.BookForm(data={})
        assert form.is_valid() is False, 'Should be invalid if no data is given'

        img = File(open('background'))

        data = {'book_title': 'Lord Of The Rings',
                'language': 'english',
                'author': 'J. R. R. Tolkien',
                'release_year': 1957,
                'genre': 'adventure',
                'ages': 16,
                'cover': img}

        form = forms.BookForm(data=data)

        assert form.is_valid() is True

我试过了: 从 django.core.files.uploadedfile 导入 SimpleUploadedFile

img = open('background')
uploaded = SimpleUploadedFile(img.name, img.read())
{'cover': uploaded}

这是我的错误:

E       assert False is True
E        +  where False = <bound method BaseForm.is_valid of <BookForm bound=True, valid=False, fields=(book_title;language;author;release_year;genre;ages;cover)>>()
E        +    where <bound method BaseForm.is_valid of <BookForm bound=True, valid=False, fields=(book_title;language;author;release_year;genre;ages;cover)>> = <BookForm bound=True, valid=False, fields=(book_title;language;author;release_year;genre;ages;cover)>
.is_valid

注意:我使用Python 3.5Django 1.9.4,并使用py.test开始测试。

更新:如果我尝试open('background.jpg') 不起作用。 错误: FileNotFoundError: [Errno 2] No such file or directory: 'background.jpg' 我解决了这个问题

更新 2:

我尝试使用mock

from django.core.files import File
import mock

file_mock = mock.MagicMock(spec=File, name='FileMock')
file_mock.name = 'test1.jpg'

{'cover': file_mock}

我尝试使用InMemoryUploadedFile

from io import BytesIO
from django.core.files.uploadedfile import InMemoryUploadedFile
from PIL import Image

im = Image.new(mode='RGB', size=(200, 200))  # create a new image using PIL
im_io = BytesIO()  # a StringIO object for saving image
im.save(im_io, 'JPEG')  # save the image to im_io
im_io.seek(0)  # seek to the beginning

image = InMemoryUploadedFile(
    im_io, None, 'random-name.jpg', 'image/jpeg', None, None
)

{'cover': image}

我修复了图像的路径。

【问题讨论】:

    标签: python django python-3.x django-forms django-testing


    【解决方案1】:

    我发现问题这是我的代码:

    #test_forms.py
    from .. import forms
    from django.core.files.uploadedfile import SimpleUploadedFile
    import os
    
    TEST_DIR = os.path.dirname(os.path.abspath(__file__))
    TEST_DATA_DIR = os.path.join(TEST_DIR, 'data')
    
    
    class TestBookForm:
        def test_form(self):
            form = forms.BookForm(data={})
            assert form.is_valid() is False, 'Should be invalid if no data is given'
    
            test_image_path = os.path.join(TEST_DATA_DIR, 'background.jpg')
    
            data = {'book_title': 'Lord Of The Rings',
                    'language': 'english',
                    'author': 'J. R. R. Tolkien',
                    'release_year': 1957,
                    'genre': 'adventure',
                    'ages': 16}
    
            with open(test_image_path, 'rb') as f:
                form = forms.BookForm(data=data, files={'cover': SimpleUploadedFile('cover', f.read())})
                assert form.is_valid(), 'Invalid form, errors: {}'.format(form.errors)
    

    更多信息在docs

    【讨论】:

      【解决方案2】:

      您可以在存储库中创建一个文件,使其物理存在,或者为您的文件模拟测试。

      试试THIS


      编辑

      尝试传递完整路径

      import os
      from django.conf import settings
      file_path = os.path.join(settings.BASE_DIR, your_folder, background.jpg)
      

      【讨论】:

      • 在我将文件放入我的包并尝试放入cover 字段后,我尝试制作一个假文件但不起作用。这是我最后的选择?我的文件必须是 jpgpngjpeg
      • 你把你的 background.jpg 文件放在哪里了?它必须到位,您可以从中运行测试。所以假设你从主文件夹运行测试,background.jpg 必须在那里
      • 我的test_formstests 包中,我的background.jpg 在同一个包中。但是当我尝试open('background.jpg') 时,它不起作用……但open('background') 起作用……
      • 正如我所说,将文件放在主文件夹中。或者,将完整路径传递给文件。我已经在我的答案中添加了代码。检查它伴侣
      • 这适用于文件,但我尝试了一个新断言:assert 'cover' not in form.errors 并且 ERRORE assert 'cover' not in {'cover': ['This field is required.']}
      猜你喜欢
      • 2011-01-29
      • 2011-01-17
      • 1970-01-01
      • 2017-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      相关资源
      最近更新 更多