How I stumbled upon a design-flaw in TestContextManager:
Yesterday I switched my testcases from JUnit to TestNG. I have some long-running tests, so I immediately enabled TestNG's "parallel"-Setting, so that my testcases run in a multithreaded fashion.
After running the testcases I realized that I get a lot of Exceptions, which were caused by tests running in parallel and disturbing each other. E.g. flushing the database, etc..
In my tests I use a inmemory-HSQLDB, so every Test should have a fresh DB and there should be no shared database server. The cause of that behaviour seems to be the ContextCache of the TestContextManager, which seems to be shared across multiple TestNG-Threads.
I understand that you cache the internal Spring-Contexts between Tests, in order to improve speed. Nevertheless I dont think that it is a good idea to share the Cache between Threads (I'm only talking about Tests. This is different in a productive application, of course.)
My proposal on how to improve the TestContextManager:
When you look into the TestContextManager, you will see that the ContextCache is a static variable:
This causes one ContextCache to be shared between multiple Test-Threads!
static final ContextCache contextCache = new ContextCache();
My proposal would be to make the ContextCache a ThreadLocal:
Therefore each Thread would have its own ContextCache.
protected static final ThreadLocal<ContextCache> contextCache = new ThreadLocal<ContextCache>();
I was able to fix my concurrency issues with that fix. I have no unexplainable Exceptions any more. But I still have Context-caching (I dont see the Spring-container being reinitialized all the time).
What do you think about that? I realize that this might have a impact on @Timed or @Test(threadPoolSize=>0). But we should start thinking about running Tests in parallel, nowadays where everyone has Dual- or Quadcore CPUs :-)