持续集成
欢迎阅读WebDriver持续集成讲义。本篇讲义将会重点介绍Selenium WebDriver API的在持续集成中的使用方法,以及使用Jenkins持续集成工具进行自动化测试的设计。
持续集成的概念
持续集成的定义
持续集成,Continuous integration ,简称CI。
随着软件开发复杂度的不断提高,团队开发成员间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题。尤其是近些年来,敏捷(Agile) 在软件工程领域越来越红火,如何能再不断变化的需求中快速适应和保证软件的质量也显得尤其的重要。
持续集成正是针对这一类问题的一种软件开发实践。首先我们看一下,敏捷教父 Martin Fowler
对持续集成的定义:
Martin Fowler:*Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. *
具体定义:持续集成式一种软件开发实践。它倡导团队的成员必须经常的集成他们的工作,通常至少每天一次甚至更多次集成。每次集成都需要通过自动化的构建(包括编译代码、构建应用、部署程序以及自动化测试)来验证,从而尽早尽快的发现集成中的错误。大量的团队利用这样的方式来更快的开发内聚的软件。大大减少此过程中的集成问题。
具体的流程图如下:
Paste_Image.png
持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元、自动化)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。
首先,解释下集成。我们所有项目的代码都是托管在SVN服务器上。每个项目都要有若干个单元测试,并有一个所谓集成测试。所谓集成测试就是把所有的单元测试跑一遍以及其它一些能自动完成的测试。只有在本地电脑上通过了集成测试的代码才能上传到SVN服务器上,保证上传的代码没有问题。所以,集成指集成测试。
再说持续。不言而喻,就是指长期的对项目代码进行集成测试。既然是长期,那肯定是自动执行的,否则,人工执行则没有保证,而且耗人力。对此,我们有一台服务器,它会定期的从SVN中检出代码,并编译,然后跑集成测试。每次集成测试结果都会记录在案。完成这方面工作的就是下面要介绍的Jenkins软件。当然,它的功能远不止这些。在我们的项目中,执行这个工作的周期是1天。也就是,服务器每1天都会准时地对SVN服务器上的最新代码自动进行一次集成测试。
Paste_Image.png
持续集成的特点
- 它是一个自动化的周期性的集成测试过程,从检出代码、编译构建、运行测试、结果记录、测试统计等都是自动完成的,无需人工干预;
- 需要有专门的集成服务器来执行集成构建;
- 需要有代码托管工具支持;
持续集成的作用
- 代码库存越是积压,就越得不到生产检验,积压越多,代码间交叉感染的概率越大,下个发布(release)的复杂度和风险越高,持续集成可以保证团队开发人员提交代码的质量,减轻了软件发布时的压力;
- 持续集成中的任何一个环节都是自动完成的,无需太多的人工干预,有利于减少重复过程以节省时间、费用和工作量;
- 及早的发现代码中的问题,及早解决,代码越早推送(PUSH)出去,用户能越早用到,快就是商业价值;
举个例子,你家装修厨房,其中一项是铺地砖,边角地砖要切割大小。如果一次全切割完再铺上去,发现尺寸有误的话浪费和返工时间就大了,不如切一块铺一块。装修厨房有很多部分,每个部分都有检测手段,如地砖铺完了要测试漏水与否,线路铺完了要通电测试电路通顺,水管装好了也要测试冷水热水。如果全部装完了再测,出现问题可能会互相影响,比如电路不行可能要把地砖给挖开……。全部装修完了,你去验收,发现地砖颜色不合意,水池太小,灶台位置不对,返工吗?所以不如没完成一部分,你就去用一下试用验收……这就是持续集成。在敏捷的思想里面,不光强调上面的过程,还需要强调自动化这个过程。过技术手段自动化这三个工作。加快交付速度,自动化测试是一个重要的组成部分。
Jenkins
Jenkins介绍
Jenkins,原名Hudson,2011年改为现在的名字,它 是一个开源的实现持续集成的软件工具。官方网站:http://jenkins-ci.org/。
Hudson是在2004年的夏天由Sun公司开发的(就是开发Java的那家),2005年2月开源并发布了第一个版本。Hudson发布的时候CruiseControl是CI界的老大哥,但是很快,在大约2007年的时候Hudson已经超越CruiseControl。2008年5月的JavaOne大会上,Hudson获得了开发解决方案类的Duke's Choice奖项。从此,小弟翻身做大哥,Hudson成为CI的代名词。
2009年6月,Oracle收购Sun。2010年9月,Oracle注册了Hudson的商标,然后就没有然后了。
mv -f Hudson Jenkins
Jenkins 能实施监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象地展示项目构建的趋势和稳定性。
Jenkins特点
- 易安装:仅仅一个
java -jar jenkins.war
,从官网下载该文件后,直接运行,无需额外的安装,更无需安装数据库; - 易配置:提供友好的GUI配置界面;
- 变更支持:Jenkins能从代码仓库(git/Subversion/CVS)中获取并产生代码更新列表并输出到编译输出信息中;
- 支持永久链接:用户是通过web来访问Jenkins的,而这些web页面的链接地址都是永久链接地址,因此,你可以在各种文档中直接使用该链接;
- 集成E-Mail/RSS/IM:当完成一次集成时,可通过这些工具实时告诉你集成结果(据我所知,构建一次集成需要花费一定时间,有了这个功能,你就可以在等待结果过程中,干别的事情);
- JUnit/TestNG测试报告:也就是用以图表等形式提供详细的测试报表功能;
- 支持分布式构建:Jenkins可以把集成构建等工作分发到多台计算机中完成;
- 文件日志信息:Jenkins会保存哪次集成构建产生了哪些jars文件,哪一次集成构建使用了哪个版本的jars文件等构建记录;
- 支持第三方插件:使得 Jenkins 变得越来越强大;
Jenkins的安装
需要从官网下载Jenkins的文件,在本地安装Java(jdk)的环境以后,直接执行以下语句进行安装:
java -jar jenkins.war
注意上述操作,一定是在Java环境已经配置好的情况下进行。输出如下:
Microsoft Windows [Version 10.0.10532]
(c) 2015 Microsoft Corporation. All rights reserved.
C:\Users\erha>java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
C:\Users\erha>java -jar d:\Jenkins\jenkins.war
Running from: D:\Jenkins\jenkins.war
webroot: $user.home/.jenkins
Jun 19, 2016 12:52:18 AM winstone.Logger logInternal
INFO: Beginning extraction from war file
Jun 19, 2016 12:52:29 AM org.eclipse.jetty.util.log.JavaUtilLog info
INFO: jetty-winstone-2.9
Jun 19, 2016 12:52:33 AM org.eclipse.jetty.util.log.JavaUtilLog info
INFO: NO JSP Support for , did not find org.apache.jasper.servlet.JspServlet
Jenkins home directory: C:\Users\erha\.jenkins found at: $user.home/.jenkins
Jun 19, 2016 12:52:35 AM org.eclipse.jetty.util.log.JavaUtilLog info
INFO: Started SelectChannelConnector@0.0.0.0:8080
Jun 19, 2016 12:52:35 AM winstone.Logger logInternal
INFO: Winstone Servlet Engine v2.0 running: controlPort=disabled
Jun 19, 2016 12:52:36 AM jenkins.InitReactorRunner$1 onAttained
INFO: Started initialization
Jun 19, 2016 12:53:11 AM jenkins.InitReactorRunner$1 onAttained
INFO: Listed all plugins
Jun 19, 2016 12:53:12 AM jenkins.InitReactorRunner$1 onAttained
INFO: Prepared all plugins
Jun 19, 2016 12:53:12 AM jenkins.InitReactorRunner$1 onAttained
INFO: Started all plugins
Jun 19, 2016 12:53:12 AM jenkins.InitReactorRunner$1 onAttained
INFO: Augmented all extensions
Jun 19, 2016 12:53:15 AM jenkins.InitReactorRunner$1 onAttained
INFO: Loaded all jobs
Jun 19, 2016 12:53:25 AM hudson.model.AsyncPeriodicWork$1 run
INFO: Started Download metadata
Jun 19, 2016 12:53:26 AM org.jenkinsci.main.modules.sshd.SSHD start
INFO: Started SSHD at port 10556
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Completed initialization
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Started initialization
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Listed all plugins
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Prepared all plugins
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Started all plugins
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Augmented all extensions
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Loaded all jobs
Jun 19, 2016 12:53:26 AM jenkins.InitReactorRunner$1 onAttained
INFO: Completed initialization
Jun 19, 2016 12:53:26 AM hudson.WebAppMain$3 run
INFO: Jenkins is fully up and running
Jun 19, 2016 12:53:32 AM hudson.model.UpdateSite updateData
INFO: Obtained the latest update center data file for UpdateSource default
Jun 19, 2016 12:53:33 AM hudson.model.DownloadService$Downloadable load
INFO: Obtained the updated data file for hudson.tasks.Maven.MavenInstaller
Jun 19, 2016 12:53:34 AM hudson.model.DownloadService$Downloadable load
INFO: Obtained the updated data file for hudson.tasks.Ant.AntInstaller
Jun 19, 2016 12:53:37 AM hudson.model.DownloadService$Downloadable load
INFO: Obtained the updated data file for hudson.tools.JDKInstaller
Jun 19, 2016 12:53:37 AM hudson.model.AsyncPeriodicWork$1 run
INFO: Finished Download metadata. 12,471 ms
随后访问http://localhost:8080即可
最后,将Jenkins安装成Windows服务启动
在Jenkins的主页中选择 Manager Jenkins
[图片上传失败...(image-223b63-1516464936475)]
接下来选择 Install as Windows Service
[图片上传失败...(image-7398af-1516464936476)]
在Installation Directory中选择jenkin的安装路径。这里会默认产生,直接点击Install就可以了。
[图片上传失败...(image-7beb5b-1516464936476)]
随后我们点击Yes,然后可以看到Windows服务中添加了Jenkins的服务,并已经设置为自动和启动状态。
[图片上传失败...(image-c7aaac-1516464936476)]
持续集成的实践
创建Jenkins Job
Jenkins提供了四种类型的Job:
- 构建一个自由风格的软件项目:这个是Jenkins的主要功能,可以构建一个你自己需要的项目。
- 构建一个maven项目:这是基于maven构建的项目,整个过程将会基于你的.pom文件进行构建,大大减轻构建的配置
- 构建一个多配置项目:这种项目适用多配置的项目,比如多个平台定制的构建,多个测试环境的部署构建等。
- 监控一个外部的任务:这种事允许你记录和执行不在Jenkins中的Job,这些Job可以运行在远程的主机上,Jenkins通过远程自动构建,作为一个控制面板而存在。
运行Jenkins Job
运行Job只需要在页面的左侧选中已经列出的项目,进行操作就可以了。选择立即构建,便可以进行自动构建的工作了。
定时构建 Job
目前有一个每日构建的概念。
Daily Build,每日构建。需要Jenkins在每日固定的时间进行代码自动构建、集成和测试的工作。那么需要定制执行时间。Jenkins的自动构建定制时间是遵循cron语法的。具体来说,每一行包括了5个用白空格或者Tab隔开的字段,分别是:MINUTE HOUR DOM MONTH DOW
。具体的格式我们参考下图
字段 | 说明 | 示例 |
---|---|---|
MINUTE | Minutes within the hour (0–59) | 30 |
HOUR | The hour of the day (0–23) | 17 |
DOM | The day of the month (1–31) | 1 |
MONTH | The month (1–12) | 5 |
DOW | The day of the week (0–7) where 0 and 7 are Sunday. | 5 |
然后每个格式,都可以由*
,-
,/
和,
4种字符组成:
*
代表所有可能的值-
代表整数之间的范围/
代表指定的时间的间隔频率,
代表指定的列表范围
命令的格式参考和示例
分钟 | 小时 | 天 | 月份 | 星期 | 执行的命令 | |
---|---|---|---|---|---|---|
* | 16 | 1,10,20 | * | * | python xxx | 每个月的1,10,20日的16:00执行 python xxx 命令格式:* 16 1,10,20 * * |
* | 16 | * | * | 1-5 | python yyy | 每个周的周一到周五的16:00执行 python yyy 命令格式:* 16 * * 1-5 |
30 | 17 | * | * | 1,5 | python zzz | 每个周的周一和周五的17:30执行 python zzz 命令格式:30 17 * * 1,5 |
ps: 注意时间是伦敦时间
至此,我们将会对Jenkins有一个非常范和初步的了解过程。
示例:
1. 创建SVN仓库
https://172.31.95.168/svn/DemoRepo/
ciuser / ciuser
2. 从SVN仓库签出文件到CI Server
3. 构建 build
4. 部署
4.1 备份目标文件夹
若有ranzhi_bak 需要先删除
rd /s /q c:\xampp\htdocs\ranzhi_bak
把 htdoc的ranzhi改成 ranzhi_bak
xcopy c:\xampp\htdocs\ranzhi c:\xampp\htdocs\ranzhi_bak\ /s /e /y
rd /s /q c:\xampp\htdocs\ranzhi
4.2 复制构建的版本到目标文件夹
把workspace的 ranzhi 复制到 htdocs下面
xcopy "%WORKSPACE%\ranzhi" c:\xampp\htdocs\ranzhi\ /s /e /y
4.3 恢复配置文件
复制 ranzhi_bak\config\my.php 到 ranzhi\config\my.php
xcopy c:\xampp\htdocs\ranzhi_bak\config\my.php c:\xampp\htdocs\ranzhi\config\ /e
5. 自动化测试
python D:\Git\Coding\BWFTraining\3.03_Selenium\codes\weekend2demo\ranzhi_test_runner.py
最后
最后跟大家推荐一个学习资料分享群:672899761,
里面大牛已经为我们整理好了许多的学习资料,有自动化,接口,性能等等的学习资料!
人生是一个逆水行舟的过程,不进则退,咱们一起加油吧!