简体   繁体   English

django-webtest:如何测试“记住我”登录/浏览器关闭cookie?

[英]django-webtest: How to test remember-me login/expire-on-browser-close cookies?

How do you test login-remember-me functionality with webtest-django? 如何使用webtest-django测试“记住我”功能? In other words, how do you use webtest to test things that involve expire-on-browser-exit cookies? 换句话说,您如何使用Webtest来测试涉及浏览器退出cookie过期的事物? I have the below draft, but it's not working. 我有下面的草案,但是不起作用。 It seems that the server must be setup and torn down (as in the snippet below my testing class), but I'm not understanding how to integrate it. 似乎必须设置服务器并拆除服务器(如测试类下面的代码片段所示),但是我不了解如何集成服务器。 There does not seem to be much information out there on using StopableWSGIServer in this way. 关于以这种方式使用StopableWSGIServer信息似乎并不多。

Finally, I'm not even sure if this functionality is going to work at all in production, as it is my understanding that the major browsers ignore expire-cookie-on-browser-exit requests. 最后,我什至不确定该功能是否会在生产环境中完全正常工作,因为据我了解,主要浏览器会忽略浏览器中的expire-cookie-browser-exit请求。 Is that correct? 那是对的吗? It would be nice to see some references regarding it. 很高兴看到一些有关它的参考。

Doc top, imports, and class top: 文档顶部,导入和类顶部:

"""
Tests for the remember-me functionality on the login page.

DEPENDS ON TEST:     test__utilities.py
DEPENDED ON BY TEST: None

To run the tests in this file:
    1. source /home/jeffy/django_files/djauth_lifecycle_tutorial/part_05/dalt05_venv/bin/activate
    2. cd /home/jeffy/django_files/djauth_lifecycle_tutorial/part_05/djauth_root/
    3. python -Wall manage.py test auth_lifecycle.registration.test_login_remember_me.py

See the top of <link to .test__utilities> for more information.
"""
from auth_lifecycle.test__utilities import UserFactory, TEST_PASSWORD
from django.core.urlresolvers       import reverse
from django_webtest                 import WebTest
from webtest                        import http
from webtest.debugapp               import debug_app
from webtest.http                   import StopableWSGIServer
import os
import time

class TestLoginRememberMeFunctionality(WebTest):
    """Tests for authentication related views."""
    def setUp(self):
        self.user = UserFactory()

Don't remember test: 不记得测试了:

    def test_login_dont_remember(self):
        """
        Log a user in with the remember-me checkbox unchecked. This takes
        you to the main page. Because they're logged in, the main page
        contains a link to their profile page. Restart the browser, and
        the session should be expired. Therefore, instead of a link to the
        profile, there should be a link to login.
        """

        #Log a user in with the remember-me checkbox unchecked.
        form = self.app.get(reverse('login')).form
        form['username'] = self.user.username
        form['password'] = TEST_PASSWORD
        form['remember'] = 'unchecked'
        response_main_page = form.submit().follow()

        #This takes you to the main page.
        self.assertEqual(response_main_page.context['user'].username,
                         self.user.username)

        #Because they're logged in, the main page contains a link to their
        #profile page.
        self.assertIn(reverse('user_profile'), str(response_main_page.content))

        #Restart the browser,
        http.StopableWSGIServer.shutdown()
        time.sleep(2)   #Two seconds
        http.StopableWSGIServer.run()

        #and the session should be expired.
        self.assertFalse(
            response_login_page.context['user'].is_authenticated())

        #Therefore, instead of a link to the profile, there should be a
        #link to login.
        response_main_page = self.app.get(reverse('main_page'))
        assert reverse('login') in response_main_page

Remember test: 记住测试:

    def test_login_dont_remember(self):
        """
        Log a user in with the remember-me checkbox checked. This takes
        you to the main page. Because they're logged in, the main page
        contains a link to their profile page. Restart the browser, and
        the session should still be active. Therefore, the link to their
        profile should still be there.
        """

        #Log a user in with the remember-me checkbox checked.
        form = self.app.get(reverse('login')).form
        form['username'] = self.user.username
        form['password'] = TEST_PASSWORD
        form['remember'] = 'checked'
        response_main_page = form.submit().follow()

        #This takes you to the main page.
        self.assertEqual(response_main_page.context['user'].username,
                         self.user.username)

        #Because they're logged in, the main page contains a link to their
        #profile page.
        user_prfl_url = reverse('user_profile')
        self.assertIn(user_prfl_url, str(response_main_page.content))

        #Restart the browser,
        http.StopableWSGIServer.shutdown()
        time.sleep(2)   #Two seconds
        http.StopableWSGIServer.run()

        #and the session should still be active.
        self.assertFalse(
            response_login_page.context['user'].is_authenticated())

        #Therefore, the link to their profile should still be there.
        response_main_page = self.app.get(reverse('main_page'))
        assert user_prfl_url in response_main_page

