基于jenkins 搭建持续集成环境 的基础上,继续介绍jenkins结合php项目实现自动化测试和自动部署。废话不再多说,直接上干活。
宅鸟所使用的server为ubuntu
要实现在jenkins中实现php的自动化测试,首先需要jenkins服务器上安装php测试框架,php的测试框架很多,在这里我们选择 phpunit framework.
phpunit的安装很简单:
sudo apt-get install phpunit
如果出现如下错误:
php warning: require_once(php/codecoverage/filter.php): failed to open stream: no such file or directory
in /usr/bin/phpunit on line 39
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
可以通过下面方法安装:
sudo pear channel-discover pear.phpunit.de
sudo pear channel-discover pear.symfony-project.com
sudo pear channel-discover components.ez.no
sudo pear channel-discover pear.symfony.com
sudo pear update-channels
sudo pear upgrade-all
sudo pear install pear.symfony.com/yaml
sudo pear install --alldeps phpunit/phpunit
sudo pear install --force --alldeps phpunit/phpunit
安装后执行phpunit --version 返回版本信息。表示安装成功。
root@dop-kvm-2:# phpunit --version
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项目所提供的一些插件,但并不是必须的,所以宅鸟只把最值得大家关注的怎么自动化测试、打包和发布来给大家讲解。
先给出项目的目录结构:
root@dop-kvm-2:/home/jenkins/api# tree
.
├── aa.php
├── build.xml
├── create.php
└── test
├── demotest.php
└── functiontest.php
1 directory, 5 files
注意:
aa.php、create.php是项目的程序文件
test目录下的demotest.php和funxtiontest.php是项目的测试文件
build.xml是jenkins持续集成测试打包部署的调用文件
首先给出项目需要的build.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<project name="api" default="build">
<target name="build" depends="make_runtime,phpcs-ci,phploc,pdepend,phpcb,phpunit,phpdox,phpcpd"/>
<property name="version-m" value="1.1" />
<property name="version" value="1.1.0" />
<property name="stability" value="stable" />
<property name="releasenotes" value="" />
<property name="tarfile" value="${phing.project.name}.${buildnumber}.${buildid}.tar.gz" />
<property name="pkgfile" value="${phing.project.name}.${version}.tgz" />
<property name="distfile" value="dist/${tarfile}" />
<property name="tests.dir" value="test" />
<fileset id="api.tar.gz" dir=".">
<include name="test/**"/>
<include name="*.php"/>
<include name="*.xml"/>
</fileset>
<target name="make_runtime">
<mkdir dir="${project.basedir}/runtime" />
<mkdir dir="${project.basedir}/build/logs" />
<mkdir dir="${project.basedir}/build/pdepend" />
<mkdir dir="${project.basedir}/build/code-browser" />
</target>
<target name="phpcs" description="find coding standard violations using php_codesniffer">
<exec executable="phpcs">
<arg value="--standard=${project.basedir}/build/phpcs.xml" />
<arg value="--ignore=autoload.php" />
<arg path="${project.basedir}/" />
</exec>
</target>
<target name="phpcs-ci" description="find coding standard violations using php_codesniffer">
<exec executable="phpcs" output="${project.basedir}/build/build.log">
<arg value="--report=checkstyle" />
<arg value="--report-file=${project.basedir}/build/logs/checkstyle.xml" />
<arg value="--standard=${project.basedir}/build/phpcs.xml" />
<arg value="--ignore=" />
<arg path="${project.basedir}/" />
</exec>
</target>
<target name="phploc" description="measure project size using phploc">
<exec executable="phploc">
<arg value="--log-csv" />
<arg value="${project.basedir}/build/logs/phploc.csv"/>
<arg path="${project.basedir}/"/>
</exec>
</target>
<target name="pdepend" description="calculate software metrics using php_depend">
<exec executable="pdepend">
<arg value="--jdepend-xml=${project.basedir}/build/logs/jdepend.xml"/>
<arg value="--jdepend-chart=${project.basedir}/build/pdepend/dependencies.svg"/>
<arg value="--overview-pyramid=${project.basedir}/build/pdepend/overview-pyramid.svg"/>
<arg path="${project.basedir}/"/>
</exec>
</target>
<target name="phpmd" description="perform project mess detection using phpmd">
<exec executable="phpmd">
<arg path="${project.basedir}/"/>
<arg value="text"/>
<arg value="${project.basedir}/build/phpmd.xml"/>
</exec>
</target>
<target name="phpmd-ci" description="perform project mess detection using phpmd">
<exec executable="phpmd">
<arg path="${project.basedir}/"/>
<arg value="xml"/>
<arg value="${project.basedir}/build/phpmd.xml"/>
<arg value="--reportfile"/>
<arg value="${project.basedir}/build/logs/pmd.xml"/>
</exec>
</target>
<target name="phpcpd" description="find duplicate code using phpcpd">
<exec executable="phpcpd">
<arg value="--log-pmd"/>
<arg value="${project.basedir}/build/logs/pmd-cpd.xml"/>
<arg path="${project.basedir}/"/>
</exec>
</target>
<target name="phpdox" description="generate api documentation using phpdox">
<exec executable="phpdox"/>
</target>
<target name="phpunit" description="run unit tests with phpunit">
<exec executable="phpunit" />
</target>
<target name="test" description="run phpunit tests">
<phpunit haltonerror="true" haltonfailure="true" printsummary="true">
<batchtest>
<fileset dir="${tests.dir}">
<include name="**/*test.php" />
</fileset>
</batchtest>
</phpunit>
</target>
<target name="phpcb" description="aggregate tool output with php_codebrowser">
<exec executable="phpcb">
<arg value="--log"/>
<arg path="${project.basedir}/build/logs"/>
<arg value="--source"/>
<arg path="${project.basedir}/"/>
<arg value="--output"/>
<arg path="${project.basedir}/build/code-browser"/>
</exec>
</target>
<target name="check" description="check variables" >
<fail unless="version" message="version not defined!" />
<fail unless="buildnumber" message="buildnumber not defined!" />
<fail unless="buildid" message="buildid not defined!" />
<delete dir="dist" failonerror="false" />
<mkdir dir="dist" />
</target>
<target name="tar" depends="check" description="create tar file for release">
<echo msg="creating distribution tar for ${phing.project.name} ${version}"/>
<delete file="${distfile}" failonerror="false"/>
<tar destfile="${distfile}" compression="gzip">
<fileset refid="api.tar.gz"/>
</tar>
</target>
</project>
阅读build.xml后,大家可以了解一下内容:
项目名称、版本、打后的包名称:
<project name="api" default="build">
<target name="build" depends="make_runtime,phpcs-ci,phploc,pdepend,phpcb,phpunit,phpdox,phpcpd"/>
<property name="version-m" value="1.1" />
<property name="version" value="1.1.0" />
<property name="stability" value="stable" />
<property name="releasenotes" value="" />
<property name="tarfile" value="${phing.project.name}.${buildnumber}.${buildid}.tar.gz" />
<property name="pkgfile" value="${phing.project.name}.${version}.tgz" />
<property name="distfile" value="dist/${tarfile}" />
<property name="tests.dir" value="test" />
打包时包括的文件和文件夹:这里还可以使用exclude排除文件和文件夹:
<fileset id="api.tar.gz" dir=".">
<include name="test/**"/>
<include name="*.php"/>
<include name="*.xml"/>
</fileset>
测试文件所在地址:
<target name="phpunit" description="run unit tests with phpunit">
<exec executable="phpunit" />
</target>
<target name="test" description="run phpunit tests">
<phpunit haltonerror="true" haltonfailure="true" printsummary="true">
<batchtest>
<fileset dir="${tests.dir}">
<include name="**/*test.php" />
</fileset>
</batchtest>
</phpunit>
</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文件内容:
<?php
class demotest extends phpunit_framework_testcase {
public function testpass() {
$this->asserttrue(true);
}
public function testfail() {
$this->assertfalse(false);
}
}
?>
我们把 testfail()改成下面:
<?php
class demotest extends phpunit_framework_testcase {
public function testpass() {
$this->asserttrue(true);
}
public function testfail() {
$this->asserttrue(false);
}
}
?>
$this->asserttrue(false);
这个是错误的断定:
提交文件后再次构建:
我们可以看到本次构建失败,查看输出结果如下:
当把测试用例修改回正确后,执行构建,发布正确。
<?php
class demotest extends phpunit_framework_testcase {
public function testpass() {
$this->asserttrue(true);
}
public function testfail() {
$this->assertfalse(false);
}
}
?>
ok,到此介绍结束.
总结一下:
jenkins根据项目根目录下的build.xml文件,并根据jenkins中targets的配置,首先自动执行test,当测试通过后,开始执行tar,打包完成后,开始链接远程webserver把程序包上传到远程webserver指定目录下,然后再根据jenkins下的command 执行解压操作,然后就可以根据自己的业务通过shell脚本进行自动处理自动发布的各项操作.
如果在执行test过程中,出现发现测试用例不通过,则就发出错误报告,终止本次构建。
以上就是基于jenkins 实现php项目的自动化测试、自动打包和自动部署的内容。