sem*_*lon 5 python django unit-testing
我想知道是否有可能,并且最好不是太难,使用 Django DiscoverRunner 在每次测试之间删除我的媒体目录,包括在最开始和最后一次。我对 Django 1.7 中引入的新属性“test_suite”和“test_runner”特别感兴趣,想知道它们是否会让这个任务变得更容易。
我还想知道如何使测试特定的 MEDIA_ROOT 成为临时文件,目前我有一个名为“media”的常规 MEDIA_ROOT 和一个名为“media_test”的测试 MEDIA_ROOT,并且我在涉及媒体的每个测试类的设置和拆卸中使用 rmtree目录。我指定使用哪个 MEDIA_ROOT 的方式在我的 test.py 设置文件中,目前我只有:
MEDIA_ROOT = normpath(join(DJANGO_ROOT, 'media_test'))
Run Code Online (Sandbox Code Playgroud)
有没有办法可以将 MEDIA_ROOT 设置为名为“media”的临时目录?
Ric*_*oke 10
这个问题有点老了,我的答案来自Django 2.0和Python 3.6.6或更高版本。虽然我认为该技术也适用于旧版本,YMMV。
\n\n我认为这是一个比人们所认为的更重要的问题!当您编写良好的测试时,您需要快速生成测试文件或生成测试文件只是时间问题。无论哪种方式,您都有污染服务器或开发人员计算机的文件系统的危险。 两者都不可取!
\n\n我认为本页上的内容是最佳实践。如果您不关心推理,我将复制/粘贴下面的代码片段(稍后会有更多注释):
\n\n首先,让\xe2\x80\x99s 编写一个基本的、非常基本的模型
\n\nfrom django.db import models\n\nclass Picture(models.Model):\n picture = models.ImageField()\nRun Code Online (Sandbox Code Playgroud)\n\n然后,让\xe2\x80\x99s 编写一个非常非常基本的测试。
\n\nfrom PIL import Image\nimport tempfile\nfrom django.test import TestCase\nfrom .models import Picture\nfrom django.test import override_settings\n\ndef get_temporary_image(temp_file):\n size = (200, 200)\n color = (255, 0, 0, 0)\n image = Image.new("RGBA", size, color)\n image.save(temp_file, \'jpeg\')\n return temp_file\n\nclass PictureDummyTest(TestCase):\n\n @override_settings(MEDIA_ROOT=tempfile.TemporaryDirectory(prefix=\'mediatest\').name)\n def test_dummy_test(self):\n temp_file = tempfile.NamedTemporaryFile()\n test_image = get_temporary_image(temp_file)\n #test_image.seek(0)\n picture = Picture.objects.create(picture=test_image.name)\n print "It Worked!, ", picture.picture\n self.assertEqual(len(Picture.objects.all()), 1)\nRun Code Online (Sandbox Code Playgroud)\n\n我对代码片段进行了一项重要更改:TemporaryDirectory().name。原始片段使用gettempdir()。TemporaryDirectory函数每次调用时都会使用系统生成的名称创建一个新文件夹。该文件夹将被操作系统删除 - 但我们不知道什么时候!这样,我们每次运行都会得到一个新文件夹,因此不会出现名称冲突。请注意,我必须添加 .name 元素才能获取生成的文件夹的名称,因为 MEDIA_ROOT 必须是字符串。最后,我添加了prefix=\'mediatest\',这样所有生成的文件夹都很容易识别,以防我想在脚本中清理它们。
\n\n对您也可能有用的是,如何将设置覆盖轻松应用于测试类,而不仅仅是一个测试函数。详情请参阅本页。
\n\n另请注意,在本文后面的评论中,有些人展示了一种更简单的方法来获取临时文件名,而无需担心使用NamedTemporaryFile的媒体设置 (仅对不使用媒体设置的测试有效!)。
\nRichard Cooke 的答案有效,但使临时目录留在文件系统中,至少在 Python 3.7 和 Django 2.2 上是这样。通过使用 setUpClass、tearUpClass 的组合并覆盖测试方法中的设置可以避免这种情况。例如:
import tempfile
class ExampleTestCase(TestCase):
temporary_dir = None
@classmethod
def setUpClass(cls):
cls.temporary_dir = tempfile.TemporaryDirectory()
super(ExampleTestCase, cls).setUpClass()
@classmethod
def tearDownClass(cls):
cls.temporary_dir = None
super(ExampleTestCase, cls).tearDownClass()
def test_example(self):
with self.settings(MEDIA_ROOT=self.temporary_dir.name):
# perform a test
pass
Run Code Online (Sandbox Code Playgroud)
这样临时文件就会立即删除,您也无需担心临时目录的名称。(当然,如果您愿意,您仍然可以prefix在调用 tempfile.TemporaryDirectory 时使用该参数)
我发现有效的一个解决方案是简单地在setUp/tearDown中删除它,我更愿意找到某种方法让它自动应用于所有测试,而不是必须将逻辑放在涉及媒体的每个测试文件中,但我还没有还知道怎么做。
我使用的代码是:
from shutil import rmtree
from django.conf import settings
from django.test import TestCase
class MyTests(TestCase):
def setUp(self):
rmtree(settings.MEDIA_ROOT, ignore_errors=True)
def tearDown(self):
rmtree(settings.MEDIA_ROOT, ignore_errors=True)
Run Code Online (Sandbox Code Playgroud)
我在setUp和tearDown中都这样做的原因是,如果我只在setUp中使用它,我最终可能会得到一个挥之不去的media_test目录,即使它不会意外地签入到GitHub(它位于.gitignore中)它仍然在我的项目资源管理器中占用不必要的空间,我只是不想让它坐在那里占用空间。如果我只将其放在拆解中,那么如果我中途退出测试,并且它尝试运行涉及媒体的测试,而已终止的测试中的媒体仍然存在,那么我就有可能导致问题。
| 归档时间: |
|
| 查看次数: |
2130 次 |
| 最近记录: |