Wednesday, June 15, 2016

Make your tests fast again !

Spring framework is quit slow at startup stuff, regardless of what top responders on stack overflow seem to think.


Over the years we have developed quite a few tactics to work with this, like starting the application in Unit @BeforeClass or even a JUnit run listener. This sort-of worked with old-style monolithic applications but it was usually a quite poor approach; there are all sorts of reasons for wanting to start slightly different permutations of your application, and why can't just spring be fast ?

As of spring 4.2 you can do this:
  return new AnnotationConfigApplicationContext() {

   @Override protected void resetCommonCaches() {
   }
  }

This will dramatically speed up creation of your subsequent spring contexts.

There are a couple of possible gotchas here; since this will re-use cached type information (cached in static scope) form your previous test run, much increasing the startup speed of a subsequent spring context within the same forked process. Moving all your IT's to a single project is always smart, since class loading and static initialization is the real killer in terms of startup time.

The method in AbstractApplicationContext (the base class) does this:
 protected void resetCommonCaches() {
  ReflectionUtils.clearCache();
  ResolvableType.clearCache();
  CachedIntrospectionResults.clearClassLoader(getClassLoader());
 }


Happy hacking !