tornado.testing ---异步代码单元测试支持

自动化测试的支持类。

  • AsyncTestCaseAsyncHTTPTestCase :UnitTest.TestCase的子类,支持异步测试 (IOLoop 基于代码。

  • ExpectLog :减少测试日志的空间。

  • main() :一个简单的测试运行程序(包装在unittest.main()周围),支持tornado.autoreload模块,以便在代码更改时重新运行测试。

异步测试用例

class tornado.testing.AsyncTestCase(methodName: str = 'runTest')[源代码]

TestCase 测试子类 IOLoop -基于异步代码。

UnitTest框架是同步的,因此测试必须在测试方法返回时完成。这意味着异步代码不能像通常那样以完全相同的方式使用,必须进行调整以适应。要用协程编写测试,请用 tornado.testing.gen_test 而不是 tornado.gen.coroutine .

此类还提供(已弃用) stop()wait() 更手动的测试方法。测试方法本身必须调用 self.wait() ,异步回调应该调用 self.stop() 表示完成。

默认情况下,新的 IOLoop 是为每个测试构建的,可用作 self.io_loop . 如果要测试的代码需要全局 IOLoop ,子类应重写 get_new_ioloop 归还它。

这个 IOLoopstart and stop methods should not be called directly. Instead, use self.stop and self.wait. Arguments passed to self.stop are returned from self.wait. It is possible to have multiple wait/stop 同一测试中的循环。

例子::

# This test uses coroutine style.
class MyTestCase(AsyncTestCase):
    @tornado.testing.gen_test
    def test_http_fetch(self):
        client = AsyncHTTPClient()
        response = yield client.fetch("http://www.tornadoweb.org")
        # Test contents of response
        self.assertIn("FriendFeed", response.body)

# This test uses argument passing between self.stop and self.wait.
class MyTestCase2(AsyncTestCase):
    def test_http_fetch(self):
        client = AsyncHTTPClient()
        client.fetch("http://www.tornadoweb.org/", self.stop)
        response = self.wait()
        # Test contents of response
        self.assertIn("FriendFeed", response.body)

6.2 版后已移除: 由于未来版本的Python(3.10之后)中的更改,不推荐使用AsyncTestCase和AsyncHTTPTestCase。当没有事件循环实际运行时,此类中使用的接口与与“当前”事件循环相关的某些方法的弃用和有意移除不兼容。使用 unittest.IsolatedAsyncioTestCase 取而代之的是。请注意,在提供更好的迁移指导之前,此类不会发出DepuationWarning。

get_new_ioloop() tornado.ioloop.IOLoop[源代码]

返回 IOLoop 用于此测试。

默认情况下,新的 IOLoop 为每个测试创建。子类可以重写此方法以返回 IOLoop.current() 如果不适合使用新的 IOLoop 在每个测试中(例如,如果有使用默认值的全局单例 IOLoop )或者如果另一个系统正在提供每个测试事件循环(例如 pytest-asyncio

stop(_arg: Optional[Any] = None, **kwargs: Any) None[源代码]

停止 IOLoop ,导致一个挂起(或将来)呼叫 wait() 返回。

传递给的关键字参数或单个位置参数 stop() 已保存并将由返回 wait() .

5.1 版后已移除: stopwait 已弃用;使用 @gen_test 相反。

wait(condition: Optional[Callable[[...], bool]] = None, timeout: Optional[float] = None) Any[源代码]

运行 IOLoop 直到调用stop或超时。

如果超时,将引发异常。默认超时为5秒;可以用 timeout 关键字参数或全局 ASYNC_TEST_TIMEOUT 环境变量。

如果 condition 不是 None , the IOLoop 将在之后重新启动 stop() 直到 condition() 收益率 True .

在 3.1 版更改: 增加了 ASYNC_TEST_TIMEOUT 环境变量。

5.1 版后已移除: stopwait 已弃用;使用 @gen_test 相反。

class tornado.testing.AsyncHTTPTestCase(methodName: str = 'runTest')[源代码]

启动HTTP服务器的测试用例。

子类必须重写 get_app() ,返回 tornado.web.Application (或其他) HTTPServer 回调)待测试。测试通常使用提供的 self.http_client 从该服务器获取URL。

示例,假设用户指南中的“hello,world”示例位于 hello.py ::

import hello

class TestHelloApp(AsyncHTTPTestCase):
    def get_app(self):
        return hello.make_app()

    def test_homepage(self):
        response = self.fetch('/')
        self.assertEqual(response.code, 200)
        self.assertEqual(response.body, 'Hello, world')

呼唤 self.fetch() 等于:

self.http_client.fetch(self.get_url('/'), self.stop)
response = self.wait()

这说明了AsyncTestCase如何能够转换异步操作,比如 http_client.fetch() 进入同步操作。如果需要在测试中执行其他异步操作,则可能需要使用 stop()wait() 你自己。

get_app() tornado.web.Application[源代码]

应被子类重写以返回 tornado.web.Application 或其他 HTTPServer 回调。

fetch(path: str, raise_error: bool = False, **kwargs: Any) tornado.httpclient.HTTPResponse[源代码]

同步获取URL的便利方法。

给定的路径将附加到本地服务器的主机和端口。任何其他关键字参数都将直接传递给 AsyncHTTPClient.fetch (所以可以用来通过 method="POST"body="..." 等)。

如果路径以http://或https://开头,它将被视为完整的URL,并按原样提取。

如果 raise_errorTrue ,A tornado.httpclient.HTTPError 如果响应代码不是200,则将引发。这与 raise_error 参数 AsyncHTTPClient.fetch ,但默认为 False 这里(它) True 在里面 AsyncHTTPClient )因为测试通常需要处理非200响应代码。

