我们有几个非常非常慢的JUnit测试,它们大量使用mocking,包括静态函数的mocking。单个测试需要20-30秒,整个"mvn测试"需要25分钟。
我想分析浪费时间的地方,但在分析方面经验不足。
我认为依赖mock对象的初始化花费的时间太长了。
两个问题:
1) 如何快速获取浪费时间的方法中的数字?我不需要复杂的超级用户工具,只需要一些基本的东西来获取数字。
2) 你知道什么设计缺陷会造成如此糟糕的时间安排吗?我们测试应该调用模拟服务的JSF支持bean。也许在后台bean中可能有一些输入验证或未重构的业务逻辑,但这是无法改变的(请不要对此发表评论;-)
ad 2)例如,一个测试有大约30(!)个类要准备好用@PrepareForTest进行测试。这不可能是好事,但我无法解释原因。
以下是我对此的输入:
-
尝试使用一些简单的东西,比如Apache Commons StopWatch类。我发现这是一种发现代码瓶颈的简单方法,通常当你找到第一个瓶颈是什么时,其他瓶颈就更容易发现。我几乎从不浪费时间来配置过于复杂的分析工具。
-
我认为在完全模拟的单元测试中出现这样的性能缺陷是很奇怪的。如果我猜测的话,我会说你丢失了一两个模拟组件,而数据库或外部web服务实际上是在你不知情的情况下被调用的。当然,我可能错了,因为我不使用PowerMock,我强调永远不要模拟任何静态方法。这是您目前最大的设计缺陷,也是为代码提供良好测试覆盖率的最大障碍。那该怎么办呢?您有两个选项,可以将静态方法重构为更容易模拟的类方法。另一种选择是将静态方法包装在类对象包装器中,然后模拟包装器。如果静态方法来自我没有源代码的第三方库,我通常会这样做。
-
one test has about 30 (!) classes to be prepared for test with @PrepareForTest. This cannot be good, but I cannot explain why.
听起来你可能也有一些方法做得太多了在大约99%的情况下,对于单个方法来说,这只是太多的依赖关系。这种方法很可能可以分为更容易测试的单独方法。
希望这能有所帮助。