【问题标题】:Django LiveServerTestCase: User created in in setUpClass method not available in test_method?Django LiveServerTestCase:在 setUpClass 方法中创建的用户在 test_method 中不可用?
【发布时间】:2013-02-05 17:44:51
【问题描述】:

我正在使用 Django 1.4 的 LiveServerTestCase 进行 Selenium 测试,但在使用 setUpClass 类方法时遇到了问题。据我了解MembershipTests.setUpClass 在单元测试运行之前运行一次。

我已经在MembershipTests.setUpClass 中添加了将用户添加到数据库的代码,但是当我运行MembershipTests.test_signup 测试时,没有将用户添加到测试数据库中。 我做错了什么?我希望我在 setUpClass 中创建的用户在所有单元测试中都可用。

如果我将用户创建代码放在MembershipTests.setUp 并运行MembershipTests.test_signup 我可以看到用户,但不希望在每个单元测试之前运行这个setUp。如您所见,我使用自定义 LiveServerTestCase 类在我的所有测试中添加基本功能 (test_utils.CustomLiveTestCase)。我怀疑这与我的问题有关。

提前致谢。

test_utils.py

from selenium.webdriver.firefox.webdriver import WebDriver
from django.test import LiveServerTestCase

class CustomLiveTestCase(LiveServerTestCase):

    @classmethod
    def setUpClass(cls):
        cls.wd = WebDriver()
        super(CustomLiveTestCase, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        cls.wd.quit()
        super(CustomLiveTestCase, cls).tearDownClass()

tests.py

from django.contrib.auth.models import User
from django.test.utils import override_settings
from test_utils import CustomLiveTestCase 
from test_constants import *

@override_settings(STRIPE_SECRET_KEY='xxx', STRIPE_PUBLISHABLE_KEY='xxx')
class MembershipTests(CustomLiveTestCase):

    fixtures = [
        'account_extras/fixtures/test_socialapp_data.json',
        'membership/fixtures/basic/plan.json',
    ]

    def setUp(self):
        pass

    @classmethod
    def setUpClass(cls):
        super(MembershipTests, cls).setUpClass()
        user = User.objects.create_user(
            TEST_USER_USERNAME,
            TEST_USER_EMAIL,
            TEST_USER_PASSWORD
        )

    def test_signup(self):
        print "users: ", User.objects.all()

【问题讨论】:

    标签: python django selenium django-testing


    【解决方案1】:

    数据库在每个测试方法上被拆除并重新加载,而不是在测试类上。因此,您的用户每次都会丢失。在setUp 而不是setUpClass 中执行此操作。

    【讨论】:

    • 感谢您的回答。这是否意味着this answer 不正确还是我误解了它?是否不可能在一个地方创建测试记录以供测试类中的所有测试方法使用?我想在所有测试方法中使用相同的用户记录,setUp 最终会在每个测试方法之前重新创建它。
    【解决方案2】:

    由于您使用的是 LiveServerTestCase,它几乎与 TransactionTestCase 相同,后者为每个运行的测试用例创建和销毁数据库(截断表)。

    所以你真的不能用 LiveServerTestCase 做全局数据。

    【讨论】:

    • 任何想法,我如何使用 LiveServerTestCase 创建用户然后登录?在 setUp 中使用 SQLite 数据库在 :memory: 中创建帐户不起作用,即使我手动提交。
    【解决方案3】:

    您应该能够按如下方式使用TestCase.setUpTestData(对您的基类稍作更改):

    test_utils.py

    from selenium.webdriver.firefox.webdriver import WebDriver
    from django.test import LiveServerTestCase, TestCase
    
    class CustomLiveTestCase(LiveServerTestCase, TestCase):
    
        @classmethod
        def setUpClass(cls):
            cls.wd = WebDriver()
            super(CustomLiveTestCase, cls).setUpClass()
    
        @classmethod
        def tearDownClass(cls):
            cls.wd.quit()
            super(CustomLiveTestCase, cls).tearDownClass()
    

    tests.py

    from django.contrib.auth.models import User
    from django.test.utils import override_settings
    from test_utils import CustomLiveTestCase
    from test_constants import *
    
    @override_settings(STRIPE_SECRET_KEY='xxx', STRIPE_PUBLISHABLE_KEY='xxx')
    class MembershipTests(CustomLiveTestCase):
    
        fixtures = [
            'account_extras/fixtures/test_socialapp_data.json',
            'membership/fixtures/basic/plan.json',
        ]
    
        @classmethod
        def setUpTestData(cls):
            super(MembershipTests, cls).setUpTestData()
            user = User.objects.create_user(
                TEST_USER_USERNAME,
                TEST_USER_EMAIL,
                TEST_USER_PASSWORD
            )
    
        def test_signup(self):
            print "users: ", User.objects.all()
    

    您可以从 MembershipTests 中的TestCase 继承而不是更改基类,但是每次需要测试数据时都必须这样做。

    请注意,我还删除了def setUp: pass,因为这会破坏事务处理。

    查看此线程以获取更多详细信息:https://groups.google.com/forum/#!topic/django-developers/sr3gnsc8gig

    如果您在使用此解决方案时遇到任何问题,请告诉我!

    【讨论】:

    • setUpTestData 是为每个类创建一次对象的理想方式。
    • 我试过了,但是数据没有出现在浏览器中——但是它可以在模型查询中访问。 selenium 服务器是否可以访问与正在使用的模型类不同的数据库?!
    • @cammil 是的,不幸的是比我在这里介绍的要复杂一些。有时间我会更新我的答案,但是实时服务器测试用例会产生一个不同的进程来与浏览器通信,因此无法查看您的事务。为测试用例切换 TransactionTestCase 是高级修复,但管理数据存在复杂性。我的计划(如果我能做到的话)是编写一个新的数据库驱动程序,该驱动程序在单独的进程中运行并共享事务,但这有点工作。
    • 或者,如果您的数据库支持 UNCOMMITTED READ 隔离级别,请使用该级别并避免让您非常头疼。
    • @DylanYoung 基于这篇文章atodorov.org/blog/2017/12/26/… 我将覆盖self._fixture_setup 来创建数据。到目前为止,它似乎正在发挥作用。在您看来,这是所有弊端中最小的吗?
    猜你喜欢
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多