Gần đây tôi đã phải viết lại api còn lại của mình và chuyển đổi từ Flask sang Cherrypy (chủ yếu là do khả năng tương thích Python 3). Nhưng bây giờ tôi đang cố gắng để viết các bài kiểm tra đơn vị của mình, Flask có một ứng dụng thử nghiệm tích hợp thực sự tiện lợi, bạn có thể sử dụng để gửi các yêu cầu giả mạo tới ứng dụng của mình (mà không cần khởi động máy chủ). cho Cherrypy, là có chức năng như vậy, hoặc tôi bị mắc kẹt bắt đầu từ một máy chủ và thực hiện các yêu cầu thực tế chống lại nó?Unittesting cherrypy webapp
Trả lời
Theo như tôi biết, CherryPy không thực sự cung cấp một cơ sở cho loại thử nghiệm này (không có máy chủ đang chạy). Nhưng nó khá dễ dàng để làm điều đó dù sao (mặc dù nó dựa trên một số bên trong của CherryPy).
Dưới đây là một giới thiệu đơn giản:
from StringIO import StringIO
import unittest
import urllib
import cherrypy
local = cherrypy.lib.httputil.Host('127.0.0.1', 50000, "")
remote = cherrypy.lib.httputil.Host('127.0.0.1', 50001, "")
class Root(object):
@cherrypy.expose
def index(self):
return "hello world"
@cherrypy.expose
def echo(self, msg):
return msg
def setUpModule():
cherrypy.config.update({'environment': "test_suite"})
# prevent the HTTP server from ever starting
cherrypy.server.unsubscribe()
cherrypy.tree.mount(Root(), '/')
cherrypy.engine.start()
setup_module = setUpModule
def tearDownModule():
cherrypy.engine.exit()
teardown_module = tearDownModule
class BaseCherryPyTestCase(unittest.TestCase):
def webapp_request(self, path='/', method='GET', **kwargs):
headers = [('Host', '127.0.0.1')]
qs = fd = None
if method in ['POST', 'PUT']:
qs = urllib.urlencode(kwargs)
headers.append(('content-type', 'application/x-www-form-urlencoded'))
headers.append(('content-length', '%d' % len(qs)))
fd = StringIO(qs)
qs = None
elif kwargs:
qs = urllib.urlencode(kwargs)
# Get our application and run the request against it
app = cherrypy.tree.apps['']
# Let's fake the local and remote addresses
# Let's also use a non-secure scheme: 'http'
request, response = app.get_serving(local, remote, 'http', 'HTTP/1.1')
try:
response = request.run(method, path, qs, 'HTTP/1.1', headers, fd)
finally:
if fd:
fd.close()
fd = None
if response.output_status.startswith('500'):
print response.body
raise AssertionError("Unexpected error")
# collapse the response into a bytestring
response.collapse_body()
return response
class TestCherryPyApp(BaseCherryPyTestCase):
def test_index(self):
response = self.webapp_request('/')
self.assertEqual(response.output_status, '200 OK')
# response body is wrapped into a list internally by CherryPy
self.assertEqual(response.body, ['hello world'])
def test_echo(self):
response = self.webapp_request('/echo', msg="hey there")
self.assertEqual(response.output_status, '200 OK')
self.assertEqual(response.body, ["hey there"])
response = self.webapp_request('/echo', method='POST', msg="hey there")
self.assertEqual(response.output_status, '200 OK')
self.assertEqual(response.body, ["hey there"])
if __name__ == '__main__':
unittest.main()
Chỉnh sửa, tôi đã mở rộng câu trả lời này như một CherryPy recipe.
Dường như có một cách thay thế để thực hiện unittest. Tôi chỉ tìm thấy và kiểm tra các công thức sau đây hoạt động tốt với cherrypy 3.5.
http://docs.cherrypy.org/en/latest/advanced.html#testing-your-application
import cherrypy
from cherrypy.test import helper
class SimpleCPTest(helper.CPWebCase):
def setup_server():
class Root(object):
@cherrypy.expose
def echo(self, message):
return message
cherrypy.tree.mount(Root())
setup_server = staticmethod(setup_server)
def test_message_should_be_returned_as_is(self):
self.getPage("/echo?message=Hello%20world")
self.assertStatus('200 OK')
self.assertHeader('Content-Type', 'text/html;charset=utf-8')
self.assertBody('Hello world')
def test_non_utf8_message_will_fail(self):
"""
CherryPy defaults to decode the query-string
using UTF-8, trying to send a query-string with
a different encoding will raise a 404 since
it considers it's a different URL.
"""
self.getPage("/echo?message=A+bient%F4t",
headers=[
('Accept-Charset', 'ISO-8859-1,utf-8'),
('Content-Type', 'text/html;charset=ISO-8859-1')
]
)
self.assertStatus('404 Not Found')
Điều này chắc chắn là cách kiểm tra CherryPy được viết nội bộ. Nhưng điều đó có nghĩa là bắt đầu một máy chủ thực tế. Đó là tự động nhưng công thức của tôi đã cố gắng để cho thấy bạn có thể kiểm tra trình xử lý của bạn mà không cần một máy chủ đang chạy. Câu trả lời của bạn không chính xác hơn một chút về khía cạnh tích hợp mà tôi muốn nói. –
Cảm ơn, sẽ cung cấp cho một thử này ngày hôm nay. – Blubber
Làm việc như một nét duyên dáng, cảm ơn lần nữa :). – Blubber
@Sylvain: có cần gì đặc biệt cho '@ cherrypy.tools.json_in()' hỗ trợ không? 'cherrypy.request.json' trong testcases khiến đối tượng' AttributeError: 'Request' không có thuộc tính 'json'' – user1338062