Ant / Junit and Class Loaders

Have you ever come across situations where you need to load external resources in your Junit tests? I generally prefer loading external resource files from the classpath. So I add the resources on the classpath and in the test case I look up the resource using the ClassLoader.getResource(). If you are running the Junit tests using ant, you can run into all sorts of problems if you are trying to load resources from the classpath.

Ant runs each Junit test in its own class loader. This makes sure that any libraries on the ant's classpath wont interfere with the test's environment.

If you are using a class loader to load the resources, always use the immediate class loader to load the resource. Generally you can get the handle to class loader through
ClassLoader.getSystemClassLoader(). But if you try to load a resource using this class loader in the test case, JVM will try to load the resource using the system class loader. System class loader in this case is class loader for Ant. But unfortunately since Ant created a special class loader for the test, the system class loader does not contain the same classpath that you have configured in ant's build.xml for running tests (Ideally you would have added the directories containing the resources that you need to dynamically look up in test cases here). You would end up with a resource not being found.

To overcome this, always use immediate class loader, how to dot it?

use
MyTest.class.getClassLoader()

This ensures that we are getting the class loader that loaded test class. Which infact is the immediate class loader.

This also applies for any framework / API you write. Using immediate class loader makes sure that your framework would be testable in the multi classloader environements.



Continuous Integration Servers

Just came across this

I have tried TeamCity already and it looks convincing. I would want to evaluate the Apache and Sun products as those are completely free.