我最近不得不重寫我們的其餘api,並將Flask切換到Cherrypy(主要歸功於Python 3的兼容性)。但是現在我試圖寫我的單元測試,Flask有一個非常漂亮的內置測試客戶端,您可以使用它向您的應用程序發送虛假請求(無需啓動服務器)。我找不到任何類似的功能對於Cherrypy,有沒有這樣的功能,還是我堅持啓動一個服務器,並針對它做實際的請求?單元測試cherrypy webapp
10
A
回答
18
據我所知,CherryPy確實沒有提供這種類型的測試(沒有運行服務器)的設施。但儘管如此,它仍然很容易(儘管它依賴於CherryPy的一些內部)。
這裏有一個簡單的展示:
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()
編輯,我已經延長這個答案作爲CherryPy recipe。
2
看來,有一種替代方法來執行單元測試。 我剛剛發現並檢查以下配方,可以在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')
+0
這肯定CherryPy測試是如何在內部編寫的。但是這意味着啓動一臺實際的服務器。這是自動的,但我的配方試圖顯示你可以測試你的處理程序,而無需運行服務器。你的迴應並不是不正確的,只是在我說的集成方面多一點。 –
相關問題
- 1. 單元測試Cherrypy HTTPRedirect。
- 2. MongoDB單元測試
- 3. 測試一個webapp
- 4. Maven中的單元測試需要訪問src/main/webapp目錄
- 5. Vue webapp運行單元測試時出錯
- 6. 單元測試測試
- 7. CakePHP測試 - 單元測試
- 8. 單元測試
- 9. 單元測試
- 10. 單元測試
- 11. 單元測試
- 12. 單元測試
- 13. 單元測試
- 14. 單元測試
- 15. 單元測試
- 16. 單元測試
- 17. 單元測試
- 18. 單元測試
- 19. 單元測試
- 20. 單元測試
- 21. 單元測試()
- 22. 單元測試
- 23. 單元測試
- 24. 單元測試
- 25. Simple單元測試簡單單元測試
- 26. 爲Websphere 7測試webapp
- 27. 單元測試Url.Action
- 28. 當單元測試
- 29. 單元測試Observable.interval
- 30. 單元測試GetManifestResourceStream
謝謝,今天要去這個給一試。 – Blubber
工程就像一個魅力,再次感謝:)。 – Blubber
@Sylvain:'@ cherrypy.tools.json_in()'支持有什麼特別需要?測試用例中的'cherrypy.request.json'導致'AttributeError:'Request'對象沒有屬性'json'' – user1338062