Search code examples
python-3.xtornado

received error: tornado.ioloop.TimeoutError: Operation timed out after 5 seconds.what to do?


Hy. I try to write test for webHander:

import pytest
import tornado
from tornado.testing import AsyncTestCase
from tornado.httpclient import AsyncHTTPClient
from tornado.web import Application, RequestHandler
import urllib.parse


class TestRESTAuthHandler(AsyncTestCase):
@tornado.testing.gen_test
def test_http_fetch_login(self):
    data = urllib.parse.urlencode(dict(username='admin', password='123456'))
    client = AsyncHTTPClient(self.io_loop)
    response = yield client.fetch("http://localhost:8080//#/login", method="POST", body=data)
    # Test contents of response
    self.assertIn("Automation web console", response.body)

Received error when running test:

raise TimeoutError('Operation timed out after %s seconds' % timeout)

tornado.ioloop.TimeoutError: Operation timed out after 5 seconds


Solution

  • You need to use AsyncHTTPTestCase, not just AsyncTestCase. A nice example is in Tornado's self-tests:

    https://github.com/tornadoweb/tornado/blob/d7d9c467cda38f4c9352172ba7411edc29a85196/tornado/test/httpclient_test.py#L130-L130

    You need to implement get_app to return an application with the RequestHandler you've written. Then, do something like:

    class TestRESTAuthHandler(AsyncHTTPTestCase):
        def get_app(self):
            # implement this
            pass
    
        def test_http_fetch_login(self):
            data = urllib.parse.urlencode(dict(username='admin', password='123456'))
            response = self.fetch("http://localhost:8080//#/login", method="POST", body=data)
            # Test contents of response
            self.assertIn("Automation web console", response.body)
    

    AsyncHTTPTestCase provides convenient features so you don't need to write coroutines with "gen.coroutine" and "yield".

    Also, I notice you're fetching a url with a fragment after "#", please note that in real life web browsers do not include the fragment when they send the URL to the server. So your server would see the URL only as "//", not "//#/login".