如何在自动化测试中初始化会话数据? (python 2.7,webpy,nesttests) [英] How to initialize session data in automated test? (python 2.7, webpy, nosetests)

查看:201
本文介绍了如何在自动化测试中初始化会话数据? (python 2.7,webpy,nesttests)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web应用程序,该应用程序使用会话数据来确定下一步要做的事情. 该应用程序正在浏览器中运行,并且将执行其应做的工作. 我想编写一个自动化测试,以便为将来的项目提供这些知识. 我过去的最后几个小时失败了,无法在测试中初始化(和移交)会话数据.同样,我在网络上也找不到这种基本情况的答案.

I have a web application that uses session data to determine what to do next. The application is running in the browser and does what it shall do. I'd like to write an automated test to have that knowledge for future projects. The last hours I failed miserable to initialize (and hand over) session data within my test. Also I couldn't find the answer for such a basic case on the web.

但是,这是应用程序代码:

However, here is the app code:

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()

代码本身不是问题的范围,但如有必要,我可以提供.

The code itself is not the scope of the question, but I can provide it, if necessary.

但是,page.html看起来像这样

However, page.html looks like this

$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>

在测试中使用以下内容:

In the test the following is used:

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才能起作用.

The first two tests work as expected. The third test is not working and I think it is because /page requires session.data to function.

我变得很生气:

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'

由于我不知道如何在测试中初始化会话/会话数据,所以我的问题是:我该怎么做,以便自动测试可以使用给出的会话信息来运行.

Since I don't know how to initialize the session/session data in the test, my question is: how can I do that, that the automated test can run with the give session information.

推荐答案

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

You don't need to initialise session in your test, since when you make app.request() call, your app will auto init session for you. The issue here is you don't maintain session id in your test ( your test is like a client as any browser ).

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

The solution is that when you make first app.request(), record the session id in the response headers. Then supply with the session id when you make subsequent app.request()

这是我的代码:

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

First I make a helper function in tests/tools.py to extract the session id from response header:

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')

这篇关于如何在自动化测试中初始化会话数据? (python 2.7,webpy,nesttests)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