本篇博文宅鳥將在上篇: 基于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 39PHP 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.desudo pear channel-discover pear.symfony-project.comsudo pear channel-discover components.ez.nosudo pear channel-discover pear.symfony.comsudo pear update-channelssudo pear upgrade-allsudo pear install pear.symfony.com/Yamlsudo pear install --alldeps phpunit/PHPUnitsudo pear install --force --alldeps phpunit/PHPUnit
安裝后執行phpunit --version 返回版本信息。表示安裝成功。
root@dop-kvm-2:# phpunit --versionPHPUnit 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.php1 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" html' target='_blank'>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文件內容:
<?phpclass DemoTest extends PHPUnit_Framework_TestCase { public function testPass() { $this->assertTrue(true); } public function testFail() { $this->assertFalse(false); }}?>
我們把 testFail()改成下面:
<?phpclass DemoTest extends PHPUnit_Framework_TestCase { public function testPass() { $this->assertTrue(true); } public function testFail() { $this->assertTrue(false); }}?>
$this
->assertTrue(false);
這個是錯誤的斷定:
提交文件后再次構建:
我們可以看到本次構建失敗,查看輸出結果如下:
當把測試用例修改回正確后,執行構建,發布正確。
<?phpclass 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結合ansible、shell和mysql版本遷移實現多服務器批量發布.敬請關注
干貨吐槽完畢,由于時間倉儲,有不足之處歡迎拍磚.
PHP編程鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。
新聞熱點
疑難解答