构建感测是一个用在持续集成周期中,用以描述构建长期统计数据的术语。Bamboo,一个不错的CI工具,它提供了很高级的构建特性。构建感测为你提供了关于构建要花多久,是否成功,以及解决这个构建失败问题要花多久等等之类的信息。这些数据很重要,因为它可以让你知道构建过程长期以来是什么样的。正是这种数据,而不是单个构建的结果,可以帮助你终优化构建过程。

  一定数量和频率的构建失败一直是一个不错的着手点。隔离的构建失败通常不需要担心??你需要做的是去检查一系列反复出现的构建失败。当一个构建反复失败时,也许是因为开发人员正纠结于一段非常麻烦的代码,或者是团队人员没注意到。虽然这两问题的原因不一样,并且解决的方法也不一样,但是它们都应当被进一步地调查。

  通过深入分析测试结果,你可以了解到更多关于为什么构建会失败的信息。许多现代的CI工具都可以让你研究长期的测试行为,例如,把一直经常失败的、或者要花很长时间进行解决的测试跟其他测试隔离开来。如果同样的测试不断失败的话,这意味着有什么地方过于复杂或者代码过于脆弱,这种情况下可以做一些重构。除此之外,这些工具还能让你知道测试运行了多久,这是另一类问题发生的源头。

  事实上,构建失败不是减慢开发进程的原因。缓慢的构建过程是另一个罪魁祸首。

  导致构建过程缓慢的常见的原因是结构混乱的测试套件。经验丰富的Java开发人员常常会将单元测试与集成测试分开来。虽然两者区别大差不差,但是一般来说,单元测试是相对孤立的、较小的、快速的、轻量级的测试类。它们主要是用来确保类能够独立地正常工作。而另一方面,集成测试则较为缓慢,需要更长的运行时间,并且可能会访问外部的资源如测试数据库,或者加载复杂的配置文件。它们被用来测试应用程序中的不同模块和类如何共同工作。性能测试和集成测试差不多,但是两者的目标有所不同。

  轻量级且运行很快的单元测试可以被迅速的执行完,并且在测试失败时能够给出很快的反馈。而另一方面,如果缓慢运行的集成测试与单元测试混在一起,那么单元测试将要花上更多的时间来执行,结果开发人员也要等更久才会得到关于单元测试失败的消息。解决之道是为单元测试和集成/性能测试创建单独的构建计划。使用这种方式后,如果单元测试构建计划失败了,由于其执行速度很快,开发人员不再需要等待很长时间才被通知到构建失败。如果单元测试成功后,集成测试和性能测试计划才会开始。

  另外,还有一个补充方法??可以使用分布式构建。例如,如果你的web功能测试由于要在几个不同的浏览器上运行并因此消耗很长时间,那么可以为每一个浏览器设立一个构建作业,以让它们(可能在不同的机器上)并行运行。

  另一个问题来自过于缓慢和效率低下的测试用例。有许多方法可以用来监测这些缓慢的测试。提高测试上的运行时间意味着有些测试会由于所需时间太长而无法运行。这也许是因为它们被设计的很糟糕,也许是因为性能问题(需要进步一深究),抑或是集成测试伪装成了单元测试。

  密切关注代码质量

  持续集成服务器不应当仅仅是一个自动构建的机器。它应当成为你团队中沟通的中枢,尤其在代码质量上。时刻关注编码规范和一些度量值如代码覆盖率以及代码复杂度,它们可以让应用程序更加可靠且更易维护。

  有很多的工具可以帮助维护应用程序中良好规范的代码。静态分析工具如Checkstyle,PMD和FindBugs,它们根据代码标准、佳实践或者潜在的bug来对代码进行分析。你所有使用的工具如何配置要依赖于你想要达到的目标。例如,Checkstyle更多关注于编码规范和佳实践,而 Findbugs则更倾向于找出错误的,破碎的或者危险的代码。所有的这些工具可以很轻松地集成到自动化构建过程中,并且可以和Ant、Maven一起很好地工作。

  覆盖测试率是代码质量的另一个方面。它用来衡量测试执行时所访问的代码行数。Java开发人员中对覆盖测试率统计的相对值仍然有着分歧。事实上,虽然它可以告诉你应用程序中的哪些行被执行,但是没法知道那些测试是写得很彻底、写得很好,抑或仅仅是简单的走马观花。总而言之,测试覆盖率不能保证你的测试质量很高??只有人工进行代码检查时才能确保如此。然而覆盖测试率的度量值可以很好地展示出哪些代码没有被测试过。在Java世界里,用得多的代码覆盖率测试工具当属Clover和Cobertura,前者是一个非常强大的商业代码覆盖率测试工具,而后者是一个更加轻量级的开源工具。它们都可以很容易地集成到基于Ant和Maven的构建脚本中。