I have a lot tests that inherited tornado.testing.AsyncHTTPTestCase, recently I find the testing is very slow and I find the AsyncHTTPTestCase make Application for every tests.
PS. I've override the Application and put some heavy jobs.
An important feature of AsyncHTTPTestCase (and the AsyncTestCase from which it inherits) is that the test case destroys and recreates the IOLoop for each test. This ensures that each test begins in a clean state unaffected by the previous one. The Application instance can't be reused between tests because the Application stores a reference to the current IOLoop.
I would try two methods to speed up your tests. First, cache the result of the heavy jobs required to start up your Application. Use a new Application for each test, but speed up Application initialization by using these cached results.
If you can't do that, you could try overriding AsyncHTTPTestCase's get_new_ioloop method to return IOLoop.current(), and move the initialization of your Application into setUpClass so it's done once per test class instead of once per test:
from tornado.ioloop import IOLoop
from tornado.testing import AsyncHTTPTestCase
from tornado.web import Application, RequestHandler
class HelloHandler(RequestHandler):
def get(self):
self.write("Hello world!")
class MyTestCase(AsyncHTTPTestCase):
@classmethod
def setUpClass(cls):
cls.my_app = Application([(r'/', HelloHandler)])
def get_new_ioloop(self):
return IOLoop.current()
def get_app(self):
return self.my_app
def test(self):
response = self.fetch("/")
self.assertEqual(response.body, b"Hello world!")
if __name__ == '__main__':
import unittest
unittest.main()
Thanks for your reply, I've cached the Application instance via a class property. I open this to want know if that could be avoid in framework level.
Great, I'm glad you've found a solution to your scenario. We're not going to change how AsyncHTTPTestCase works, because destroying and recreating the IOLoop and the Application is usually fast, and it's an important way to isolate tests from each other.
Most helpful comment
An important feature of AsyncHTTPTestCase (and the AsyncTestCase from which it inherits) is that the test case destroys and recreates the IOLoop for each test. This ensures that each test begins in a clean state unaffected by the previous one. The Application instance can't be reused between tests because the Application stores a reference to the current IOLoop.
I would try two methods to speed up your tests. First, cache the result of the heavy jobs required to start up your Application. Use a new Application for each test, but speed up Application initialization by using these cached results.
If you can't do that, you could try overriding AsyncHTTPTestCase's
get_new_ioloopmethod to returnIOLoop.current(), and move the initialization of your Application intosetUpClassso it's done once per test class instead of once per test: