Python Django setUpTestData() 与 setUp()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29428894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 04:32:31  来源:igfitidea点击:

Django setUpTestData() vs. setUp()

pythondjangounit-testing

提问by rnevius

Django 1.8 shipped with a refactored TestCasewhich allows for data initialization at the class level using transactions and savepoints via the setUpTestData()method. This is in contrast to unittest's setUp()which runs before every single test method.

Django 1.8 附带了一个重构的 TestCase,它允许通过setUpTestData()方法使用事务和保存点在类级别进行数据初始化。这与 unittest 的setUp()形成对比,后者在每个测试方法之前运行。

Question: What is the use case for setUp()in Django now that setUpTestData()exists?

问题:现在存在的Django用例是什么?setUp()setUpTestData()

I'm looking for objective, high-level answers only, as otherwise this question would be too broad for Stack Overflow.

我只是在寻找客观的、高层次的答案,否则这个问题对于 Stack Overflow 来说太宽泛了。

采纳答案by Zack M. Davis

It's not uncommon for there to be set-up code that can't run as a class method. One notable example is the Django test client: you might not want to reuse the same client instance across tests that otherwise share much of the same data, and indeed, the client instances automatically included in subclasses of Django's SimpleTestCaseare created per test methodrather than for the entire class. Suppose you had a test from the pre-Django 1.8 world with a setUpmethod like this:

设置代码不能作为类方法运行的情况并不少见。一个值得注意的例子是 Django测试客户端:您可能不希望跨测试重用相同的客户端实例,否则这些测试会共享大部分相同的数据,实际上,自动包含在 Django 子类中的客户端实例SimpleTestCase按测试方法创建的,而不是为整个班级。假设你有一个来自 Django 1.8 之前的世界的测试,setUp方法是这样的:

    def setUp(self):
        self.the_user = f.UserFactory.create()
        self.the_post = f.PostFactory.create(author=self.the_user)
        self.client.login(
            username=self.the_user.username, password=TEST_PASSWORD
        )
        # ... &c.

You might tempted to modernize the test case by changing setUpto setUpTestData, slapping a @classmethoddecorator on top, and changing all the selfs to cls. But that will fail with a AttributeError: type object 'MyTestCase' has no attribute 'client'! Instead, you should use setUpTestDatafor the shared data and setUpfor the per-test-method client:

您可能想通过更改setUpsetUpTestData@classmethod在顶部添加装饰器并将所有selfs更改为来使测试用例现代化cls。但这将失败AttributeError: type object 'MyTestCase' has no attribute 'client'!相反,您应该setUpTestData用于共享数据和setUpper-test-method 客户端:

    @classmethod
    def setUpTestData(cls):
        cls.the_user = f.UserFactory.create()
        cls.the_post = f.PostFactory.create(author=cls.the_user)
        # ... &c.

    def setUp(self):
        self.client.login(
            username=self.the_user.username, password=TEST_PASSWORD
        )

Note: if you are wondering what that variable fis doing in the example code, it comes from factoryboy- a useful fixtures library for creating objects for your tests.

注意:如果您想知道示例代码中的变量f在做什么,它来自factoryboy- 一个有用的夹具库,用于为您的测试创建对象。

回答by Joachim Jablon

Caches issues. Even if Django gets better at providing test isolation with transaction rollback, caches are still generated and cleared manually.

缓存问题。即使 Django 在通过事务回滚提供测试隔离方面做得更好,缓存仍然是手动生成和清除的。

[edit] : SetUpTestData defines the state the DB will be restored to after each test, and does so with a method that is executed only once, transaction rollback being done behind the curtain by Django. This does not work for caches. If you want the cache to be the same for each test, you need to reset it between each test, thus the need for setUp. Django can rollback the DB but can't rollback everything.

[编辑] : SetUpTestData 定义了每次测试后数据库将恢复到的状态,并使用只执行一次的方法来实现,事务回滚由 Django 在幕后完成。这不适用于缓存。如果希望每次测试的缓存都相同,则需要在每次测试之间重置它,因此需要设置。Django 可以回滚数据库,但不能回滚所有内容。

(Thank you bryan-oakley for the suggestion )

(感谢 bryan-oakley 的建议)

回答by user2052130

Taken from this testing tutorial: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Testing#Views

取自本测试教程:https: //developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Testing#Views

setUpTestData() is called once at the beginning of the test run for class-level setup. You'd use this to create objects that aren't going to be modified or changed in any of the test methods.

setUpTestData() 在类级别设置的测试运行开始时调用一次。您将使用它来创建不会在任何测试方法中修改或更改的对象。

setUp() is called before every test function to set up any objects that may be modified by the test (every test function will get a "fresh" version of these objects).

在每个测试函数之前调用 setUp() 以设置任何可能被测试修改的对象(每个测试函数都将获得这些对象的“新”版本)。