I'd recommend checking out the use of ivy to manage your classpaths.
In your build file use the retrieve command to copy the jars into dedicated directories:
<ivy:retrieve pattern="${lib.dir}/[conf]/[artifact].[ext]"/>
Note the conf parameter. This refers to an ivy configuration (similar to scope in Maven). It allows you to classify each of the jars you depend on.
Now that each collection of jars are conveniently located in separate directories the declaration of the paths in your build file becomes trivial:
<path id="compile.path">
<fileset dir="${lib.dir}/compile"/>
</path>
<path id="test.path">
<fileset dir="${lib.dir}/test"/>
</path>
<path id="runtime.path">
<fileset dir="${lib.dir}/runtime"/>
</path>
The complexity of defining the jar groupings is delegated to ivy and it's configuration management:
Here's an example of the controlling ivy.xml file
<ivy-module version="2.0">
<info organisation="apache" module="hello-ivy"/>
<configurations>
<conf name="compile" description="Libraries needed for compilation"/>
<conf name="runtime" extends="compile" description="Libraries that should be included when deploying the code" />
<conf name="test" extends="runtime" description="Additional test libraries, not deployed" />
</configurations>
<dependencies>
<dependency org="commons-lang" name="commons-lang" rev="2.0" conf="build->default"/>
<dependency org="commons-cli" name="commons-cli" rev="1.0" conf="build->default"/>
<dependency org="junit" name="junit" rev="4.7" conf="test->default"/>
</dependencies>
</ivy-module>
The magic bits are the conf attributes associated with each dependency. For example Junit has been declared to be part of the test which means it only appears in the test path. The others will appear in all 3 paths, due to the manner in which the configurations have been declared.