你如何加速java单元测试?

Jam*_*eng 32 java ant performance unit-testing

目前我们的项目有超过3000个单元测试,"ant testAll"需要超过20分钟.除了获得更好的硬件,还有办法加快速度吗?

jal*_*alf 29

以同样的方式加速任何其他代码.找出哪些测试花费最多时间,并了解如何优化它们.

有很多操作可能很慢,如果你这样做了3000次,它就会增加.有时,在测试之间重用数据是值得的(即使你不应该在单元测试中这样做,如果这是让你的测试以可接受的速度运行所需要的).

测试时间.通常,它们中的90%几乎会立即执行,而最后10%将几乎所有时间都会执行.找到那些10%,看看他们在做什么.

通过分析器运行代码,并记下花费时间的位置.猜测是浪费时间.你认为测试跑步者正在做的事情毫无意义.而不是猜测,找出它在做什么.然后你会知道如何加快速度.


Alc*_*nja 14

一些想法:

  • 使用模拟框架来避免命中数据库(或进行Web服务调用等).
  • 如果您正在进行大量单独测试的相同或类似设置,请尝试在测试夹具设置中进行(即每个夹具完成一次而不是每次测试一次).
  • 我相信一些测试框架允许您并行运行测试


mik*_*kek 10

您可能希望将单元测试拆分为套件.您的应用程序是否模块化?你经常需要经常进行所有测试吗?如果您的开发人员只运行与他们自己的模块相关的单元测试,并且您每晚都运行一系列测试和/或CI,那么这是可以接受的吗?

是否有任何特定的单元测试非常复杂(我知道,我在这里正在进行功能和集成测试,但这条线有时是模糊的),但是它们中的任何一个都可以在开发过程中以健全级别运行,然后是在CI上全力以赴?

编辑:只是为了踢,我将在之前的一个项目中简要描述测试程序

首先,测试系统的增长是有机的,这意味着它最初没有计划好,但随着它的发展而被修改和改变.因此它并不完美,并且有一些命名惯例随着时间的推移而变得杜松.

  • 在开发人员级别,我们使用了一个名为CheckIn的简单的两分钟测试套件,它验证了代码是否足够健康以加入主干.
  • 最重要的是,我们在CI机器上不断进行健全性测试.这些是更复杂的集成和功能测试的简化版本,所有单元测试和所有回归测试.
  • 复杂的测试套件(以小时为单位)在白天和晚上远程运行,结果在第二天早上编译.

自动测试 - 这是笨蛋的坚果.

  • "合在一起"的东西会受到其他一些测试,比如集成测试或其他什么.单元测试是关于单元的,所以单元应该独立工作.并不意味着我们不需要一起测试所有的东西,但这不是单元测试,IMO. (5认同)
  • 这是一个糟糕的建议.您应该尽可能多地运行测试,以确保所有组件独立工作.你永远不能假设系统的一个方面是"正常工作",因为你没有针对那个领域进行开发. (2认同)

Jas*_*Day 6

fork="yes"junit通话中使用吗?如果是这样,请确保设置forkMode="once",否则 junit 任务将为每个 TestCase 类启动一个新的 VM。使用 3000 个单元测试,这将产生巨大的差异。

http://ant.apache.org/manual/Tasks/junit.html


Kha*_*oth 5

首先:
a)获取有关Junit测试的运行时间的统计信息.您可能已经在测试报告中限制了该信息.
b)取出前10个测试课程(及时),并尝试减少时间.这需要持续进行.
c)尝试通过重构甚至改变测试方法来减少运行时间.
我遇到的一个这样的案例是在CRUD测试用例的一个Test类中.更新测试用例首先创建funtionlaity然后更新.但是我们已经在seprate测试用例中进行了测试.所以在这些情况下你可以将测试用例链接起来

@Test()
    public void testCreate() throws Exception
    {}
    @Test(dependsOnMethods = "testCreate")
    public void testAmend() throws Exception
    {}
    @Test(dependsOnMethods = "testAmend")
    public void testDelete() throws Exception
    {} 
Run Code Online (Sandbox Code Playgroud)

所以你节省了重复测试.

d)我能够明显减少时间的另一个例子是.我们有一个系统(inherietd),其中每个测试用例都调用SetUp(Strating Spring Server等)并在运行关闭系统资源之后.这非常耗时,所以我重构它以在测试套装之前和整个套件之后启动coomon资源.完成然后关闭那些.

e)根据您的项目,他们可能是您可能需要解决的其他瓶颈.

如何在TDD中管理构建时间


Pab*_*jim 5

我假设您已经完成了所有其他常见步骤,例如模拟数据库调用、优化测试设置阶段等,测试运行时间如此之长是因为您有 3000 次测试,而不是单个测试非常慢。

如果是这样,一种方法是多线程测试运行。Test-NG 很好地支持这一点。将您的测试从 junit 转换为 test-ng 并不难,只需要做一次。

必须按顺序运行的测试可以轻松标记:

@Test(sequential = true)
public class ATest {
  ...
Run Code Online (Sandbox Code Playgroud)

在多核机器上,您会看到运行时间的巨大改进。即使在单核上,您也会看到很好的改进,因为某些线程等待 io 操作。

有关如何设置的详细信息,请参见此处:

http://beust.com/weblog/archives/000407.html

希望这可以帮助。

....

更多建议- 我不敢相信您没有使用持续集成。相信我 30 个开发人员不会让您的 CI 服务器超载。即使您无法购买 CI,也可以在您自己的机器上安装hudson - 设置需要 10 分钟,而且好处是巨大的。问问你的经理,每个开发人员坐等单元测试完成还是让服务器为你做这件事,哪个更糟糕。为破坏构建的人戴上一顶愚蠢的帽子通常足以说服开发人员运行他们的单元测试。

如果签入的质量真的是一个很大的问题(不要忘记签入总是可以回滚)考虑Teamcity - 它运行测试并且如果测试失败则不提交代码。

最后,可能适合您的用例的选项也是clover 和 carbon最新版本记录了哪些代码由哪些测试进行测试,以及何时进行更改,它只运行相关测试。这可能非常强大。

但是请记住,像 test-ng、teamcity 和 clover 这样的聪明工具只会让你走到这一步——好的测试不会自己编写!

总结我的解决方案是尝试以下全部或部分步骤:

  1. 优化测试 - 模拟、通用设置等。
  2. 并行运行测试
  3. 获取其他东西来为您运行测试 - 使用 hudson 或类似工具使其成为离线任务
  4. 只运行需要运行的测试 - 将它们分类成包或使用三叶草和竹子。


jer*_*jvl 3

在不进一步了解正在测试的内容的情况下,唯一容易出现的方法是:

  • 使用更好的硬件(抱歉)
  • 简化测试逻辑

您甚至可能想在测试运行中运行探查器,看看是否有任何实施效率特别低的测试。