如何在@ tornado.testing.gen_test中编写要调用的函数?

Ale*_*lex 3 python tornado

所以我有一些我想要测试的代码,而且我遇到了基于yield generator @tornado.testing.gen_test的预期输入测试的非常可怕的副作用:

class GameTest(tornado.testing.AsyncHTTPTestCase):

    def new_game(self):
        ws = yield websocket_connect('address')
        ws.write_message('new_game')
        response = yield ws.read_message()
        # I want to say:
        # return response

    @tornado.testing.gen_test
    def test_new_game(self):
        response = self.new_game()
        # do some testing
Run Code Online (Sandbox Code Playgroud)

问题是我无法从生成器返回值,所以我的本能是错误的.此外,我不能这样做:

class GameTest(tornado.testing.AsyncHTTPTestCase):

    def new_game(self):
        ws = yield websocket_connect('address')
        ws.write_message('new_game')
        response = yield ws.read_message()
        yield response, True

    @tornado.testing.gen_test
    def test_new_game(self):
        for i in self.new_game():
            if isinstance(i, tuple):
                response, success = i
                break
        # do some testing
Run Code Online (Sandbox Code Playgroud)

因为那时我遇到了错误:

AttributeError: 'NoneType' object has no attribute 'write_message'
Run Code Online (Sandbox Code Playgroud)

显然,我可以在测试中包含整个测试生成代码,但这非常难看,难以维护等等.这种测试模式是否真的使间接如此困难?

Ben*_*ell 5

您应该使用@gen.coroutine异步函数来调用@gen_test方法,就像在非测试代码中一样. @gen_test是顶级测试函数的适配器,可以在同步unittest接口中使用异步代码.

@gen.coroutine
def new_game(self):
    ws = yield websocket_connect('address')
    ws.write_message('new_game')
    response = yield ws.read_message()
    raise gen.Return(response)

@tornado.testing.gen_test
def test_new_game(self):
    response = yield self.new_game()
    # do some testing
Run Code Online (Sandbox Code Playgroud)

在Python 3.3+中,您可以使用return response而不是raise gen.Return(response).@gen.coroutine如果您yield from在呼叫站点使用,甚至可以省略.