【问题标题】:How to initialize session data in automated test? (python 2.7, webpy, nosetests)如何在自动化测试中初始化会话数据? (python 2.7、webpy、nosetests)
【发布时间】:2015-02-01 05:49:03
【问题描述】:

我有一个 Web 应用程序,它使用会话数据来确定下一步要做什么。 应用程序正在浏览器中运行并执行它应该执行的操作。 我想编写一个自动化测试来为未来的项目提供这些知识。 在我的测试中初始化(和移交)会话数据的最后几个小时我很痛苦。我在网上也找不到这样一个基本案例的答案。

但是,这里是应用代码:

import web
from project import code

urls = (
    "/page", "/Page",
    "/", "Index"
    )

app = web.application(urls, globals())

# Little hack so that debug mode works with sessions.
if web.config.get('_session') is None:
    store = web.session.DiskStore('sessions')
    session = web.session.Session(app, store, initializer={'data':None})
    web.config._session = session
else:
    session = web.config._session

render = web.template.render('templates/', base="layout")

class Index():
    def GET(self):
    # This is used to "setup" the session with starting values.
    # code.START contains a dict "whatnext"
    # that assigns keywords to information what to do next.
    # It also contains a attribute "name"
    session.data = code.START
    web.seeother("/page")

class Page(object):
    def GET(self):
    if session.data:
        return render.page(data=session.data)
    else:
    # This is here in case someone puts "/page" directly as URL.
    # wrong_page just has a link to "/" and everything will be fine
    # from there on.
        return render.wrong_page()

    def POST(self):
    form = web.input(action=None)
    if form.action in session.data.whatnext:
        # The method .go returns what to do next according to the
        # keywords.
        session.data = session.data.go(form.action)

    web.seeother("/page")

if __name__ == "__main__":
    app.run()

代码本身不是问题的范围,但如果需要,我可以提供。

然而,page.html 看起来像这样

$def with (data)

Something something dependend on the data.

$if data.name == "finished":
    <p><a href="/"> Again? </a></p>
$else:
    <p>
    <form action="/page" method="POST">
    <input type="text" name="action"> <input type="SUBMIT">
    </form>
    </p>

在测试中使用了以下内容:

from nose.tools import *
import re

def assert_response(resp, contains=None, status="200"):

    assert status in resp.status, "Excpected response %r not in %r" % (status, 
resp.status)

    if status == "200":
    assert resp.data, "Response data is empty."

    if contains:
    assert contains in resp.data, "Response does not contain %r" % contains

这是实际测试:

from nose.tools import *
from bin.app import app # the code above
from tests.tools import assert_response

def test_redirect():
    # Check that we get a 303 on the / URL
    resp = app.request("/")
    assert_response(resp, status="303")

def test_wrong_page():
    # test the first GET request to /game
    resp = app.request("/page")
    assert_response(resp, contains="Go here instead")

def test_page
    # test that we get expected values
    what_to_do = {'action' : 'foo'}
    resp = app.request("/page", method="POST", data=what_to_do)
    assert_response(resp, contains="something specific according to foo")

前两个测试按预期工作。 第三个测试不起作用,我认为这是因为 /page 需要 session.data 才能运行。

我得到了输出:

Traceback (most recent call last):
  File "/.../nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/.../tests/app_tests.py", line 19, in test_page
    assert_response(resp, contains="something specific according to foo")
  File "/.../tests/tools.py", line 17, in assert_response
    resp.status)
AssertionError: Excpected response '200' not in '500 Internal Server Error'

由于我不知道如何在测试中初始化会话/会话数据,我的问题是:我该如何做到这一点,自动化测试可以使用给定的会话信息运行。

【问题讨论】:

    标签: python web.py nosetests


    【解决方案1】:

    您不需要在测试中初始化会话,因为当您调用 app.request() 时,您的应用会自动为您初始化会话。这里的问题是您没有在测试中维护会话 ID(您的测试就像任何浏览器一样的客户端)。

    解决方案是,当你第一次创建 app.request() 时,在响应头中记录会话 id。然后在您进行后续 app.request() 时提供会话 ID

    这是我的代码:

    首先我在 tests/tools.py 中创建一个辅助函数来从响应头中提取会话 ID:

    def get_session_id(resp):
        cookies_str = resp.headers['Set-Cookie']
        if cookies_str:
            for kv in cookies_str.split(';'):
                if 'webpy_session_id=' in kv:
                    return kv
    

    然后将测试写为:

    def test_session():
        resp = app.request('/')
        session_id = get_session_id(resp)
    
        resp1 = app.request('/game', headers={'Cookie':session_id})
        assert_response(resp1, status='200', contains='Central Corridor')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-10
      • 2012-02-11
      • 2011-07-27
      • 1970-01-01
      • 2023-03-19
      • 2015-12-17
      • 2014-12-29
      • 1970-01-01
      相关资源
      最近更新 更多