自动assembly时,Spring集成测试速度很慢

我正在尝试加速我们环境中的集成测试。 我们所有的课程都是自动assembly的。 在我们的applicationContext.xml文件中,我们定义了以下内容:

   ...additional directories 

我注意到Spring正在扫描上面指出的所有目录,然后迭代每个bean并缓存每个bean的属性。 (我从spring开始查看DEBUG消息)

因此,以下测试大约需要14秒才能运行:

 public class MyTest extends BaseSpringTest { @Test def void myTest(){ println "test" } } 

有没有办法延迟加载配置? 我尝试添加default-lazy-init="true"但这不起作用。

理想情况下,只实例化测试所需的bean。

提前致谢。

更新 :我之前应该说过,我不想为每个测试都有一个上下文文件。 我也不认为只有测试的上下文文件才有效。 (此测试上下文文件最终会包含所有内容)

如果您真的想加速应用程序上下文 ,请在运行任何测试之前禁用

 Resource resource = new ClassPathResource(); // source.xml, for instance InputStream in = resource.getInputStream(); Document document = new SAXReader().read(in); Element root = document.getRootElement(); /** * remove component-scanning */ for ( Iterator i = root.elementIterator(); i.hasNext(); ) { Element element = (Element) i.next(); if(element.getNamespacePrefix().equals("context") && element.getName().equals("component-scan")) root.remove(element); } in.close(); ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true); for (String source: new String[] {"com.mycompany.framework", "com.mycompany.service"}) { for (BeanDefinition bd: scanner.findCandidateComponents(source)) { root .addElement("bean") .addAttribute("class", bd.getBeanClassName()); } } //add attribute default-lazy-init = true root.addAttribute("default-lazy-init","true"); /** * creates a new xml file which will be used for testing */ XMLWriter output = new XMLWriter(new FileWriter()); output.write(document); output.close(); 

除此之外,启用

由于您需要在运行任何测试之前执行上述例程,因此可以创建一个抽象类,您可以在其中运行以下命令

设置用于测试环境的Java系统属性如下所示

 -Doptimized-application-context=false 

 public abstract class Initializer { @BeforeClass public static void setUpOptimizedApplicationContextFile() { if(System.getProperty("optimized-application-context").equals("false")) { // do as shown above // and System.setProperty("optimized-application-context", "true"); } } } 

现在,对于每个测试类,只需扩展Initializer

一种方法是完全跳过自动检测,并加载单独的上下文(使用测试所需的组件)或在运行时(在测试运行之前)重新定义bean。

该主题讨论了bean的重新定义以及用于执行此操作的自定义测试类:

Spring bean在unit testing环境中重新定义

这是您为组件自动检测所支付的价格 – 它的速度较慢。 即使您的测试只需要某些bean,您的也要广泛得多,Spring将实例化并初始化它找到的每个bean。

我建议你为测试使用一个不同的bean文件,一个只定义测试本身所需的bean,即不使用

您可能需要的是重构您的配置以减少使用自动assembly。 我的方法几乎总是按名称连接bean,试图明确设计,但同时,也不要太冗长,使用自动assembly时,很明显你正在使用它来隐藏细微的细节。

附录:如果这还不够并且您使用的是junit,则可能需要使用JUnit Addons项目中的实用程序。 DirectorySuiteBuilder类从目录结构动态构建测试套件。 所以你可以做类似的事情

 DirectorySuiteBuilder builder = new DirectorySuiteBuilder(); Test suite = builder.suite("project/tests"); 

在此代码之前初始化Spring上下文,您可以立即运行所有测试。 但是,如果每个测试都假设一个“干净”的Spring上下文,那么你可能会丢失。

在这种情况下,您需要找到一个平衡点。 一方面,您可能希望在最短的时间内运行测试以快速获得结果。 在具有持续集成工作的团队环境中工作时,这一点尤其重要。 另一方面,您也希望尽可能简化测试配置,以便测试套件的维护不会变得太麻烦而无法使用。

但在一天结束时,您需要找到自己的平衡并做出决定。 我建议创建一些上下文配置文件进行测试以对一些测试进行分组,这样一个简单的测试不需要花费很长时间就可以简单地由Spring配置,同时保持配置文件的数量最少,你可以管理。

Convention bean工厂旨在解决这一问题,并显着加快整个过程,增加3倍或更多。

由于这里的答案都没有为我解决这个问题,我添加了自己的经验。

我的问题是,Spring,Hibernate和EhCache组成了试图用详细的DEBUG消息淹没我的控制台,导致无法读取的日志 – 更糟糕的是 – 难以忍受的低性能。

配置他们的日志级别修复了所有:

 Logger.getLogger("org.hibernate").setLevel(Level.INFO); Logger.getLogger("net.sf.ehcache").setLevel(Level.INFO); Logger.getLogger("org.springframework").setLevel(Level.INFO);