(续上。。。)
各个击破
的确可以将把测试代码时所需的所有步骤集成为一个大的整体任务,然后在有代码提交到存储库中的时候,只要执行这一任务就可以了。但是,通常情况下,将这些任务拆分成一个个小任务或事件,然后再按顺序执行这些事件会更好。我们可以对事件的执行顺序进行配置, 后面的事件如何执行,取决于前面的事件执行之后所取得的结果。这样,就可以将一系列执行不同测试的事件链接在一起,通过将很多简单的步骤结合在一起,来形成一系列复杂的任务。
分裂测试的基本原理在于:测试失败时,能够及时发现。如果单元测试早就失败了,就没有必要将软件下载到硬件上,并执行代码覆盖率测试。所以,在持续集成过程中,使用各个击破的测试方法是非常有效的。软件只有通过当前阶段的测试,才能进入到下一测试阶段。这样可以确保开发人员能够尽快得到反馈,从而尽快提出修复方案。
管理大量细小的事件要比管理一个庞大的整体事件容易一些,比如,添加一个新测试或改变测试的顺序。图3展示了如何运行一系列事件。如果代码通过,就可以进入下一阶段。如果代码通过所有阶段的测试,那么这个代码就能成为一个候选发布版本。
图3 典型的事件运行序列
第二部分 通过持续集成进行静态分析代码检测
静态分析是一个广义的概念,它包含了很多种对源代码进行分析的方法,进行静态分析时,不需要真正构建和运行代码(虽然好工具也可以显示出该项目在运行过程中的情况)。静态分析可以被看作代码质量谱的结构端的测试,动态测试则主要负责功能方面的测试。静态分析可保证代码遵循最佳编码惯例,还能够发现很多问题,包括未定义行为、可移植性问题、由语言误用产生的危险但是合法的构建、代码清晰度问题、代码的实际布局问题等。静态分析也可以发现动态测试不能发现的一些问题,还能够帮助简化脚本,使脚本更易于维护,更加高效。虽然自动化的静态分析不能完全取代代码评审,但是对于代码评审来说,它是非常重要的一部分。
静态分析一个非常重要的方面就在于:在完成第一行代码之后,就可以立即进行静态分析,这就将测试代码的重点放到了开发初期。
静态分析的关键在于,能够在早期和持续的应用程序代码评审中大量减少代码中存在的问题,确保在项目的编码阶段,能够遵循最佳编码惯例。为了提高效率,需要大部分代码评审工作都能够实现自动化:代码还是需要开发人员来评审,但是传统代码评审中找出的问题,大多数都能够自动检测到。“尽早、经常性”的代码评审策略与持续集成的概念非常吻合——因此,将自动代码检查与持续集成过程结合起来,是大有裨益的。
代码集成中存在的问题同样存在于执行编码规范的过程中:如果将问题一直留到代码编写完成,那这个做法一定是有问题的。
如果将新编码规范应用于之前未遵循该编码规范的代码,常常会发现很多违规行为。要解决所发现的问题不仅会耗费很多时间,而且在修改功能的过程中,还可能会使代码更加糟糕,甚至还可能引进更多严重的违规行为。
所以,在编写代码时就遵循编码规范会更加有效率、更加安全;开发人员在编码代码的时候,就应该及时解决所发现的编码问题。
因此,进行集成和执行编码规范时,都应该“尽早开始,并经常进行”。
增量执行编码规范最主要的优点就是能够保证代码的质量,但同时也会带来其它好处。可以将很多度量都收集起来,作为静态分析的一部分,而且增量测试可以形成一个趋势图,可以通过观察所形成的趋势图来判断项目是否健康。如果度量开始与期望偏离(可能是通过与“优质标准的项目”进行对比),就可以有针对性地采取措施,使项目回归正常。
第二章 部署示例:Jenkins and PRQA 工具
第一节 Jenkins 作为持续集成系统
现在有很多持续集成工具,既有免费的,也有商业的。最近的研究显示,Jenkins正发展成为最受欢迎的持续集成工具。Jenkins是Hudson持续集成系统的一个分支,但是Jenkins拥有最活跃的生态系统。
在MIT许可下,Jenkins是免费的,但是和一些开源软件一样,Jenkins也有付费版本,并会提供技术支持。虽然Jenkins是一个开源项目,但是对核心代码所作的所有修改,都由核心提交者严格把控,其中一位核心提交者就是项目架构师Koshuke Kawaguchi。
系统概述
Jenkins是用Java写的,由一个很小的内核和一个内置网站服务器组成。大多数用户与Jenkins的互动都是通过常规网页浏览器来实现的,不需要安装特别的客户端软件。
灵活性是优质持续集成系统的一个主要特性,它能够满足所有公司的业务要求。Jenkins有两个非常重要的结构特点,使得它既可自定义又可扩展:主/从分布式构建结构和插件。
主/从结构
虽然Jenkins经常以主/从安装形式配置,但其实Jenkins也可以部署在一台独立的电脑上。由一个主机控制何时进行代码的构建和测试,并为用户提供接口。Jenkins上的所有任务都叫做事件。由一个或多个从属机器执行实际的构建和测试工作。构建(工件,如最终的二进制文件、程序包、测试报告,等等)产生的所有重要结果,都会从从属机器转移到并保存到主机上。中间文件,如目标代码,还是保留在从属机器上(会定期移除)。主机会保留所有的历史构建结果,因而可以判断出项目的趋势。
从属机器没有什么特别的 —— 只要是装有所需的开发和测试工具的现成电脑就可以了。从属机器可以运行与主机不同的操作系统——这对于为多平台编写代码有重要意义。从属机器也可以连接到硬件设备,以便可以将嵌入式代码下载到实际设备中进行测试。从属机器也不一定要是实际机器,现在虚拟机正在越来越广泛地被用做从属机器,采用基于云的解决方案,因为这种方法成本较低。
插件
Jenkins完成的大多数自定义任务都是通过插件来实现的。Jenkins内核中定义好的应用程序界面(API),可以通过安装插件来丰富图形用户界面(GUI)的配置选项,这些功能在使用的时候就好像是内核的一部分一样。
现在有超过800(正在增多)种插件,插件涉及很多方面,包括:版本控制系统的交互作用、代码构建、测试、报告、工件管理。通过安装相关的插件,可以定制Jenkins,以适应项目的构建和测试需求。
仪表盘
Jenkins可通过仪表盘模式显示所有事件的整体状态。每个事件的状态都以点状形式显示,颜色表示上次执行的状态(在默认情况下,红色表示失败,黄色表示不稳定,蓝色表示成功——但是和Jenkins中的大多数功能一样,颜色也是可以自定义的)。闪烁的点表示该事件正在构建中。用“天气”的标志,通过晴天(太阳)、阴天(雷云)等天气状态,以比较直观的形式总结出最近的构建情况。
仪表盘会显示事件队列 —— 待构建事件的列表。同时还会显示从属机器的状态,指出哪些事件是不运行的,哪些正在执行。图4显示的是Apache Software Foundation的Jenkins仪表盘。
图4 Jenkins仪表盘 图4显示的是Jenkins仪表盘。右侧显示的是事件列表。左下方显示的是从属机器列表,从属机器列表的上方显示的是构建队列。
事件
每个事件都有一个页面记录构建的历史情况,通常情况下,是一些图形化输出,显示测试状态以及与最近的构建工件、代码修改及其它重要或相关的数据。
一个事件可被拆分成3个顶级阶段:
- 构建前。在这个阶段,会从存储库中检出最新的代码。通常是先检查存储库,看是否有新代码提交进来,如果有就检出。也可能是根据时间安排或在完成了其它事件之后,对存储库中的代码进行检出。
- 构建中。这一步在大多数实际工作完成之后开始,包括:从编译和耦合到对代码进行测试。Jenkins会记录所有命令的控制台输出,以便排除故障。
- 构建后。在这一过程中,需要对构建好的代码进行进一步测试。同时还要收集并解析测试结果,最后将结果显示出来。并将所需的工件存档到主机上。
构建阶段和构建后的阶段需不需要包含多个步骤,取决于构建/测试的需求,以及所安装的插件。
一个简单的事件可能要进行以下配置:
- 构建前: 版本控制系统应用程序,存储库的路径,模块名称
- 构建中:包含简单的“make”命令的shell执行步骤
- 构建后:对工件进行存档时要使用构建阶段生成的可执行文件的名称。
在执行事件的时候,Jenkins会从存储库中检出最新版本的代码,然后在shell中执行“make”命令,并将生成的可执行文件复制到主机上。如果其中某一步执行失败了,那么后面的步骤就都无法执行了,所以事件的状态就会显示为“失败”。只有当所有的步骤能准确无误地执行完成之后,该事件的状态才可能显示为“成功”。如果能达到这个最基本的水平,就可以用Jenkins安排夜间构建。
入门指导
Jenkins的入门很简单 —— 它可以以一个完整、可运行的网络应用程序的存档文件形式存在。该文件可以下载并执行 —— 但是,为了正确安装,要将它以服务/后台程序的形式安装,并按权限以用户的身份执行。
(未完待续。。。)
|