分类: 项目管理
2010-12-22 18:05:51
安装和配置 Hudson 持续集成引擎以持续构建和测试 Oracle ADF 应用程序的基础知识。
作者:John Stegeman
2010 年 3 月发布
两个或更多的开发人员就一个项目协同工作时会将多个开发人员的代码集成在一起,如果某个开发人员的代码有不良的影响或代码之间发生交互,就可能会出现问题。在“传统”开发环境下,各个开发人员可能会在较长的时间内独立完成各自的代码编写工作,这些代码集成问题可能在实际编写代码之后很长时间才被发现,与在开发周期早期发现这些问题相比,这样会加大识别和解决这些集成问题的难度。为了解决这一滞后问题,应运而生了一种称为持续集成(即 CI)的新的开发技术。在 CI 环境下,在开发过程的早期并且常常是在开发过程中即将多个开发人员的代码集成在一起进行共同测试。这有助于开发人员在开发出代码后不久即可发现问题,而此时开发人员对导致问题的代码还记忆犹新,从而可以更加快速地纠正这些问题。此外,及早发现问题可防止问题扩大,防止问题变得更复杂、更难以解决,防止产生更为高昂的问题诊断和解决成本。
由于构建和测试应用程序的工作会占用大量资源,因此采用 CI 通常意味着采用一种工具来自动进行应用程序的构建和测试。在互联网上快速搜索一下即可发现众多的 CI 服务器,截至本文撰写之日,有关 CI 的 Wikipedia 文章有不下 35 种服务器示例!CI 服务器的工作原理是:等待某种触发条件(如定期调度、开发人员请求,或者开发人员向版本控制系统提交代码),然后执行一次应用程序的完全构建并运行相应的测试。使用此方法的项目组通常会遵循一个过程,该过程要求开发人员至少每天提交一次代码。如果开发人员提交的代码导致 CI 构建“中断”(测试失败或编译失败),通常会向该开发人员分派某项非预期的公共任务令其完成,从而促使其采取措施以避免构建中断。甚至有一些有点奇特的硬件设备可公开显示构建状态,如。
在这么多可以使用的 CI 服务器中,您如何进行选择呢?对于基于 Java 的项目来说,有:
对于本文,我之所以选择使用 Hudson 有以下两个原因:第一个原因是,它是一个使用非常广泛的系统,因此,它有着广大的用户群和丰富的插件(在本文稍后,您会看到插件是多么有用)。第二个原因是,与 Cruise Control(虽然也是广泛使用)不同,Hudson 的安装和配置相当容易。
我们将使用本系列较早的文章中开发的 Oracle Application Development Framework (Oracle ADF) 11g 应用程序、单元测试和 UI 测试。如果您没有跟随学习本系列文章,可以从这里下载源代码:oracle.com/technology/pub/files/adf-development-essentials-sample.zip。对于本文,我还从 VisualSVN Subversion 信息库中删除了“everyone”访问,要求访问时提供登录凭证,这样我们可以看到其工作方式。如果您这么做,我建议您在 Subversion 服务器中专门为 Hudson 创建一个用户,这样 Hudson 可执行的任何操作(如对一个构建进行标记)将被记录为由 Hudson 完成。如果您的信息库是不受保护的,则可跳过这些提供凭证的相关步骤。
开发人员使用的便携式计算机 (Windows Vista)
计算机名:jstegema-lap
安装了 Oracle JDeveloper 11g
安装了 Oracle Database 11g 和 Visual SVN(用于测试)
CI 服务器(虚拟机)
计算机名:jstegema-lnx
安装了 OpenSUSE 11.2RC2 和 Hudson
在 CI 服务器上,我们需要的第一个组件是能够运行 Hudson 的 JDK。我的 CI 服务器上已经安装了一个 JDK,这对于 Hudson 的运行来说是件好事,但作为编译 Oracle ADF 11g 应用程序所使用的 JDK,它稍微有点过时了。尽管 Hudson 能够自动下载并安装 JDK 和各种版本的 Ant,但这个过程确实需要进行一点配置。因此,对于本文,我将手动下载并安装最新的 JDK。而对于 Ant,您可能还记得我们在本系列的 JUnit 一文中讲过,需要将一些 JAR 文件从 Oracle JDeveloper 安装中复制到 Ant 的 library 目录中,因此我们无法使用自动安装功能,必须亲自安装 Ant 并复制各个库。
为了安装 Ant,只需从 下载,将其解压缩至 CI 服务器上一个合适的目录。如 Ant 一文中所述,我们需要从 Oracle JDeveloper 11g 安装中将 junit.jar 和 ant-weblogic.jar(这些文件在 <安装目录>/jdeveloper/ant/lib 下)复制到您已下载并解压缩的 Ant 的 lib 目录中。
下一步是告诉 Hudson 我们打算使用的 JDK 和 Ant 安装。幸运的是,所有 Hudson 配置都通过一个 Web 界面进行并且相当简单。首先,在浏览器中访问 Hudson URL(默认)并单击 Manage Hudson 链接。然后,在 Manage Hudson 页面中,单击 Configure System。在此页面中,您可以配置 JDK 和 Ant 这两个安装。首先,在 JDK 区域中,单击 Add JDK 按钮。取消选中 Install Automatically 复选框,提供一个易于记忆的名称(我建议使用 JDK 的版本作为名称)并提供 JDK 的安装位置。我的系统上的配置如下所示:
图 1:JDK 配置
接下来,重复上述过程以添加一个 Ant 安装。下面是我的配置:
图 2:Ant 配置
单击 Save 按钮保存该配置。现在,您创建 Hudson 作业时即可使用已配置的 JDK 和 Ant 安装了。
创建一个提交触发构建和测试的作业
我们首先创建一个 Hudson 作业,该作业有以下特点:
此作业将展示 Hudson 的基本功能。我们建立好该作业之后,将看一下如何使用 Hudson 的插件在该作业中添加更多功能。首先,转到 Hudson 主页,该页面位于 您的主机名>:8080。我们很容易就可以开始:该 Hudson 页面中央向您发出这样的邀请,“please create new jobs to get started”。此时单击 create new jobs 链接。接着,Hudson 让您指定作业名称并选择要创建的作业类型。我们以 Build and Test OTN Trunk 作为该作业的名称(我们将从 Subversion 中的“trunk”项目构建),该作业类型为“free-style software project”(用 Hudson 的术语说)。填入相应信息,然后单击 OK:
图 3:新作业的信息
在出现的下一个屏幕中,您将进行整个作业自身的配置。如果您愿意,在所提供的域中为该作业提供一个说明。在这里,我们并不会对作业屏幕上的每个选项的用途都加以解释,而只是看一看为了配置该作业至少需要哪些选项。为了指定运行 Ant 任务时使用哪个 JDK,我们将该构建配置为 Hudson 中参数化的构建,并添加一个字符串参数以设置 JAVA_HOME 参数的值。为此,选中 This build is parameterized 复选框,使用下拉列表添加一个名为 JAVA_HOME 的字符串参数,令其值指向您系统中相应的 JDK,如下所示:
图 4:设置该构建作业的 JAVA_HOME 参数
我们需要提供的下一项是 Source Code Management (SCM) 信息。由于我们使用 Subversion,因此可单击 Subversion 单选按钮查看 Subversion 的相关选项。我们需要提供的唯一一项信息是我们要从其中进行构建的 Subversion URL。提供在您的环境下该应用程序的“trunk”项目的 URL。我这里是 。
图 5:该作业的 Subversion URL
从屏幕截图中可以看出,Hudson 立刻就知道了该 Subversion 信息库是受保护的。单击 enter credential 链接,提供该信息库的用户名和口令。在新打开的窗口中,提供正确信息后单击 OK。我这里是这样的:
图 6:Subversion 身份验证
接下来,我们需要设置一个构建触发器。我们说过我们希望 CI 作业在开发人员向 Subversion 提交更改时运行。对此,Hudson 有一个相应的选项:Poll SCM。单击 Poll SCM 复选框之后,您就可以指定轮询调度周期了。以 cron 作业所使用的格式指定该调度周期(有关详细信息和示例,可单击该域的 Help 按钮获取)。我们让该作业每分钟对新的提交进行一次轮询,这样我们就不必等很长时间才能看到系统的反应了:
图 7:SCM 轮询调度
接着,添加我们希望 Hudson 在该构建过程中执行的一些步骤。根据我们对该作业的描述,我们希望让 Hudson 执行下列 Ant 任务:
我们来添加第一个构建步骤:单击 Add build step 列表并选择 Invoke Ant:
图 8:添加一个基于 Ant 的构建步骤
然后,您可以从列表中指定要使用的 Ant 版本。由于在我们的项目中有多个 Ant build.xml 文件,我们需要单击 Advanced 按钮告诉 Hudson 具体使用哪一个。应相对于 Subversion URL 的路径来指定构建文件。因此,要让 Hudson 在 Model 项目的 Ant build.xml 中执行 model.compile 任务,填写如下信息:
图 9:针对 model.build Ant 任务的构建步骤
接着,您可以按上述过程对另外两个 Ant 任务再添加两个构建步骤。对这两个任务的配置如下:
图 10:剩余的构建步骤
配置该作业的最后一步是设置作业的任何构建后操作。通过查看各个选项您可以发现,您可以做很多的事情,如向某人发送电子邮件以让其知道构建状况,或者发布 Javadoc。我们关注的是发布 JUnit 测试结果。选中相应复选框,将 JUnit 测试结果的存放位置告诉 Hudson(同样,使用相对于 Subversion URL 的路径,Hudson 需要该路径以“trunk”开头):
图 11:指定测试结果的位置
现在可单击 Save 按钮保存该作业。Hudson 将首次运行该构建作业。您可以单击右上角的 ENABLE AUTO REFRESH 链接来查看构建进度。一旦构建开始,您会看到 Build History 小部件开始呈现动画效果(如果 Hudson 没有自动启动构建,您始终可以单击 Build Now 链接):
图 12:构建状态小部件
如果想监视构建详情,可单击该构建的链接,然后单击 Console Output 链接以查看输出。该控制台视图还非常有助于您理解构建失败的原因(作业配置错误、编译失败等等)。例如,在重复进行的一次构建步骤中,我键入了错误的 Ant 任务,于是在控制台视图中看到以下信息:
图 13:由于构建失败而产生的控制台日志
当我返回 Hudson Dashboard 页面时,看到我的作业状态是失败(以一个大红球来指示)并且该项目的“天气状况”是暴风雨:
图 14:暴风雨项目
希望您的第一个构建成功进行。一旦您改正了所有可能的错误并且构建成功,该信息板就开始呈现一个更妥当的画面:
图 15:更妥当的画面
请注意,由于最近存在构建失败,该项目的“天气状态”不会立即转为晴朗。一旦您进行了一连串成功的构建,您的项目就会转为晴朗宜人了。您可以单击 Last Success 或 Last Failure 列中的任何链接来查看有关该构建的信息。例如,当我单击上次成功构建的相关链接时,出现了有关该构建的状态页面:
图 16:一个构建状态页面
通过该页面,我可以查看到以下测试结果:
图 17:测试结果
. . 甚至可以下钻到各个测试:
图 18:各个测试结果
要对触发构建的能力进行测试,您可以在 Oracle JDeveloper 11g 中对应用程序进行一次更改后提交该更改。不久之后,您会在 Hudson 信息板中看到,Hudson 发现了该更改并启动了构建过程:
图 19:正在进行构建
一旦构建完成,如果单击其构建号,可以看到一个说明该构建由某个 SCM 更改触发的指示、开发人员提供的有关该次提交的注释,甚至还可以看到一个 detail 链接,该链接可显示出提交者和提交者所更改的文件:
图 20:构建结果显示出该构建由 SCM 更改启动
为了能够运行 UI 测试,首先须将应用程序打包到一个企业存档 (EAR) 文件,然后将其安装到 Oracle WebLogic Server 上以便测试。此外,UITests 项目还需要一个运行 UI 测试的 Ant 脚本。对此过程的逐步详细说明会使本文变得过长,因此我在此概要介绍一下这些步骤:
完成上述准备步骤后,您就可以创建该 Hudson 作业了。对该 Hudson 作业的配置十分类似于对您创建的第一个作业的配置,只是有以下不同:
图 21:每天午夜时分执行该作业
图 22:针对 UI 测试的构建步骤
图 23:发布 UI 测试结果
创建该作业之后,确保 Oracle WebLogic Server 和 Selenium RC 启动(如果愿意,可以在 Ant 任务中添加步骤以启动它们),然后执行该作业。如果您观察构建服务器,最终会看到一个浏览器窗口弹出(这是 Selenium RC 所为)并执行 UI 测试。如果一切正常,您会看到在 Hudson 信息板中出现了两个“晴朗的”项目:
图 24:两个“晴朗的”项目!
现在,您已具备了所有相应工具,能够以团队的形式有效地开发 Oracle ADF 应用程序,能够使项目构建通过 Ant 自动进行、使单元测试通过 JUnit 自动进行、使 UI 测试通过 Selenium 自动进行,并能够通过 Hudson 对您的应用程序进行持续的集成和测试了。希望您觉得这些文章对您有所帮助。
致谢John Stegeman () 是 Cambridge Solutions(一家跨国 BPO 和 IT 服务公司)的 EMEA 地区的 Oracle ACE 总监(Oracle 融合中间件)兼首席架构师。他从 1990 年开始就使用 Oracle 产品工作,从版本 3 开始就使用 Oracle JDeveloper 了。