Python - CherryPy 测试 - 设置会话数据?
Python - CherryPy testing - set session data?
当 运行 针对 CherryPy 服务器进行 pytest 单元测试时,使用 cherrypy.helper.CPWebCase sub-class,如何为会话对象设置数据?我试过只调用 cherrypy.session['foo']='bar'
就像我真的在一个 cherrypy 调用中一样,但这只是给了一个 "AttributeError: '_Serving' object has no attribute 'session'"
作为参考,测试用例可能看起来像这样(从 the CherryPy Docs 中提取并稍作编辑):
import cherrypy
from cherrypy.test import helper
from MyApp import Root
class SimpleCPTest(helper.CPWebCase):
def setup_server():
cherrypy.tree.mount(Root(), "/", {'/': {'tools.sessions.on': True}})
setup_server = staticmethod(setup_server)
def check_two_plus_two_equals_four(self):
#<code to set session variable to 2 here>
# This is the question: How do I set a session variable?
self.getPage("/")
self.assertStatus('200 OK')
self.assertHeader('Content-Type', 'text/html;charset=utf-8')
self.assertBody('4')
处理程序可能看起来像这样(或其他任何东西,这没有任何区别):
class Root:
@cherrypy.expose
def test_handler(self):
#get a random session variable and do something with it
number_var=cherrypy.session.get('Number')
# Add two. This will fail if the session variable has not been set,
# Or is not a number
number_var = number_var+2
return str(number_var)
可以安全地假设配置是正确的,并且会话按预期工作。
当然,我可以编写一个 CherryPy 页面,将键和值作为参数,然后设置指定的会话值,并从我的测试代码中调用它(编辑:我测试过这个,它确实有效)。然而,这似乎很笨拙,如果我走那条路,我真的想将它限制为仅以某种方式进行测试。
您要实现的目标通常称为 mocking。
虽然 运行ning 测试您通常希望 'mock' 您使用具有相同接口(鸭子输入)的虚拟对象访问的一些资源。这可以通过猴子修补来实现。为了简化这个过程,您可以使用 unittest.mock.patch
作为上下文管理器或 method/function 装饰器。
请在下面找到带有上下文管理器选项的工作示例:
==> MyApp.py <==
import cherrypy
class Root:
_cp_config = {'tools.sessions.on': True}
@cherrypy.expose
def test_handler(self):
# get a random session variable and do something with it
number_var = cherrypy.session.get('Number')
# Add two. This will fail if the session variable has not been set,
# Or is not a number
number_var = number_var + 2
return str(number_var)
==> cp_test.py <==
from unittest.mock import patch
import cherrypy
from cherrypy.test import helper
from cherrypy.lib.sessions import RamSession
from MyApp import Root
class SimpleCPTest(helper.CPWebCase):
@staticmethod
def setup_server():
cherrypy.tree.mount(Root(), '/', {})
def test_check_two_plus_two_equals_four(self):
# <code to set session variable to 2 here>
sess_mock = RamSession()
sess_mock['Number'] = 2
with patch('cherrypy.session', sess_mock, create=True):
# Inside of this block all manipulations with `cherrypy.session`
# actually access `sess_mock` instance instead
self.getPage("/test_handler")
self.assertStatus('200 OK')
self.assertHeader('Content-Type', 'text/html;charset=utf-8')
self.assertBody('4')
现在您可以安全地运行测试如下:
$ py.test -sv cp_test.py
============================================================================================================ test session starts =============================================================================================================
platform darwin -- Python 3.5.2, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 -- ~/.pyenv/versions/3.5.2/envs/cptest-pyenv-virtualenv/bin/python3.5
cachedir: .cache
rootdir: ~/src/cptest, inifile:
collected 2 items
cp_test.py::SimpleCPTest::test_check_two_plus_two_equals_four PASSED
cp_test.py::SimpleCPTest::test_gc <- ../../.pyenv/versions/3.5.2/envs/cptest-pyenv-virtualenv/lib/python3.5/site-packages/cherrypy/test/helper.py PASSED
当 运行 针对 CherryPy 服务器进行 pytest 单元测试时,使用 cherrypy.helper.CPWebCase sub-class,如何为会话对象设置数据?我试过只调用 cherrypy.session['foo']='bar'
就像我真的在一个 cherrypy 调用中一样,但这只是给了一个 "AttributeError: '_Serving' object has no attribute 'session'"
作为参考,测试用例可能看起来像这样(从 the CherryPy Docs 中提取并稍作编辑):
import cherrypy
from cherrypy.test import helper
from MyApp import Root
class SimpleCPTest(helper.CPWebCase):
def setup_server():
cherrypy.tree.mount(Root(), "/", {'/': {'tools.sessions.on': True}})
setup_server = staticmethod(setup_server)
def check_two_plus_two_equals_four(self):
#<code to set session variable to 2 here>
# This is the question: How do I set a session variable?
self.getPage("/")
self.assertStatus('200 OK')
self.assertHeader('Content-Type', 'text/html;charset=utf-8')
self.assertBody('4')
处理程序可能看起来像这样(或其他任何东西,这没有任何区别):
class Root:
@cherrypy.expose
def test_handler(self):
#get a random session variable and do something with it
number_var=cherrypy.session.get('Number')
# Add two. This will fail if the session variable has not been set,
# Or is not a number
number_var = number_var+2
return str(number_var)
可以安全地假设配置是正确的,并且会话按预期工作。
当然,我可以编写一个 CherryPy 页面,将键和值作为参数,然后设置指定的会话值,并从我的测试代码中调用它(编辑:我测试过这个,它确实有效)。然而,这似乎很笨拙,如果我走那条路,我真的想将它限制为仅以某种方式进行测试。
您要实现的目标通常称为 mocking。
虽然 运行ning 测试您通常希望 'mock' 您使用具有相同接口(鸭子输入)的虚拟对象访问的一些资源。这可以通过猴子修补来实现。为了简化这个过程,您可以使用 unittest.mock.patch
作为上下文管理器或 method/function 装饰器。
请在下面找到带有上下文管理器选项的工作示例:
==> MyApp.py <==
import cherrypy
class Root:
_cp_config = {'tools.sessions.on': True}
@cherrypy.expose
def test_handler(self):
# get a random session variable and do something with it
number_var = cherrypy.session.get('Number')
# Add two. This will fail if the session variable has not been set,
# Or is not a number
number_var = number_var + 2
return str(number_var)
==> cp_test.py <==
from unittest.mock import patch
import cherrypy
from cherrypy.test import helper
from cherrypy.lib.sessions import RamSession
from MyApp import Root
class SimpleCPTest(helper.CPWebCase):
@staticmethod
def setup_server():
cherrypy.tree.mount(Root(), '/', {})
def test_check_two_plus_two_equals_four(self):
# <code to set session variable to 2 here>
sess_mock = RamSession()
sess_mock['Number'] = 2
with patch('cherrypy.session', sess_mock, create=True):
# Inside of this block all manipulations with `cherrypy.session`
# actually access `sess_mock` instance instead
self.getPage("/test_handler")
self.assertStatus('200 OK')
self.assertHeader('Content-Type', 'text/html;charset=utf-8')
self.assertBody('4')
现在您可以安全地运行测试如下:
$ py.test -sv cp_test.py
============================================================================================================ test session starts =============================================================================================================
platform darwin -- Python 3.5.2, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 -- ~/.pyenv/versions/3.5.2/envs/cptest-pyenv-virtualenv/bin/python3.5
cachedir: .cache
rootdir: ~/src/cptest, inifile:
collected 2 items
cp_test.py::SimpleCPTest::test_check_two_plus_two_equals_four PASSED
cp_test.py::SimpleCPTest::test_gc <- ../../.pyenv/versions/3.5.2/envs/cptest-pyenv-virtualenv/lib/python3.5/site-packages/cherrypy/test/helper.py PASSED