 <p>You need to use AsyncHTTPTestCase, not just AsyncTestCase. A nice example is in Tornado's self-tests:</p> <p><a href="https://github.com/tornadoweb/tornado/blob/d7d9c467cda38f4c9352172ba7411edc29a85196/tornado/test/httpclient_test.py#L130-L130" rel="nofollow noreferrer">https://github.com/tornadoweb/tornado/blob/d7d9c467cda38f4c9352172ba7411edc29a85196/tornado/test/httpclient_test.py#L130-L130</a></p> <p>You need to implement <code>get_app</code> to return an application with the RequestHandler you've written. Then, do something like:</p> <pre><code>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) </code></pre> <p>AsyncHTTPTestCase provides convenient features so you don't need to write coroutines with "gen.coroutine" and "yield".</p> <p>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".</p>