【问题标题】:JUnit startup time is slowJUnit 启动时间慢
【发布时间】:2017-01-18 13:58:16
【问题描述】:

我正在处理一个相当小的项目(就依赖项而言),每当我运行单元测试时,JVM 需要 8 秒才能加载,然后在 0.2 秒内运行实际测试。

我的环境:

  • Java 8
  • Spring Tool Suite 3.8.1.RELEASE
  • JUnit 4
  • Windows 8

我担心我的环境中一定有什么东西导致了这需要这么长时间,我希望有人以前见过这个并找到问题的根源并可能找到解决方案?

例如如果我的PATH 环境变量真的很长,那有关系吗?

当我运行 JUnit 测试时究竟会发生什么?

我要运行的实际测试是:

public class TemplateLocationCalculatorTest {

    private TemplateLocationCalculator target = new TemplateLocationCalculator();
    
    @Test
    public void whenGivenRootReturnIndex(){
        Assert.assertEquals("index", target.calculate("/"));
    }
}

目标类是这样的:

public class TemplateLocationCalculator {

    public String calculate(String string) {
        return "index";
    }

}

当我说这不应该花很长时间加载时,我希望你会同意我的看法。

【问题讨论】:

  • @PieterDeBie 我做到了。第二段。计算机硬件性能应该不是问题。
  • 阅读太快,删除了我的评论:)
  • 你能描述一下在这 8 秒的启动过程中发生了什么吗?您可以尝试this question 中描述的方法来记录各种 JVM 引导事件。
  • @apangin 感谢您的建议。我试过了,但是在应用程序(而不是 JVM)启动之前,日志不会开始。
  • 抱歉,我将 spring 工具套件误读为 spring。好吧,您使用的是 Eclipse IDE?如果您在 IntelliJ 中打开测试,它会在那里运行得更快吗?

标签: java junit jvm spring-tool-suite


【解决方案1】:

在这里。

suggestion given in the chat 之后,我使用了Microsoft Process Monitor,经过大量过滤后,我发现 AV 软件 Avecto DefendPoint 正在我的机器上运行,这似乎是瓶颈.每当我开始测试时,它会以大约 25% 的速度运行,这对我来说似乎表明它在我的四个核心之一的单个线程上全速运行。我不是这台机器的管理员,所以我无法禁用它来验证这个假设,但一般来说,如果其他人应该看到这个问题,请检查它是否可能是你的防病毒软件。

【讨论】:

    【解决方案2】:

    潜在的reason 可能是启动期间的组件扫描和组件自动装配。您可以通过为测试创建单独的config 文件来限制这一点,以限制组件的搜索空间,如here 所述。

    在配置中,您可以lazy load beans <beans default-lazy-init="true"> 或显式连接bean(更详细地解释here

    <beans ...>
        <!-- this bean will be injected into the OrderServiceTest class -->
        <bean id="target" class="TemplateLocationCalculator" />
    
        <!-- other beans -->
    </beans>
    

    然后在测试类中,我们指定新的配置文件:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "classpath:/path/to/test-config.xml" })
    public class TemplateLocationCalculatorTest {
    
        @Autowired
        private TemplateLocationCalculator target;
    
        @Test
        public void whenGivenRootReturnIndex(){
            Assert.assertEquals("index", target.calculate("/"));
        }
    
    }
    
    @Bean
    public class TemplateLocationCalculator {
    
       public String calculate(String string) {
           return "index";
       }
    
    }
    

    【讨论】:

    • 这里没有使用 Spring。它是 Spring Tool Suite (STS)。还是您的意思是即使运行简单的 JUnit 测试,STS 也会自动装配?
    • STS 是一个预安装 Spring IDE 组件的插件 - 在引擎盖下它仍然是 spring。即使它只是一个 JUnit 测试,也需要构建和运行应用程序,因此仍然会进行自动连接。这里的想法是简化这个过程
    • 好的...我的意思是这里没有直接使用 Spring。如果 STS 在后台进行一些布线会减慢进程并且您的答案解决了这个问题,那么一切都很好;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 2013-12-24
    • 1970-01-01
    • 2018-03-06
    • 2016-09-01
    • 2021-12-07
    • 1970-01-01
    相关资源
    最近更新 更多