Skip to main content

帮助您度过龙卷风。

项目描述

阅读文档 特拉维斯 代码气候

Glinda 是tornado的配套库。这是一种尝试,让您在使用该框架时不那么痛苦。事实上,我想让它变得非常愉快。我开始在 Tornado 中开发 HTTP 端点并需要对其进行测试。tornado.testing包对于单独测试端点很方便。但是,当您有一个异步调用其他 HTTP 服务的 HTTP 服务时,您会怎么做。事实证明,测试并不像应有的那么容易。这是我要解决的第一件事,也是这个库要提供的第一件事——一种测试非平凡服务的方法

一旦您可以测试您的应用程序,下一步就是编写一个很好地适合 WWW 的应用程序。Tornado 在处理细节的 HTTP 细节(例如,CTE、传输编码)方面做得非常好。它没有提供一种干净的方式来透明地处理表示,所以我决定也将它添加到这个库中。

内容处理

Tornado 有一些内部内容解码可以通过调用 tornado.web.RequestHandler 的 get_body_arguments方法来访问。它将专门解码基本表单数据,application/x-www-form-urlencodedmultipart/form-data。其他任何事情都由您决定。 glinda公开了一个内容处理混合,它为标准 RequestHandler 注入了一个属性,该属性是解码的请求正文和编码响应的新方法。这是它的样子:

class MyHandler(glinda.content.HandlerMixin, web.RequestHandler):
    def post(self, *args, **kwargs):
        body_argument = self.request_body['arg']
        # do stuff
        self.send_response(response_dict)
        self.finish()

if __name__ == '__main__':
    glinda.content.register_text_type('application/json',
                                      default_charset='utf-8',
                                      dumper=json.dumps, loader=json.loads)
    glinda.content.register_binary_type('application/msgpack',
                                        msgpack.dumpb, msgpack.loadb)

当客户端发送一个内容类型为application/json的帖子时,它会根据 HTTP 标头将二进制正文解码为字符串,并在您引用request_body 属性时调用json.loads对正文进行解码。通过引发HTTPError(400)来处理失败,因此您不必担心处理格式错误的消息。send_response方法将负责根据任何包含的Accept标头 找出适当的内容类型。您所要做的就是为预期的内容类型安装编码和解码处理程序。

glinda.content包实现了RFC7231中描述的内容 处理。具体来说,它解码第 3.1 节中描述的请求主体 和第3.4.15.3节中描述的主动内容协商 。

测试

这是一个测试异步调用另一个服务的 Tornado 端点的示例。在这种情况下,应用程序与其他一些服务的 /add端点交互。如果不必运行服务的副本,单独进行测试可能会很棘手。您可以模拟出AsyncHTTPClient并返回虚假的期货,但这样做会产生令人讨厌的副作用,即隐藏内容类型或标头处理方式的缺陷——没有 HTTP 请求意味着您有未经测试的假设。

以下代码片段使用glinda.testing提供的ServiceLayer抽象来测试被测应用程序 。

from tornado import testing
from glinda.testing import services


class MyServiceTests(testing.AsyncHTTPTestCase):

   def setUp(self):
      service_layer = services.ServiceLayer()
      self.service = service_layer['adder']
      # TODO configured your application here using
      # self.service.url_for('/add') or self.service.host
      super(MyServiceTests, self).setUp()

   def get_app(self):
      return MyApplication()

   def test_that_my_service_calls_other_service(self):
      self.service.add_response(
         services.Request('POST', '/add'),
         services.Response(200, body='{"result": 10}'))
      self.fetch(self.get_url('/do-stuff'), method='GET')

      recorded = self.service.get_request('/add')
      self.assertEqual(recorded.method, 'POST')
      self.assertEqual(recorded.body, '[1,2,3,4]')
      self.assertEqual(recorded.headers['Content-Type'], 'application/json')

通过实现标准的tornado.testing.AsyncHTTPTestCase.get_app方法来链接被测应用程序 。然后,您添加一个glinda.testing.services.ServiceLayer对象,并通过添加端点将其配置为看起来像您所依赖的服务,然后将您的应用程序配置为指向服务层。当您使用self.fetch(...)调用被测应用程序时,它将通过 Tornado 堆栈发送 HTTP 请求(使用测试ioloop) 到将适当响应的服务层。美妙之处在于整个 HTTP 堆栈都在本地运行,因此您可以轻松测试边缘案例,例如正确处理状态代码、自定义标头或格式错误的正文,而无需借助深度模拟。

在哪里?

资源

https://github.com/dave-shawley/glinda

地位

https://travis-ci.org/dave-shawley/glinda

下载

https://pypi.python.org/pypi/glinda

文档

http://glinda.readthedocs.org/en/latest

问题

https://github.com/dave-shawley/glinda

下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

glinda-1.0.1.tar.gz (24.6 kB 查看哈希)

已上传 source

内置分布

glinda-1.0.1-py2.py3-none-any.whl (13.0 kB 查看哈希)

已上传 py2 py3