Here is the snippet , but it's not clear to me how to use this in the test itself. 这是代码段 ,但是我不清楚如何在测试本身中使用它。

import os
from webtest import http
from webtest.debugapp import debug_app


def setup_test(test):
    server = http.StopableWSGIServer.create(debug_app)
    server.wait()
    path_to_html_file = os.path.join('tests', 'test.html')
    test.globs.update(
        server=server,
        your_url=server.application_url.rstrip('/') + '/form.html',
        path_to_html_file=path_to_html_file,
    )
setup_test.__test__ = False


def teardown_test(test):
    test.globs['server'].shutdown()
teardown_test.__test__ = False

FYI: Here is a fully-working test for a login page, ignoring the remember-me functionality. 仅供参考:这是登录页面的完整测试,忽略了“记住我”功能。 It's what I based the above on: 这就是我基于以上内容的原因:

"""
Tests for authentication related views.

DEPENDS ON TEST:     test__utilities.py
DEPENDED ON BY TEST: None

To run the tests in this file:
    1. source /home/myname/django_files/django_auth_lifecycle/djauth_venv/bin/activate
    2. cd /home/myname/django_files/django_auth_lifecycle/djauth_root/
    3. python -Wall manage.py test auth_lifecycle.registration.test_login_basic

See the top of <link to .test__utilities> for more information.
"""
from auth_lifecycle.test__utilities import UserFactory, TEST_PASSWORD
from django.core.urlresolvers       import reverse
from django_webtest                 import WebTest

class AuthTest(WebTest):
    """Tests for authentication related views."""
    def setUp(self):
        self.user = UserFactory()

Test function top: 测试功能顶部:

    def test_login(self):
        """
        Log a user in, which takes you to the main page. Because they're
        logged in, the main page contains a link to their profile page. Go
        to it. The profile page contains their email address and a link to
        logout. Click that link, which expires the session and takes you
        back to the login page.
        """

        #The following warning is given even before the test database is
        #created:
        #
        #/home/myname/django_files/django_auth_lifecycle/djauth_venv/lib/python3.4/site-packages/bs4/builder/_htmlparser.py:157:
        #DeprecationWarning: The value of convert_charrefs will become True in 3.5. You are encouraged to set the value explicitly.
        #
        #It is also given repeatedly during the test. I therefore believe
        #it is unrelated to our code.

Test function main section: 测试功能主要部分:

        #Log a user in,
        form = self.app.get(reverse('login')).form
        form['username'] = self.user.username
        form['password'] = TEST_PASSWORD
        response_main_page = form.submit().follow()

        #which takes you to the main page.
        self.assertEqual(response_main_page.context['user'].username,
                         self.user.username)

        #Because they're logged in, the main page contains a link to their
        #profile page.
        user_prfl_url = reverse('user_profile')
        self.assertIn(user_prfl_url, str(response_main_page.content))

        #Go to it. The profile page contains their email address
        response_profile_page = response_main_page.click(href=user_prfl_url)
        assert self.user.email in response_profile_page

        #and a link to logout
        logout_url = reverse('logout_then_login')
        self.assertIn(logout_url, str(response_profile_page.content))

        #Click that link, which expires the session and takes you back to
        #the login page.
        response_login_page = response_profile_page.click(href=logout_url).follow()
        self.assertIn('value="login"', str(response_login_page.content))

        self.assertFalse(
            response_login_page.context['user'].is_authenticated())

Cookies are saved in a session. Cookies将保存在会话中。 So 所以

self.app.set_user(user=None)
self.app.reset()

should unset the user and clear the client session (includes cookies). 应该取消用户设置并清除客户端会话(包括cookie)。 This way you can simulate a browser restart. 这样,您可以模拟浏览器重启。

http.StopableWSGIServer.shutdown() stops I think the server side ( wsgi=server-app connection ). http.StopableWSGIServer.shutdown()停止了我的服务器端工作( wsgi=server-app connection )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM