如何为python龙卷风应用程序编写单元测试?

时间:2016-02-22 17:47:56

标签: python unit-testing tornado

我想尝试在TDD练习后编写一些代码。我想基于python的龙卷风框架创建简单的应用程序。我正在通过互联网查看人们如何为龙卷风编写测试并找到类似这样的内容:

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()申请和请求。尚未处理如何创建它们。

但我的问题是,人们是否像第一个例子那样为龙卷风编写测试,或者有人在app中调用处理程序?要遵循什么模式?如果有人有相关的代码可以分享,那就太好了。

2 个答案:

答案 0 :(得分:5)

使用AsyncHTTPTestCase的模式主要是因为它会为您提供所有请求内容。当然,也可以使用AsyncTestCase并手动处理它。

AsyncTestCase示例。由于它将测试作为协同程序的get方法,因此我们将使用gen_test使其更简单一些。 RequestHandler需要ApplicationHTTPRequest个对象。因为我们没有转发应用程序的设置,所以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_applciation, payload_request)
        with self.assertRaises(ValueError):
            yield handler.get()

恕我直言,由您决定使用哪种模式。我选择AsyncHTTPTestCase作为http-verb方法(get,post等),因为:

  • 更容易
  • 此方法的消费者是HTTP客户端,因此断言响应代码,正文很有意义
  • 它可以防止过于复杂的方法

当然,使用AsyncTestCase测试了其余的处理程序方法。

答案 1 :(得分:2)

AsyncHTTPTestCase专为第一个示例而设计,使用self.fetch而不是直接实例化处理程序。

RequestHandler不是为了在不使用Application的情况下手工实例化的,所以如果你有一些功能,你宁愿在没有完整的HTTP堆栈的情况下进行测试,那么这个代码通常应该在静态函数或非RequestHandler类中。