您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“在Mac OS上如何搭建PHP的Yii框架及相關(guān)測(cè)試環(huán)境”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“在Mac OS上如何搭建PHP的Yii框架及相關(guān)測(cè)試環(huán)境”這篇文章吧。
必要概念
selenium
selenium是個(gè)著名的自動(dòng)化測(cè)試工具,可以調(diào)起本地的瀏覽器來(lái)完成測(cè)試,所以可以用來(lái)自動(dòng)化測(cè)試web項(xiàng)目。selenium分為服務(wù)端和客戶端,服務(wù)端使用java開(kāi)發(fā),所以需要一個(gè)jdk,服務(wù)端在啟動(dòng)時(shí),會(huì)啟動(dòng)一個(gè)http服務(wù),客戶端通過(guò)與服務(wù)端進(jìn)行http通信,向服務(wù)端發(fā)起測(cè)試請(qǐng)求,服務(wù)端會(huì)自動(dòng)調(diào)起瀏覽器完成測(cè)試。測(cè)試人員負(fù)責(zé)編寫(xiě)客戶端腳本,支持大部分主流的編程語(yǔ)言,當(dāng)然實(shí)際上這是由于開(kāi)源社區(qū)強(qiáng)大的威力,為不同的語(yǔ)言開(kāi)發(fā)了針對(duì)selenium的接口程序而已,服務(wù)端和客戶端之間的協(xié)議筆者并沒(méi)有研究,因?yàn)檫@并不重要。
phpunit
phpunit是php語(yǔ)言的測(cè)試框架和工具,在進(jìn)行單元測(cè)試的時(shí)候是使用它的框架,在進(jìn)行功能測(cè)試的時(shí)候是使用它的工具。基于這個(gè)測(cè)試框架,有人在此基礎(chǔ)上做了selenium的php接口程序,作為phpunit的擴(kuò)展存在。
YII框架如何集成
Yii在phpunit的基礎(chǔ)上,為測(cè)試做了一些簡(jiǎn)單的封裝。因此,使用Yii來(lái)進(jìn)行測(cè)試的時(shí)候,需要依賴上述兩者。
環(huán)境安裝
Firefox
selenium-server能夠識(shí)別的瀏覽器并不多,似乎是IE和Firefox,所以在OSX上先安裝好Firefox瀏覽器。安裝瀏覽器跟一般的軟件安裝沒(méi)有大的區(qū)別,這里不累述了。
JDK
由于selenium-server是使用java開(kāi)發(fā)的,我們需要先安裝好JDK,百度搜索JDK下載安裝即可。不再累述。
selenium-server
首先來(lái)安裝selenium的server版本。在osx下,可以使用brew來(lái)安裝,比較方便:
$ brew install selenium-server-standalone
由于selenium-server的源在googleapis上,所以需要翻墻才能進(jìn)行操作,事實(shí)上,如果不翻墻,其他步驟也比較困難。
安裝完成后的提示:
To have launchd start selenium-server-standalone at login: ln -sfv /usr/local/opt/selenium-server-standalone/*.plist ~/Library/LaunchAgents Then to load selenium-server-standalone now: launchctl load ~/Library/LaunchAgents/homebrew.mxcl.selenium-server-standalone.plist Or, if you don't want/need launchctl, you can just run: selenium-server -p 4444
這里明確告訴我們通過(guò)如下命令來(lái)啟動(dòng)服務(wù)端
$ selenium-server -p 4444
正如所見(jiàn),通常selenium-server偵聽(tīng)4444端口,如果希望修改端口,那么相應(yīng)的Yii處需要修改一下配置。
phpunit
彎路
個(gè)人理解,phpunit是一個(gè)工具和框架的集合,工具歸工具,框架歸框架。從官網(wǎng)的文檔看,phpunit的工具部分,是以phar包的形式發(fā)布的,而框架部分是通過(guò)pear管理的。那么先來(lái)記錄一下這兩個(gè)概念。沒(méi)有興趣的可以跳過(guò)這節(jié)。
phar是一種php打包方案。也就是可以把一個(gè)php程序或者php網(wǎng)站打包在一起分發(fā),甚至被作為一個(gè)功能模塊調(diào)用。因此,phpunit完全可以將工具程序打包成phar,執(zhí)行phar的時(shí)候,通常需要使用php命令。
$ wget https://phar.phpunit.de/phpunit.phar $ chmod +x phpunit.phar $ sudo mv phpunit.phar /usr/local/bin/phpunit $ phpunit --version PHPUnit x.y.z by Sebastian Bergmann and contributors.
用上面的命令可以下載phpunit的可執(zhí)行文件,可以看到這是個(gè)phar包
pear是php擴(kuò)展庫(kù)的體系,因?yàn)樵缙趐hp復(fù)用比較困難。編譯型語(yǔ)言由于語(yǔ)法比較緊湊和嚴(yán)謹(jǐn),比較容易復(fù)用。而php由于靈活多變,復(fù)用起來(lái)學(xué)習(xí)成本比較高,于是pear就提出了一個(gè)編程規(guī)范和分發(fā)體系來(lái)實(shí)現(xiàn)php的功能復(fù)用,現(xiàn)在似乎pear已經(jīng)被composer替代了(下面會(huì)說(shuō))。不過(guò)古老的東西既然已經(jīng)走過(guò)彎路了不妨記下來(lái)。
在mac下可以這么安裝pear:
$ wget http://pear.php.net/go-pear.phar $ sudo php -d detect_unicode=0 go-pear.phar
可以看到,go-pear也是個(gè)phar,只不過(guò)它是一個(gè)安裝pear的php腳本,使用php命令可以執(zhí)行。安裝過(guò)程中會(huì)提示是否要修改php.ini文件:
WARNING! The include_path defined in the currently used php.ini does not contain the PEAR PHP directory you just specified: </usr/share/pear> If the specified directory is also not in the include_path used by your scripts, you will have problems getting any PEAR packages working. Would you like to alter php.ini </etc/php.ini>? [Y/n] : Y php.ini </etc/php.ini> include_path updated. Current include path : .: Configured directory : /usr/share/pear Currently used php.ini (guess) : /etc/php.ini Press Enter to continue: The 'pear' command is now at your service at /usr/bin/pear ** The 'pear' command is not currently in your PATH, so you need to ** use '/usr/bin/pear' until you have added ** '/usr/bin' to your PATH environment variable.
從這段提示我們可以得知:
pear的可執(zhí)行程序安裝在/usr/bin/pear
pear有個(gè)工作目錄是/usr/share/pear,這個(gè)工作目錄需要添加到php.ini中,如果讓安裝程序自動(dòng)添加的話,將是這樣的:
;***** Added by go-pear include_path=".:/usr/share/pear" ;*****
當(dāng)我們?cè)趐hp使用require等包含其他文件的函數(shù)時(shí),php其實(shí)除了搜索當(dāng)前目錄,還會(huì)搜索include_path。這樣配置就表明,通過(guò)pear安裝的程序代碼將存放在工作目錄,而且php能夠找到,默認(rèn)在工作目錄下會(huì)有一個(gè)System.php,所以以下代碼是可以工作的:
<?php require 'System.php'; ?>
使用composer安裝
本來(lái),phpunit可以通過(guò)pear來(lái)安裝的,然而,時(shí)過(guò)境遷,在composer大行其道的時(shí)代,phpunit也宣布全面支持composer,并且放棄pear,原本通過(guò)pear的安裝方式果然都不行了。最后逼不得已,只能上composer(話說(shuō)包管理工具真是多的十個(gè)手指不夠用了,將來(lái)有機(jī)會(huì)來(lái)個(gè)橫向比較)。
首先安裝composer,在翻墻狀態(tài)下:
$ brew update $ brew tap josegonzalez/homebrew-php $ brew tap homebrew/versions $ brew install php55-intl $ brew install josegonzalez/php/composer
這樣composer就裝好了。
在項(xiàng)目的根目錄下,創(chuàng)建一個(gè)composer.json,寫(xiě)入:
{ "require-dev": { "phpunit/phpunit": "4.7.*", "phpunit/php-invoker": "*", "phpunit/dbunit": ">=1.2", "phpunit/phpunit-selenium": ">=1.2", "phpunit/phpunit-story": "*" } }
上面的phpunit-selenium就是基于phpunit寫(xiě)的selenium客戶端庫(kù),詳見(jiàn)文后的參考資料。
然后在項(xiàng)目根目錄下,執(zhí)行
$ sudo composer install
composer會(huì)根據(jù)這個(gè)composer.json文件在根目錄創(chuàng)建一個(gè)vendor目錄,并將依賴的東西全部下載到這個(gè)目錄中,其中vendor/bin下面有phpunit的可執(zhí)行文件。
由于是Yii的項(xiàng)目,所以cd到/protected/tests目錄下,執(zhí)行如下命令即可啟動(dòng)默認(rèn)的SiteTest.php里面的測(cè)試方法: (注意在執(zhí)行前,保持selenium-server開(kāi)啟狀態(tài))
$ ../../vendor/bin/phpunit functional/SiteTest.php
會(huì)看到firefox會(huì)在執(zhí)行過(guò)程中自動(dòng)啟動(dòng),并由如下日志輸出:
PHPUnit 4.7.7 by Sebastian Bergmann and contributors. Warning: Deprecated configuration setting "selenium" used . Time: 11.52 seconds, Memory: 6.50Mb OK (1 test, 1 assertion)
phpunit工具程序會(huì)自動(dòng)找到tests/phpunit.xml這個(gè)配置文件并根據(jù)此來(lái)進(jìn)行某些配置,而Yii會(huì)利用phpunit和phpunit-selenium的框架來(lái)與selenium-server端通信,server端會(huì)啟動(dòng)瀏覽器,并將日志和結(jié)果等返回給客戶端。整個(gè)過(guò)程大致就是這樣的。
測(cè)試
測(cè)試是軟件開(kāi)發(fā)中必不可少的環(huán)節(jié).無(wú)論我們是否意識(shí)到,在開(kāi)發(fā)Web應(yīng)用的時(shí)候,我們始終都是在測(cè)試的.例如, 當(dāng)我們用PHP寫(xiě)了一個(gè)類時(shí), 我們可能會(huì)用到一些注入 echo 或者 die 語(yǔ)句來(lái)顯示我們是否正確地實(shí)現(xiàn)了某個(gè)方法;當(dāng)我們實(shí)現(xiàn)了包含一套復(fù)雜的HTML表單的web頁(yè)面時(shí), 我們可能會(huì)試著輸入一些測(cè)試數(shù)據(jù)來(lái)確認(rèn)頁(yè)面是否是按照我們的預(yù)期來(lái)交互的.更高級(jí)的開(kāi)發(fā)者則會(huì)寫(xiě)一些代碼來(lái)自動(dòng)完成這個(gè)測(cè)試過(guò)程, 這樣一來(lái)每當(dāng)我們需要測(cè)試一些東西的時(shí)候, 我們只需要調(diào)用代碼, 剩下來(lái)的就交給計(jì)算機(jī)了. 這就是所謂的 自動(dòng)測(cè)試, 也是本章的主要話題.
Yii 提供的測(cè)試支持包括 單元測(cè)試 和 功能測(cè)試.
單元測(cè)試檢驗(yàn)了代碼的一個(gè)獨(dú)立單元是否按照預(yù)期工作. 在面向?qū)ο缶幊讨? 最基本的代碼單元就是類. 因此, 單元測(cè)試的主要職責(zé)就是校驗(yàn)這個(gè)類所實(shí)現(xiàn)的每個(gè)方法工作都是正常的. 單元測(cè)試通常是由開(kāi)發(fā)了這個(gè)類的人來(lái)編寫(xiě).
功能測(cè)試檢驗(yàn)了特性是否按照預(yù)期工作(如:在一個(gè)博客系統(tǒng)里的提交操作).與單元測(cè)試相比, 功能測(cè)試通常要高級(jí)一些, 因?yàn)榇郎y(cè)試的特性常常牽涉到多個(gè)類. 功能測(cè)試通常是由非常了解系統(tǒng)需求的人編寫(xiě).(這個(gè)人既可以是開(kāi)發(fā)者也可以是質(zhì)量工程師).
測(cè)試驅(qū)動(dòng)開(kāi)發(fā)
以下展示的便是所謂的 測(cè)試驅(qū)動(dòng)開(kāi)發(fā) (TDD) 的開(kāi)發(fā)周期:
創(chuàng)建一個(gè)涵蓋要實(shí)現(xiàn)的特性的新的測(cè)試. 測(cè)試預(yù)計(jì)將在第一次執(zhí)行的時(shí)候失敗, 因?yàn)樘匦陨形磳?shí)現(xiàn).
執(zhí)行所有測(cè)試,確保這個(gè)新的測(cè)試是失敗的.
編寫(xiě)代碼來(lái)使得測(cè)試通過(guò).
執(zhí)行所有測(cè)試,確保所有測(cè)試通過(guò).
重構(gòu)新編寫(xiě)的代碼并確保這些測(cè)試仍然能夠通過(guò).
重復(fù)步驟1至5推進(jìn)整體功能的實(shí)現(xiàn).
構(gòu)建測(cè)試環(huán)境
Yii 提供的測(cè)試支持需要 PHPUnit 3.5+ 和 Selenium Remote Control 1.0+.請(qǐng)參照他們提供的文檔來(lái)安裝 PHPUnit 和 Selenium Remote Control.
當(dāng)我們使用 yiic webapp 控制臺(tái)命令來(lái)創(chuàng)建一個(gè)新的 Yii 應(yīng)用時(shí), 它將會(huì)生成以下文件和目錄供我們來(lái)編寫(xiě)和完成測(cè)試.
testdrive/
protected/ 包含了受保護(hù)的應(yīng)用文件
tests/ 包含了應(yīng)用測(cè)試
fixtures/ 包含了數(shù)據(jù) fixtures
functional/ 包含了功能測(cè)試
unit/ 包含了單元測(cè)試
report/ 包含了 coverage 報(bào)告
bootstrap.php 這個(gè)腳本在一開(kāi)始執(zhí)行
phpunit.xml PHPUnit 配置文件
WebTestCase.php 基于 Web 的功能測(cè)試基類
如上所示的, 我們的測(cè)試代碼主要放在 fixtures, functional 和 unit 這三個(gè)目錄下, report 目錄則用于存儲(chǔ)生成的代碼 coverage 報(bào)告.
我們可以在控制臺(tái)窗口執(zhí)行以下命令來(lái)執(zhí)行測(cè)試(無(wú)論是單元測(cè)試還是功能測(cè)試):
% cd testdrive/protected/tests % phpunit functional/PostTest.php // 執(zhí)行單個(gè)測(cè)試 % phpunit --verbose functional // 執(zhí)行 'functional' 下的所有測(cè)試 % phpunit --coverage-html ./report unit
上面的最后一條命令將執(zhí)行 unit 目錄下的所有測(cè)試然后在 report 目錄下生成出一份 code-coverage 報(bào)告. 注意要生成 code-coverage 報(bào)告必須安裝并開(kāi)啟PHP的 xdebug 擴(kuò)展 .
測(cè)試的引導(dǎo)腳本
讓我們來(lái)看看 bootstrap.php 文件里會(huì)有些什么. 首先這個(gè)文件有點(diǎn)特殊,因?yàn)樗雌饋?lái)很像是 入口腳本, 而它也正是我們執(zhí)行一系列測(cè)試的入口.
$yiit='path/to/yii/framework/yiit.php'; $config=dirname(__FILE__).'/../config/test.php'; require_once($yiit); require_once(dirname(__FILE__).'/WebTestCase.php'); Yii::createWebApplication($config);
如上所示, 首先我們包含了來(lái)自 Yii 框架的 yiit.php 文件, 它初始化了一些全局常量以及必要的測(cè)試基類.然后我們使用 test.php 這個(gè)配置文件來(lái)創(chuàng)建一個(gè)應(yīng)用實(shí)例.如果你查看 test.php 文件, 你會(huì)發(fā)現(xiàn)它是繼承自 main.php 這個(gè)配置文件的, 只不過(guò)它多加了一個(gè)類名為 [CDbFixtureManager] 的 fixture 應(yīng)用組件.
return CMap::mergeArray( require(dirname(__FILE__).'/main.php'), array( 'components'=>array( 'fixture'=>array( 'class'=>'system.test.CDbFixtureManager', ), /* 去除以下注釋可為測(cè)試提供一個(gè)數(shù)據(jù)庫(kù)連接. 'db'=>array( 'connectionString'=>'DSN for test database', ), */ ), ) );
當(dāng)我執(zhí)行那些涉及到數(shù)據(jù)庫(kù)操作的測(cè)試時(shí), 我們應(yīng)該提供一個(gè)測(cè)試專用的數(shù)據(jù)庫(kù)以便測(cè)試執(zhí)行不會(huì)干擾到正常的開(kāi)發(fā)或者生產(chǎn)活動(dòng). 這樣一來(lái), 我們紙需要去除上面 db 配置的注釋, 然后填寫(xiě) connectionString 屬性的用以連接到數(shù)據(jù)庫(kù)的DSN(數(shù)據(jù)源名稱)即可.
通過(guò)這樣一個(gè)啟動(dòng)腳本, 當(dāng)我們執(zhí)行單元測(cè)試時(shí), 我們便可以獲得一個(gè)與服務(wù)需求類似的應(yīng)用實(shí)例, 而主要的不同就是測(cè)試擁有一個(gè) fixture 管理器以及它專屬的測(cè)試數(shù)據(jù)庫(kù).
定義特定狀態(tài)(Fixtures)
自動(dòng)測(cè)試需要被執(zhí)行很多次.為了確保測(cè)試過(guò)程是可以重復(fù)的, 我們很想要在一些可知的狀態(tài)下進(jìn)行測(cè)試, 這個(gè)狀態(tài)我們稱之為 特定狀態(tài). 舉個(gè)例子,在一個(gè)博客應(yīng)用中測(cè)試文章創(chuàng)建特性, 每次當(dāng)我們進(jìn)行測(cè)試時(shí), 與文章相關(guān)的表(例如. Post 表 , Comment 表)應(yīng)該被恢復(fù)到一個(gè)特定的狀態(tài)下. PHPUnit 文檔 已經(jīng)很好的描述了一般的特定狀態(tài)的構(gòu)建. 而本節(jié)主要介紹怎樣像剛才描述的例子那樣構(gòu)建數(shù)據(jù)庫(kù)特定狀態(tài).
設(shè)置構(gòu)建數(shù)據(jù)庫(kù)的特定狀態(tài),這恐怕是測(cè)試以數(shù)據(jù)庫(kù)為后端支持的應(yīng)用最耗時(shí)的部分之一.Yii 引進(jìn)的 [CBbFixtureManager] 應(yīng)用組件可以有效的減輕這一問(wèn)題.當(dāng)進(jìn)行一組測(cè)試的時(shí)候,它基本上會(huì)做以下這些事情:
在所有測(cè)試運(yùn)行之前,它重置測(cè)試相關(guān)數(shù)據(jù)為可知的狀態(tài).
在單個(gè)測(cè)試運(yùn)行之前, 它將特定的表重置為可知狀態(tài).
在一個(gè)測(cè)試方法執(zhí)行過(guò)程中, 它提供了供給特定狀態(tài)的行數(shù)據(jù)的訪問(wèn)接口.
請(qǐng)按如下使用我們?cè)?應(yīng)用配置 中配置的 [CDbFixtureManager].
return array( 'components'=>array( 'fixture'=>array( 'class'=>'system.test.CDbFixtureManager', ), ), );
然后我們?cè)谀夸?protected/tests/fixtures下提供一個(gè)特定狀態(tài)數(shù)據(jù). 這個(gè)目錄可以通過(guò)配置應(yīng)用配置文件中的 [CDbFixtureManager::basePath] 屬性指定為其他目錄.特定狀態(tài)數(shù)據(jù)是由多個(gè)稱之為特定狀態(tài)文件的PHP文件組合而成.每個(gè)特定狀態(tài)文件返回一個(gè)數(shù)組, 代表數(shù)據(jù)的一個(gè)特定表的初始行.文件名和表名相同.以下則是將 Post 表的特定狀態(tài)數(shù)據(jù)存儲(chǔ)于名為 Post.php 文件里的例子.
<?php return array( 'sample1'=>array( 'title'=>'test post 1', 'content'=>'test post content 1', 'createTime'=>1230952187, 'authorId'=>1, ), 'sample2'=>array( 'title'=>'test post 2', 'content'=>'test post content 2', 'createTime'=>1230952287, 'authorId'=>1, ), );
正如我們所見(jiàn), 上面返回了兩行數(shù)據(jù). 每一行都表示一個(gè)數(shù)組,其鍵是表的字段名,其值則是對(duì)應(yīng)的字段值.每行的索引都是稱之為行別名的字符串(例如: simple1, simple2). 稍后當(dāng)我們編寫(xiě)測(cè)試腳本的時(shí)候, 我們可以方便地通過(guò)它的別名調(diào)用這行數(shù)據(jù).你也許注意到了我們并未在上述特定狀態(tài)中指定 id 字段的值. 這是因?yàn)?id 字段已經(jīng)被定義為自增主鍵了,它的值也會(huì)在我們插入新數(shù)據(jù)的時(shí)候自動(dòng)生成.
當(dāng) [CDbFixtureManager] 第一次被引用時(shí), 它會(huì)仔細(xì)檢查所有的特定狀態(tài)文件然后使用他們重置對(duì)應(yīng)的表.它通過(guò)清空表,重置表主鍵的自增序列值,然后插入來(lái)自特定狀態(tài)文件的數(shù)據(jù)行到表中來(lái)重置表.
有時(shí)候,我們可能不想在一套測(cè)試前重置特定狀態(tài)文件里描述的每一個(gè)表, 因?yàn)橹刂锰嗟奶囟顟B(tài)文件可能需要很多時(shí)間.這種情況下,我們可以寫(xiě)一個(gè)PHP腳本來(lái)定制這個(gè)初始化過(guò)程.這個(gè)腳本應(yīng)該被保存在存放特定狀態(tài)文件的目錄下,并命名為 init.php.當(dāng) [CDbFixtureManager] 檢測(cè)到了這個(gè)腳本的存在, 它將執(zhí)行這個(gè)腳本而不是重置每一個(gè)表.
不喜歡使用默認(rèn)方式來(lái)重置表也是可以的,例如: 清空表然后插入特定狀態(tài)數(shù)據(jù). 如果是這種情況, 我們可以為指定的特定狀態(tài)文件編寫(xiě)一個(gè)初始化腳本.這個(gè)腳本必須名稱為表名+.init.php. 例如: Post 表的初始化腳本文件就是 Post.init.php. 當(dāng) [CDbFixtureManager] 發(fā)現(xiàn)了這個(gè)腳本,它將執(zhí)行這個(gè)腳本而不是采用默認(rèn)的方式去重置該表.
Tip: 太多的特定狀態(tài)文件大大延長(zhǎng)了測(cè)試時(shí)間.因此, 你應(yīng)該只為那些在測(cè)試中數(shù)據(jù)會(huì)發(fā)生變化的表提供特定狀態(tài)文件. 那些做為查找服務(wù)的表不會(huì)改變,因此不需要特定狀態(tài)文件.
以上是“在Mac OS上如何搭建PHP的Yii框架及相關(guān)測(cè)試環(huán)境”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。