【问题标题】:Django: change media root for testsDjango:更改媒体根以进行测试
【发布时间】:2011-05-08 19:54:16
【问题描述】:

我正在尝试为 Django 应用程序编写一些测试,包括文件上传。为此,我想将MEDIA_ROOT 临时更改为“myproject/fixtures/test_media/”。出于某种原因,这似乎阻止了 Django 找到固定装置。

我的测试用例看起来像

from django.conf import settings

class TestMedia(TestCase):
    fixtures = ['fixtures/test_data.json']

    def setUp(self):
        settings.MEDIA_ROOT = ''.join(
            [settings.PROJECT_PATH, '/fixtures/test_media/'])

    def test_photo_size(self):
        pass # Actually do something with the media files

由于某种原因,Django 无法加载固定装置,因此所有测试都失败了

安装夹具“fixtures/test_data.json”时出现问题:回溯(最后一次调用) ...

我做错了什么?

【问题讨论】:

标签: django unit-testing django-testing


【解决方案1】:

你有没有试过去掉setUp,看看能不能加载fixture?

此外,我认为您真的不需要更改 MEDIA_ROOT 来测试上传。您只需在 tearDown 中删除那些上传的文件即可恢复所有内容。

编辑:

您似乎正在生产环境中运行单元测试。老实说,这不是一个好主意。

但如果你必须这样做,使用另一个设置文件怎么样?像这样:

from mysite.settings import *

MEDIA_ROOT = '/what_ever_you_like'

并使用附加参数运行您的测试:

./manage.py test --settings=mysite.settings_for_test

【讨论】:

  • 是的,如果没有设置,灯具可以正常工作。当我更改 MEDIA_ROOT 时会出现问题。不过,我看不出 MEDIA_ROOT 应该如何影响灯具。
  • 至于使用原始MEDIA_ROOT的可能性,我不能这样做。我需要已经有一些用于测试的媒体文件,但我无法将它们保存在实际的媒体目录中。
  • 使用附加参数运行测试的可能性很有趣。我仍然不知道为什么在测试中更改媒体根会破坏固定装置。
  • Django 对这种情况和其他情况有一个设置覆盖,非常有用
【解决方案2】:

在setUp中不覆盖,只在运行TestCase子类的每个测试方法之前执行,在所有测试之前在模块中覆盖它。

from django.conf import settings
settings.MEDIA_ROOT += 'test'
【解决方案3】:

您可以覆盖测试的所有设置。它是一种更“Django”的方式 - 文档不鼓励直接更改 settings。在Django docs 中有一段关于它。

import os
from django.conf import settings
from django.test import TestCase, override_settings

@override_settings(MEDIA_ROOT=os.path.join(settings.PROJECT_PATH, 'fixtures/test_media/'))
class TestMedia(TestCase):
    fixtures = ['fixtures/test_data.json']

    def setUp(self):
         # any other setup stuff you need

关于覆盖设置的更多信息。您可以在整个测试中使用装饰器:

from django.test import TestCase, override_settings


@override_settings(LOGIN_URL='/other/login/')
class LoginTestCase(TestCase):

    def test_login(self):
        response = self.client.get('/sekrit/')
        self.assertRedirects(response, '/other/login/?next=/sekrit/')

或者您可以只覆盖部分代码的设置:

from django.test import TestCase

class LoginTestCase(TestCase):

    def test_login(self):

        # First check for the default behavior
        response = self.client.get('/sekrit/')
        self.assertRedirects(response, '/accounts/login/?next=/sekrit/')

        # Then override the LOGIN_URL setting
        with self.settings(LOGIN_URL='/other/login/'):
            response = self.client.get('/sekrit/')
            self.assertRedirects(response, '/other/login/?next=/sekrit/')

注意内联版本的不同语法。示例取自文档。

【讨论】:

    猜你喜欢
    • 2013-12-15
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2011-08-06
    相关资源
    最近更新 更多