在 Django 中使用 LiveServerTestCase 时使用代码登录

Posted

技术标签:

【中文标题】在 Django 中使用 LiveServerTestCase 时使用代码登录【英文标题】:Login with code when using LiveServerTestCase with Django 【发布时间】:2014-04-25 00:46:21 【问题描述】:

所以我有一个 Selenium 功能测试套件。我已经在一些测试中测试了登录/注册功能,方法是将 Selenium 客户端导航到注册页面,输入用户名和密码,然后告诉 Selenium 使用相同的凭据登录。现在我想测试站点“需要登录”区域的其他部分,而不必告诉 Selenium 单击并在测试浏览器中输入文本。

换句话说,我想使用这样的东西(我在视图单元测试中使用得很好):

self.client = Client()  
self.user = User.objects.create_user('temporary', 'temporary@gmail.com', 'temporary')  
self.user.save()  
self.client.login(username='temporary', password='temporary')

在我的 Selenium 测试中,因此我不必在每个测试中重复冗长的手动登录过程(因为我已经在之前的测试中测试过登录系统,如前所述)

截至目前,我只是为每个需要登录的测试复制并粘贴“登录流程”Selenium 说明。这会导致我的测试每次多花 5-6 秒,这会使我的 function_tests.py 文件非常臃肿。

我所有的谷歌搜索都将我带到了教我如何使用 Selenium 测试登录的页面。

提前致谢。

【问题讨论】:

【参考方案1】:

您无法从 selenium 驱动程序登录用户。没有一些技巧是不可能的。

但是您可以通过将每个 TestCase 移至 setUp 方法来登录一次。

您还可以通过创建从 LiveServerTestCase 继承的类来避免复制粘贴。

更新

这段代码对我有用:

self.client.login(username=superuser.username, password='superpassword') #Native django test client
cookie = self.client.cookies['sessionid']
self.browser.get(self.live_server_url + '/admin/')  #selenium will set cookie domain based on current page domain
self.browser.add_cookie('name': 'sessionid', 'value': cookie.value, 'secure': False, 'path': '/')
self.browser.refresh() #need to update page for logged in user
self.browser.get(self.live_server_url + '/admin/')

【讨论】:

只是为了澄清,“您还可以通过创建从 LiveServerTestCase 继承的类来避免复制粘贴。”你的意思是你会创建一个继承自 LiveServerTestCase 的 MyBaseTest 类,然后从 MyBaseTest 继承你的实际测试类,对吗? 这个答案非常适合清理代码,但我的测试仍然需要大约一分钟的时间才能执行,因为使用 facebook 登录需要额外的步骤去 facebook.com。哦,好吧。 这对我不起作用,self.client.cookies 似乎是空的,我在 Django 1.8 上得到了一个 KeyError 使用这种方法,使用request.user 表明它是AnonymousUser。不完全是我们想要的…… 必须先找到班级Client - 如果其他人有同样的问题:from django.test import Client【参考方案2】:

在 Django 1.8 中,可以创建预认证会话 cookie 并将其传递给 Selenium。

为此,您必须:

    在您的后端创建一个新会话; 使用新创建的会话数据生成一个 cookie; 将该 cookie 传递给您的 Selenium 网络驱动程序。

会话和 cookie 创建逻辑如下:

# create_session_cookie.py
from django.conf import settings
from django.contrib.auth import (
    SESSION_KEY, BACKEND_SESSION_KEY, HASH_SESSION_KEY,
    get_user_model
)
from django.contrib.sessions.backends.db import SessionStore

def create_session_cookie(username, password):

    # First, create a new test user
    user = get_user_model()
    user.objects.create_user(username=username, password=password)

    # Then create the authenticated session using the new user credentials
    session = SessionStore()
    session[SESSION_KEY] = user.pk
    session[BACKEND_SESSION_KEY] = settings.AUTHENTICATION_BACKENDS[0]
    session[HASH_SESSION_KEY] = user.get_session_auth_hash()
    session.save()

    # Finally, create the cookie dictionary
    cookie = 
        'name': settings.SESSION_COOKIE_NAME,
        'value': session.session_key,
        'secure': False,
        'path': '/',
    
    return cookie

现在,在您的 Selenium 测试中:

#selenium_tests.py

# assuming self.webdriver is the selenium.webdriver obj.
from create_session_cookie import create_session_cookie

session_cookie = create_session_cookie(
    username='test@email.com', password='top_secret'
)

# visit some url in your domain to setup Selenium.
# (404 pages load the quickest)
self.driver.get('your-url' + '/404-non-existent/')

# add the newly created session cookie to selenium webdriver.
self.driver.add_cookie(session_cookie)

# refresh to exchange cookies with the server.
self.driver.refresh()

# This time user should present as logged in.
self.driver.get('your-url')

【讨论】:

我试过了,显然 cookie 域不匹配。 我得到的错误(Django 1.10 Python 3.5)是:Failed to set the 'cookie' property on 'Document': Cookies are disabled inside 'data:' URLs. 这对我有用...我将 'create_session_cookie(self)' 方法添加到基本 selenium 类并在测试中使用它...如果有人对如何在这里发表评论感到困惑,我会添加一个完整的例子。 如果我想要现有用户的会话 cookie,我将如何修改此代码? @F.ENoelNfebe & tilacog @n00b 你知道 cookie 的名称吗?或如何得到它?如果您知道名称,就很容易获取 cookie。【参考方案3】:

GitHub 上有一个用于此目的的库:django-selenium-login

【讨论】:

以上是关于在 Django 中使用 LiveServerTestCase 时使用代码登录的主要内容,如果未能解决你的问题,请参考以下文章

Django:在管理界面中使用 TinyMCE 4

在 django-crispy 按钮名称中使用 django 模板变量

使用 django-import-export 在 django 迁移中的外键

如何使用 Django Rest Framework 在 Django 中进行操作日志记录

如何在 Django 中使用模式?

使用 Django 注册应用程序在 Django 中处理帐户/个人资料的好地方在哪里?