我想尝试按照 TDD 实践编写一些代码。我想基于 python 的 Tornado 框架创建简单的应用程序。我在网上查看人们如何为 tornado 编写测试并发现类似这样的内容:
class TestSomeHandler(AsyncHTTPTestCase):
def test_success(self):
response = self.fetch('/something')
self.assertEqual(response.code, 200)
如果我错了请纠正我,但它看起来更像是集成测试。相反,我正在尝试为一些虚拟处理程序编写简单的单元测试。比如这样一个:
class SomeHandler(BaseHandler):
@gen.coroutine
def get(self):
try:
from_date = self.get_query_argument("from", default=None)
datetime.datetime.strptime(from_date, '%Y-%m-%d')
except ValueError:
raise ValueError("Incorrect argument value for from_date = %s, should be YYYY-MM-DD" % from_date)
测试看起来像:
class TestSomeHandler(AsyncHTTPTestCase):
def test_no_from_date_param(self):
handler = SomeHandler()
with self.assertRaises(ValueError):
handler.get()
我知道我错过了 get()
应用程序和请求。尚未处理如何创建它们。
但我的问题是,人们是像第一个示例那样为 Tornado 编写测试,还是有人在应用程序内部调用处理程序?遵循什么模式?如果有人可以分享相关代码,那就太好了。
最佳答案
使用 AsyncHTTPTestCase
的模式主要是因为它为您制作了所有请求内容。当然也可以使用AsyncTestCase
,手动处理。
AsyncTestCase 示例。由于它将测试协程的 get
方法,我们将使用 gen_test
让它更简单一点。 RequestHandler
需要 Application
和 HTTPRequest
对象。因为我们没有传递应用程序的设置、ui_methods 等。Application
是一个简单的模拟。
from tornado.testing import AsyncTestCase, gen_test
from tornado.web import Application
from tornado.httpserver import HTTPRequest
from unittest.mock import Mock
class TestSomeHandler(AsyncTestCase):
@gen_test
def test_no_from_date_param(self):
mock_application = Mock(spec=Application)
payload_request = HTTPRequest(
method='GET', uri='/test', headers=None, body=None
)
handler = SomeHandler(mock_application, payload_request)
with self.assertRaises(ValueError):
yield handler.get()
恕我直言,使用哪种模式取决于您。我为 http-verb 方法(get、post 等)选择 AsyncHTTPTestCase
,因为:
- 更容易
- 此方法的使用者是 HTTP 客户端,因此断言响应代码、正文很有意义
- 它防止了过于复杂的方法
当然,处理程序的其余方法已使用 AsyncTestCase
进行测试。
关于python - 如何为 python tornado 应用程序编写单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35560415/