本篇博文宅鸟将在上篇: 基于Jenkins 搭建持续集成环境 的基础上,继续介绍Jenkins结合php项目实现自动化测试和自动部署。废话不再多说,直接上干活。
宅鸟所使用的server为Ubuntu
要实现在jenkins中实现php的自动化测试,首先需要Jenkins服务器上安装php测试框架,php的测试框架很多,在这里我们选择 PHPUnit Framework.
PHPUnit的安装很简单:
1.
sudo
apt-get
install
phpunit
如果出现如下错误:
1.
PHP Warning: require_once(PHP/CodeCoverage/Filter.php): failed to
open
stream: No such
file
or directory
in
/usr/bin/phpunit on line 39
2.
PHP Fatal error: require_once(): Failed opening required 'PHP/CodeCoverage/Filter.php' (include_path='.:/usr/share/php:/usr/share/pear')
in
/usr/bin/phpunit on line 39
可以通过下面方法安装:
01.
sudo
pear channel-discover pear.phpunit.de
02.
sudo
pear channel-discover pear.symfony-project.com
03.
sudo
pear channel-discover components.ez.no
04.
sudo
pear channel-discover pear.symfony.com
05.
sudo
pear update-channels
06.
sudo
pear upgrade-all
07.
sudo
pear
install
pear.symfony.com/Yaml
08.
sudo
pear
install
--alldeps phpunit/PHPUnit
09.
sudo
pear
install
--force --alldeps phpunit/PHPUnit
安装后执行phpunit --version 返回版本信息。表示安装成功。
1.
root@dop-kvm-2:
# phpunit --version
2.
PHPUnit 3.7.28 by Sebastian Bergmann.
下面我们开始给Jenkins一些插件:
Subversion/Git:用于集成项目版本控制软件,根据需要选择(在上篇博文已安装使用)
Phing/Ant:使用Phing或Apache Ant 对PHP项目做自动化构建
CheckStyle:使用PHP CodeSniffer进行代码风格检查的工具。用于检查PHP代码是否有违反一组预先设置好的编码标准的一个PEAR包,内置了ZEND,PEAR的编码风格规则
Clover PHP:使用phpunit进行单元测试的工具,可以被xdebug扩展用来生成代码覆盖率报告,并且可以与phing集成来自动测试,还可以和Selenium整合来完成大型自动化集成测试
DRY:使用PHPCPD(php copy paste detector)来发现项目中的重复代码
HTML Publisher:用来发布phpunit代码覆盖率报告
JDepend:使用PHP Depend分析php中静态代码,用来检查项目中的代码规模和复杂程度
Plot:使用phploc来统计php项目规模大小的工具,可以统计php的项目代码行数
PMD:使用phpmd(php mess dector),对基于pdepend的结果进行分析,一旦项目超过了pdepend中各具体指标的规定,将发出警告信息.
Violations:按照代码缺陷严重性集中显示pwd静态代码分析的结果
xUnit:使用JUnit的格式来输出phpunit的日志文件
注意这些插件是jenkins为php项目所提供的一些插件,但并不是必须的,所以宅鸟只把最值得大家关注的怎么自动化测试、打包和发布来给大家讲解。
先给出项目的目录结构:
01.
root@dop-kvm-2:/home/jenkins/api
# tree
02.
.
03.
├── aa.php
04.
├── build.xml
05.
├── create.php
06.
└──
test
07.
├── DemoTest.php
08.
└── FunctionTest.php
09.
1 directory, 5 files
注意:
aa.php、create.php是项目的程序文件
test目录下的DemoTest.php和FunxtionTest.php是项目的测试文件
build.xml是jenkins持续集成测试打包部署的调用文件
首先给出项目需要的build.xml文件:
001.
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
002.
<
project
name
=
"api"
default
=
"build"
>
003.
<
target
name
=
"build"
depends
=
"make_runtime,phpcs-ci,phploc,pdepend,phpcb,phpunit,phpdox,phpcpd"
/>
004.
<
property
name
=
"version-m"
value
=
"1.1"
/>
005.
<
property
name
=
"version"
value
=
"1.1.0"
/>
006.
<
property
name
=
"stability"
value
=
"stable"
/>
007.
<
property
name
=
"releasenotes"
value
=
""
/>
008.
<
property
name
=
"tarfile"
value
=
"${phing.project.name}.${buildnumber}.${buildid}.tar.gz"
/>
009.
<
property
name
=
"pkgfile"
value
=
"${phing.project.name}.${version}.tgz"
/>
010.
<
property
name
=
"distfile"
value
=
"dist/${tarfile}"
/>
011.
<
property
name
=
"tests.dir"
value
=
"test"
/>
012.
<
fileset
id
=
"api.tar.gz"
dir
=
"."
>
013.
<
include
name
=
"test/**"
/>
014.
<
include
name
=
"*.php"
/>
015.
<
include
name
=
"*.xml"
/>
016.
</
fileset
>
017.
<
target
name
=
"make_runtime"
>
018.
<
mkdir
dir
=
"${project.basedir}/Runtime"
/>
019.
<
mkdir
dir
=
"${project.basedir}/build/logs"
/>
020.
<
mkdir
dir
=
"${project.basedir}/build/pdepend"
/>
021.
<
mkdir
dir
=
"${project.basedir}/build/code-browser"
/>
022.
</
target
>
023.
<
target
name
=
"phpcs"
description
=
"Find coding standard violations using PHP_CodeSniffer"
>
024.
<
exec
executable
=
"phpcs"
>
025.
<
arg
value
=
"--standard=${project.basedir}/build/phpcs.xml"
/>
026.
<
arg
value
=
"--ignore=autoload.php"
/>
027.
<
arg
path
=
"${project.basedir}/"
/>
028.
</
exec
>
029.
</
target
>
030.
<
target
name
=
"phpcs-ci"
description
=
"Find coding standard violations using PHP_CodeSniffer"
>
031.
<
exec
executable
=
"phpcs"
output
=
"${project.basedir}/build/build.log"
>
032.
<
arg
value
=
"--report=checkstyle"
/>
033.
<
arg
value
=
"--report-file=${project.basedir}/build/logs/checkstyle.xml"
/>
034.
<
arg
value
=
"--standard=${project.basedir}/build/phpcs.xml"
/>
035.
<
arg
value
=
"--ignore="
/>
036.
<
arg
path
=
"${project.basedir}/"
/>
037.
</
exec
>
038.
</
target
>
039.
040.
<
target
name
=
"phploc"
description
=
"Measure project size using PHPLOC"
>
041.
<
exec
executable
=
"phploc"
>
042.
<
arg
value
=
"--log-csv"
/>
043.
<
arg
value
=
"${project.basedir}/build/logs/phploc.csv"
/>
044.
<
arg
path
=
"${project.basedir}/"
/>
045.
</
exec
>
046.
</
target
>
047.
048.
<
target
name
=
"pdepend"
description
=
"Calculate software metrics using PHP_Depend"
>
049.
<
exec
executable
=
"pdepend"
>
050.
<
arg
value
=
"--jdepend-xml=${project.basedir}/build/logs/jdepend.xml"
/>
051.
<
arg
value
=
"--jdepend-chart=${project.basedir}/build/pdepend/dependencies.svg"
/>
052.
<
arg
value
=
"--overview-pyramid=${project.basedir}/build/pdepend/overview-pyramid.svg"
/>
053.
<
arg
path
=
"${project.basedir}/"
/>
054.
</
exec
>
055.
</
target
>
056.
057.
<
target
name
=
"phpmd"
description
=
"Perform project mess detection using PHPMD"
>
058.
<
exec
executable
=
"phpmd"
>
059.
<
arg
path
=
"${project.basedir}/"
/>
060.
<
arg
value
=
"text"
/>
061.
<
arg
value
=
"${project.basedir}/build/phpmd.xml"
/>
062.
</
exec
>
063.
</
target
>
064.
065.
<
target
name
=
"phpmd-ci"
description
=
"Perform project mess detection using PHPMD"
>
066.
<
exec
executable
=
"phpmd"
>
067.
<
arg
path
=
"${project.basedir}/"
/>
068.
<
arg
value
=
"xml"
/>
069.
<
arg
value
=
"${project.basedir}/build/phpmd.xml"
/>
070.
<
arg
value
=
"--reportfile"
/>
071.
<
arg
value
=
"${project.basedir}/build/logs/pmd.xml"
/>
072.
</
exec
>
073.
</
target
>
074.
075.
<
target
name
=
"phpcpd"
description
=
"Find duplicate code using PHPCPD"
>
076.
<
exec
executable
=
"phpcpd"
>
077.
<
arg
value
=
"--log-pmd"
/>
078.
<
arg
value
=
"${project.basedir}/build/logs/pmd-cpd.xml"
/>
079.
<
arg
path
=
"${project.basedir}/"
/>
080.
</
exec
>
081.
</
target
>
082.
<
target
name
=
"phpdox"
description
=
"Generate API documentation using phpDox"
>
083.
<
exec
executable
=
"phpdox"
/>
084.
</
target
>
085.
<
target
name
=
"phpunit"
description
=
"Run unit tests with PHPUnit"
>
086.
<
exec
executable
=
"phpunit"
/>
087.
</
target
>
088.
<
target
name
=
"test"
description
=
"Run PHPUnit tests"
>
089.
<
phpunit
haltonerror
=
"true"
haltonfailure
=
"true"
printsummary
=
"true"
>
090.
<
batchtest
>
091.
<
fileset
dir
=
"${tests.dir}"
>
092.
<
include
name
=
"**/*Test.php"
/>
093.
</
fileset
>
094.
</
batchtest
>
095.
</
phpunit
>
096.
</
target
>
097.
<
target
name
=
"phpcb"
description
=
"Aggregate tool output with PHP_CodeBrowser"
>
098.
<
exec
executable
=
"phpcb"
>
099.
<
arg
value
=
"--log"
/>
100.
<
arg
path
=
"${project.basedir}/build/logs"
/>
101.
<
arg
value
=
"--source"
/>
102.
<
arg
path
=
"${project.basedir}/"
/>
103.
<
arg
value
=
"--output"
/>
104.
<
arg
path
=
"${project.basedir}/build/code-browser"
/>
105.
</
exec
>
106.
</
target
>
107.
<
target
name
=
"check"
description
=
"Check variables"
>
108.
<
fail
unless
=
"version"
message
=
"Version not defined!"
/>
109.
<
fail
unless
=
"buildnumber"
message
=
"buildnumber not defined!"
/>
110.
<
fail
unless
=
"buildid"
message
=
"buildid not defined!"
/>
111.
<
delete
dir
=
"dist"
failonerror
=
"false"
/>
112.
<
mkdir
dir
=
"dist"
/>
113.
</
target
>
114.
115.
<
target
name
=
"tar"
depends
=
"check"
description
=
"Create tar file for release"
>
116.
<
echo
msg
=
"Creating distribution tar for ${phing.project.name} ${version}"
/>
117.
<
delete
file
=
"${distfile}"
failonerror
=
"false"
/>
118.
<
tar
destfile
=
"${distfile}"
compression
=
"gzip"
>
119.
<
fileset
refid
=
"api.tar.gz"
/>
120.
</
tar
>
121.
</
target
>
122.
</
project
>
阅读build.xml后,大家可以了解一下内容:
项目名称、版本、打后的包名称:
01.
<
project
name
=
"api"
default
=
"build"
>
02.
<
target
name
=
"build"
depends
=
"make_runtime,phpcs-ci,phploc,pdepend,phpcb,phpunit,phpdox,phpcpd"
/>
03.
<
property
name
=
"version-m"
value
=
"1.1"
/>
04.
<
property
name
=
"version"
value
=
"1.1.0"
/>
05.
<
property
name
=
"stability"
value
=
"stable"
/>
06.
<
property
name
=
"releasenotes"
value
=
""
/>
07.
<
property
name
=
"tarfile"
value
=
"${phing.project.name}.${buildnumber}.${buildid}.tar.gz"
/>
08.
<
property
name
=
"pkgfile"
value
=
"${phing.project.name}.${version}.tgz"
/>
09.
<
property
name
=
"distfile"
value
=
"dist/${tarfile}"
/>
10.
<
property
name
=
"tests.dir"
value
=
"test"
/>
打包时包括的文件和文件夹:这里还可以使用exclude排除文件和文件夹:
1.
<
fileset
id
=
"api.tar.gz"
dir
=
"."
>
2.
<
include
name
=
"test/**"
/>
3.
<
include
name
=
"*.php"
/>
4.
<
include
name
=
"*.xml"
/>
5.
</
fileset
>
测试文件所在地址:
01.
<
target
name
=
"phpunit"
description
=
"Run unit tests with PHPUnit"
>
02.
<
exec
executable
=
"phpunit"
/>
03.
</
target
>
04.
<
target
name
=
"test"
description
=
"Run PHPUnit tests"
>
05.
<
phpunit
haltonerror
=
"true"
haltonfailure
=
"true"
printsummary
=
"true"
>
06.
<
batchtest
>
07.
<
fileset
dir
=
"${tests.dir}"
>
08.
<
include
name
=
"**/*Test.php"
/>
09.
</
fileset
>
10.
</
batchtest
>
11.
</
phpunit
>
12.
</
target
>
了解这些后,我们开始在jenkins中新建autoTestTarAndPublish项目,选择:构建一个自由风格的软件项目:
并且指定好代码库:如图所示
然后再 增加构建步骤->Invoke Phing targets:
增加两个 target: test,tar 分别与build.xml中的test,tar名称相对应
给tar加上参数:
然后在左边主菜单: 系统管理->系统设置->Publish over SSH 下添加主机:(这里宅鸟设置使用ssh免密码登陆)需要设置成从jenkins到要发布的web服务器的无密码登陆
如图设置:
这里添加设置的主机名是:134
接下来我们就可以设置部署工作了:
在添加构建步骤下来表中选择:Send files or execute commands over SSh,如果该选项未出现需要在插件管理中安装插件:Publish Over SSH 然后重启jenkins即可.
然后在出现的SSH Publishers中选择要发布的主机:
并填写打包文件地址,发布到远程server地址信息,并在Exec command文本框中填写解压等shell脚本:
详情见图:
此项设置完毕后,就可以发布php项目到134服务器上了:
最后文件发布包的存档工作:
增加构建后操作步骤:
填写dist/*.tar.gz
至此配置完毕后,点击 保存 按钮.我们就可以发布程序到指定服务器134上了.
来看一下发布结果:
回到项目左侧点击:立即构建:可以看到构建进度条,结束后可以在控制台看到输出结果:
我们来到134上看:
至此发布完毕.
此时我们查看一下test/DemoTest.php文件内容:
01.
<?php
02.
class
DemoTest
extends
PHPUnit_Framework_TestCase {
03.
public
function
testPass() {
04.
$this
->assertTrue(true);
05.
}
06.
public
function
testFail() {
07.
$this
->assertFalse(false);
08.
}
09.
}
10.
?>
我们把 testFail()改成下面:
01.
<?php
02.
class
DemoTest
extends
PHPUnit_Framework_TestCase {
03.
public
function
testPass() {
04.
$this
->assertTrue(true);
05.
}
06.
public
function
testFail() {
07.
$this
->assertTrue(false);
08.
}
09.
}
10.
?>
$this
->assertTrue(false);
这个是错误的断定:
提交文件后再次构建:
我们可以看到本次构建失败,查看输出结果如下:
当把测试用例修改回正确后,执行构建,发布正确。
01.
<?php
02.
class
DemoTest
extends
PHPUnit_Framework_TestCase {
03.
public
function
testPass() {
04.
$this
->assertTrue(true);
05.
}
06.
public
function
testFail() {
07.
$this
->assertFalse(false);
08.
}
09.
}
10.
?>
ok,到此介绍结束.
总结一下:
jenkins根据项目根目录下的build.xml文件,并根据jenkins中targets的配置,首先自动执行test,当测试通过后,开始执行tar,打包完成后,开始链接远程webserver把程序包上传到远程webserver指定目录下,然后再根据jenkins下的command 执行解压操作,然后就可以根据自己的业务通过shell脚本进行自动处理自动发布的各项操作.
如果在执行test过程中,出现发现测试用例不通过,则就发出错误报告,终止本次构建。
下一篇博文,将介绍jenkins结合ansible、shell和mysql版本迁移实现多服务器批量发布.敬请关注
干货吐槽完毕,由于时间仓储,有不足之处欢迎拍砖.
联系客服