【问题标题】:Generate in-memory image for Django testing为 Django 测试生成内存中的图像
【发布时间】:2012-01-26 13:17:08
【问题描述】:

是否可以生成内存中的图像用于测试目的?

这是我当前的代码:

  def test_issue_add_post(self):
        url = reverse('issues_issue_add')
        image = 'cover.jpg'
        data = {
            'title': 'Flying Cars',
            'cover': image,
        }
        response = self.client.post(url, data)
        self.assertEqual(response.status_code, 302)

【问题讨论】:

  • 我对 django 一无所知,但是 client.post 对图像的期望是什么?像对象一样的文件?一个字节串?

标签: python django django-testing


【解决方案1】:

要生成 200x200 的纯红色测试图像:

import Image
size = (200,200)
color = (255,0,0,0)
img = Image.new("RGBA",size,color)

要将其转换为类似文件的对象,则:

import StringIO
f = StringIO.StringIO(img.tostring())

http://effbot.org/imagingbook/image.htm

【讨论】:

    【解决方案2】:

    Jason 接受的答案在 Django 1.5 中对我不起作用

    假设生成的文件要从单元测试中保存到模型的 ImageField,我需要更进一步,创建一个 ContentFile 以使其工作:

    from PIL import Image
    from StringIO import StringIO
    
    from django.core.files.base import ContentFile
    
    image_file = StringIO()
    image = Image.new('RGBA', size=(50,50), color=(256,0,0))
    image.save(image_file, 'png')
    image_file.seek(0)
    
    django_friendly_file = ContentFile(image_file.read(), 'test.png')
    

    【讨论】:

      【解决方案3】:

      因此,如果 client.post 需要一个类似对象的文件,您可以创建一个示例图像(如果您想在测试后直观地检查结果)或者只是制作一个 1px png 并从控制台读取它

      open('1px.png', 'rb').read()
      

      在我的情况下被丢弃了

      image_data = '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\tpHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x07tIME\x07\xdb\x0c\x17\x020;\xd1\xda\xcf\xd2\x00\x00\x00\x0cIDAT\x08\xd7c\xf8\xff\xff?\x00\x05\xfe\x02\xfe\xdc\xccY\xe7\x00\x00\x00\x00IEND\xaeB`\x82'
      

      然后你可以使用StringIO,它作为一个像对象一样的文件,所以上面的图像是

      from StringIO import StringIO
      
      def test_issue_add_post(self):
          ...
          image = StringIO(image_data)
          ...
      

      您将拥有一个包含图像数据的类似对象的文件

      【讨论】:

        【解决方案4】:

        在 Python 3 中

        from io import BytesIO
        from PIL import Image
        
        image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0))
        file = BytesIO(image.tobytes())
        file.name = 'test.png'
        file.seek(0)
        #  + + + django_friendly_file = ContentFile(file.read(), 'test.png') # year 2019, django 2.2.1  -works 
        

        【讨论】:

        • 在 Pyton 3.6 中,PIL 和 Image.version = 1.1.7,我不得不将 image.tostring() 更改为 image.tobytes()
        【解决方案5】:

        感谢 Eduardo 的帮助,我得到了一个可行的解决方案。

        from StringIO import StringIO
        import Image
        
        file = StringIO()
        image = Image.new("RGBA", size=(50,50), color=(256,0,0))
        image.save(file, 'png')
        file.name = 'test.png'
        file.seek(0)
        

        【讨论】:

        • 我需要在 2021 年改用 BytesIO
        【解决方案6】:

        您使用过 PIL 模块吗?它可以让您操作图像 - 并且还应该允许创建。

        事实上,这是一个博客条目,其中包含一些代码 http://bradmontgomery.blogspot.com/2008/07/django-generating-image-with-pil.html

        不知道你的测试机器是否有网络连接,但你也可以从谷歌随机下载图片来改变测试数据?

        【讨论】:

          猜你喜欢
          • 2018-08-10
          • 2015-11-22
          • 2016-02-13
          • 1970-01-01
          • 2012-05-22
          • 2011-03-31
          • 1970-01-01
          • 2015-03-30
          • 1970-01-01
          相关资源
          最近更新 更多