在 5.0 版更改: 添加了对绝对URL的支持。

在 5.1 版更改: 增加了 raise_error 参数。

5.1 版后已移除: 此方法当前将任何异常转换为 HTTPResponse 状态代码为599。在Tornado 6.0中,除 tornado.httpclient.HTTPError 将通过,并且 raise_error=False 只会抑制由于非200响应代码而引起的错误。

get_httpserver_options() Dict[str, Any][源代码]

可以被子类重写以返回服务器的其他关键字参数。

get_http_port() int[源代码]

返回服务器使用的端口。

为每个测试选择一个新端口。

get_url(path: str) str[源代码]

返回测试服务器上给定路径的绝对URL。

class tornado.testing.AsyncHTTPSTestCase(methodName: str = 'runTest')[源代码]

启动HTTPS服务器的测试用例。

接口通常与 AsyncHTTPTestCase .

get_ssl_options() Dict[str, Any][源代码]

可以被子类重写以选择SSL选项。

默认情况下,包括自签名测试证书。

tornado.testing.gen_test(*, timeout: Optional[float] = 'None') Callable[[Callable[[...], Union[collections.abc.Generator, Coroutine]]], Callable[[...], None]][源代码]
tornado.testing.gen_test(func: Callable[[...], Union[collections.abc.Generator, Coroutine]]) Callable[[...], None]

试验当量 @gen.coroutine ,用于试验方法。

@gen.coroutine 无法用于测试,因为 IOLoop 尚未运行。 @gen_test 应该应用于子类的测试方法 AsyncTestCase .

例子::

class MyTest(AsyncHTTPTestCase):
    @gen_test
    def test_something(self):
        response = yield self.http_client.fetch(self.get_url('/'))

默认情况下, @gen_test 5秒后超时。可以使用 ASYNC_TEST_TIMEOUT 环境变量,或每个测试的 timeout 关键字参数:

class MyTest(AsyncHTTPTestCase):
    @gen_test(timeout=10)
    def test_something_slow(self):
        response = yield self.http_client.fetch(self.get_url('/'))

注意 @gen_test 与不兼容 AsyncTestCase.stopAsyncTestCase.waitAsyncHTTPTestCase.fetch . 使用 yield self.http_client.fetch(self.get_url()) 如上图所示。

3.1 新版功能: 这个 timeout 论证与 ASYNC_TEST_TIMEOUT 环境变量。

在 4.0 版更改: 包装器现在就传下去了 *args, **kwargs 所以它可以用于带参数的函数。

控制日志输出

class tornado.testing.ExpectLog(logger: Union[logging.Logger, str], regex: str, required: bool = True, level: Optional[int] = None)[源代码]

用于捕获和抑制预期日志输出的上下文管理器。

有助于减少错误条件测试的噪音,同时仍保留意外的日志条目。 不是线程安全的。

属性 logged_stack 设置为 True 如果记录了任何异常堆栈跟踪。

用法:

with ExpectLog('tornado.application', "Uncaught exception"):
    error_response = self.fetch("/some_page")

在 4.3 版更改: 增加了 logged_stack 属性。

构造ExpectLog上下文管理器。

参数
  • logger -- 要监视的记录器对象(或记录器名称)。传递空字符串以监视根记录器。

  • regex -- 要匹配的正则表达式。指定记录器上与此regex匹配的任何日志条目都将被禁止。

  • required -- 如果为true,则在 with 语句不匹配任何日志条目。

  • level -- 来自 logging 指示预期日志级别的模块。如果提供此参数,则只有此级别的日志消息才被视为匹配。另外,供应的 logger 将在必要时调整其水平(在 ExpectLog 以启用预期的消息。

在 6.1 版更改: 增加了 level 参数。

试验转轮

tornado.testing.main(**kwargs: Any) None[源代码]

一个简单的测试运行程序。

这个测试运行程序基本上等同于 unittest.main 从标准库中,但添加了对Tornado样式选项解析和日志格式的支持。它是 not 必须使用这个 main 用于运行测试的函数 AsyncTestCase ;这些测试是独立的,可以与任何测试运行程序一起运行。

运行测试的最简单方法是通过命令行:

python -m tornado.testing tornado.test.web_test

参见标准库 unittest 用于指定测试方式的模块。

具有许多测试的项目可能希望定义类似 tornado/test/runtests.py . 此脚本应定义一个方法 all() 它返回一个测试套件,然后调用 tornado.testing.main() . 注意,即使使用了测试脚本, all() 可以通过在命令行上命名单个测试来重写测试套件::

# Runs all tests
python -m tornado.test.runtests
# Runs one test
python -m tornado.test.runtests tornado.test.web_test

传递给的其他关键字参数 unittest.main() . 例如,使用 tornado.testing.main(verbosity=2) 在运行时显示许多测试详细信息。完整参数列表请参见http://docs.python.org/library/unittest.html unittest.main。

在 5.0 版更改: 此函数本身不生成任何输出;只生成由 unittest 模块(以前它会添加一条通过或失败日志消息)。

帮助程序函数

tornado.testing.bind_unused_port(reuse_port: bool = False, address: str = '127.0.0.1') Tuple[socket.socket, int][源代码]

将服务器套接字绑定到本地主机上的可用端口。

返回元组(套接字、端口)。

在 4.4 版更改: 总是绑定到 127.0.0.1 不解析名称 localhost .

在 6.2 版更改: 添加了可选选项 address 参数覆盖默认的“127.0.0.1”。

tornado.testing.get_async_test_timeout() float[源代码]

获取异步测试的全局超时设置。

返回浮点值,超时值以秒为单位。

3.1 新版功能.