国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > PHP > 正文

在Mac OS上搭建PHP的Yii框架及相關測試環(huán)境

2020-03-22 20:05:59
字體:
來源:轉載
供稿:網友
YII集成了單元測試和功能測試,借助phpunit和selenium實現(xiàn)。筆者在配置過程中遇到了不少麻煩,紀錄在此。必要概念
selenium
selenium是個著名的自動化測試工具,可以調起本地的瀏覽器來完成測試,所以可以用來自動化測試web項目。selenium分為服務端和客戶端,服務端使用java開發(fā),所以需要一個jdk,服務端在啟動時,會啟動一個http服務,客戶端通過與服務端進行http通信,向服務端發(fā)起測試請求,服務端會自動調起瀏覽器完成測試。測試人員負責編寫客戶端腳本,支持大部分主流的編程語言,當然實際上這是由于開源社區(qū)強大的威力,為不同的語言開發(fā)了針對selenium的接口程序而已,服務端和客戶端之間的協(xié)議筆者并沒有研究,因為這并不重要。phpunit
phpunit是php語言的測試框架和工具,在進行單元測試的時候是使用它的框架,在進行功能測試的時候是使用它的工具。基于這個測試框架,有人在此基礎上做了selenium的php接口程序,作為phpunit的擴展存在。YII框架如何集成
Yii在phpunit的基礎上,為測試做了一些簡單的封裝。因此,使用Yii來進行測試的時候,需要依賴上述兩者。環(huán)境安裝
Firefox
selenium-server能夠識別的瀏覽器并不多,似乎是IE和Firefox,所以在OSX上先安裝好Firefox瀏覽器。安裝瀏覽器跟一般的軟件安裝沒有大的區(qū)別,這里不累述了。JDK
由于selenium-server是使用java開發(fā)的,我們需要先安裝好JDK,百度搜索JDK下載安裝即可。不再累述。selenium-server
首先來安裝selenium的server版本。在osx下,可以使用brew來安裝,比較方便:$ brew install selenium-server-standalone由于selenium-server的源在googleapis上,所以需要翻墻才能進行操作,事實上,如果不翻墻,其他步驟也比較困難。安裝完成后的提示:To have launchd start selenium-server-standalone at login: ln -sfv /usr/local/opt/selenium-server-standalone/*.plist ~/Library/LaunchAgentsThen to load selenium-server-standalone now: launchctl load ~/Library/LaunchAgents/homebrew.mxcl.selenium-server-standalone.plistOr, if you don't want/need launchctl, you can just run: selenium-server -p 4444這里明確告訴我們通過如下命令來啟動服務端$ selenium-server -p 4444正如所見,通常selenium-server偵聽4444端口,如果希望修改端口,那么相應的Yii處需要修改一下配置。phpunit
彎路
個人理解,phpunit是一個工具和框架的集合,工具歸工具,框架歸框架。從網址的文檔看,phpunit的工具部分,是以phar包的形式發(fā)布的,而框架部分是通過pear管理的。那么先來記錄一下這兩個概念。沒有興趣的可以跳過這節(jié)。phar是一種php打包方案。也就是可以把一個php程序或者php網站打包在一起分發(fā),甚至被作為一個功能模塊調用。因此,phpunit完全可以將工具程序打包成phar,執(zhí)行phar的時候,通常需要使用php命令。$ wget https://phar.phpunit.de/phpunit.phar$ chmod +x phpunit.phar$ sudo mv phpunit.phar /usr/local/bin/phpunit$ phpunit --versionPHPUnit x.y.z by Sebastian Bergmann and contributors.用上面的命令可以下載phpunit的可執(zhí)行文件,可以看到這是個phar包pear是php擴展庫的體系,因為早期php復用比較困難。編譯型語言由于語法比較緊湊和嚴謹,比較容易復用。而php由于靈活多變,復用起來學習成本比較高,于是pear就提出了一個編程規(guī)范和分發(fā)體系來實現(xiàn)php的功能復用,現(xiàn)在似乎pear已經被composer替代了(下面會說)。不過古老的東西既然已經走過彎路了不妨記下來。在mac下可以這么安裝pear:$ wget http://pear.php.net/go-pear.phar$ sudo php -d detect_unicode=0 go-pear.phar可以看到,go-pear也是個phar,只不過它是一個安裝pear的php腳本,使用php命令可以執(zhí)行。安裝過程中會提示是否要修改php.ini文件:WARNING! The include_path defined in the html' target='_blank'>currently used php.ini does notcontain the PEAR PHP directory you just specified: /usr/share/pear If the specified directory is also not in the include_path used byyour scripts, you will have problems getting any PEAR packages working.
** 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有個工作目錄是/usr/share/pear,這個工作目錄需要添加到php.ini中,如果讓安裝程序自動添加的話,將是這樣的:
;***** Added by go-pearinclude_path=".:/usr/share/pear";*****當我們在php使用require等包含其他文件的函數(shù)時,php其實除了搜索當前目錄,還會搜索include_path。這樣配置就表明,通過pear安裝的程序代碼將存放在工作目錄,而且php能夠找到,默認在工作目錄下會有一個System.php,所以以下代碼是可以工作的: php require 'System.php';
使用composer安裝
本來,phpunit可以通過pear來安裝的,然而,時過境遷,在composer大行其道的時代,phpunit也宣布全面支持composer,并且放棄pear,原本通過pear的安裝方式果然都不行了。最后逼不得已,只能上composer(話說包管理工具真是多的十個手指不夠用了,將來有機會來個橫向比較)。首先安裝composer,在翻墻狀態(tài)下:$ brew update$ brew tap josegonzalez/homebrew-php$ brew tap homebrew/versions$ brew install php55-intl$ brew install josegonzalez/php/composer這樣composer就裝好了。在項目的根目錄下,創(chuàng)建一個composer.json,寫入: "require-dev": { "phpunit/phpunit": "4.7.*", "phpunit/php-invoker": "*", "phpunit/dbunit": " =1.2", "phpunit/phpunit-selenium": " =1.2", "phpunit/phpunit-story": "*"上面的phpunit-selenium就是基于phpunit寫的selenium客戶端庫,詳見文后的參考資料。然后在項目根目錄下,執(zhí)行$ sudo composer installcomposer會根據(jù)這個composer.json文件在根目錄創(chuàng)建一個vendor目錄,并將依賴的東西全部下載到這個目錄中,其中vendor/bin下面有phpunit的可執(zhí)行文件。由于是Yii的項目,所以cd到/protected/tests目錄下,執(zhí)行如下命令即可啟動默認的SiteTest.php里面的測試方法: (注意在執(zhí)行前,保持selenium-server開啟狀態(tài))$ ../../vendor/bin/phpunit functional/SiteTest.php會看到firefox會在執(zhí)行過程中自動啟動,并由如下日志輸出:PHPUnit 4.7.7 by Sebastian Bergmann and contributors.Warning: Deprecated configuration setting "selenium" usedTime: 11.52 seconds, Memory: 6.50MbOK (1 test, 1 assertion)phpunit工具程序會自動找到tests/phpunit.xml這個配置文件并根據(jù)此來進行某些配置,而Yii會利用phpunit和phpunit-selenium的框架來與selenium-server端通信,server端會啟動瀏覽器,并將日志和結果等返回給客戶端。整個過程大致就是這樣的。測試測試是軟件開發(fā)中必不可少的環(huán)節(jié).無論我們是否意識到,在開發(fā)Web應用的時候,我們始終都是在測試的.例如, 當我們用PHP寫了一個類時, 我們可能會用到一些注入 echo 或者 die 語句來顯示我們是否正確地實現(xiàn)了某個方法;當我們實現(xiàn)了包含一套復雜的HTML表單的web頁面時, 我們可能會試著輸入一些測試數(shù)據(jù)來確認頁面是否是按照我們的預期來交互的.更高級的開發(fā)者則會寫一些代碼來自動完成這個測試過程, 這樣一來每當我們需要測試一些東西的時候, 我們只需要調用代碼, 剩下來的就交給計算機了. 這就是所謂的 自動測試, 也是本章的主要話題.Yii 提供的測試支持包括 單元測試 和 功能測試.單元測試檢驗了代碼的一個獨立單元是否按照預期工作. 在面向對象編程中, 最基本的代碼單元就是類. 因此, 單元測試的主要職責就是校驗這個類所實現(xiàn)的每個方法工作都是正常的. 單元測試通常是由開發(fā)了這個類的人來編寫.功能測試檢驗了特性是否按照預期工作(如:在一個博客系統(tǒng)里的提交操作).與單元測試相比, 功能測試通常要高級一些, 因為待測試的特性常常牽涉到多個類. 功能測試通常是由非常了解系統(tǒng)需求的人編寫.(這個人既可以是開發(fā)者也可以是質量工程師).測試驅動開發(fā)以下展示的便是所謂的 測試驅動開發(fā) (TDD) 的開發(fā)周期: 創(chuàng)建一個涵蓋要實現(xiàn)的特性的新的測試. 測試預計將在第一次執(zhí)行的時候失敗, 因為特性尚未實現(xiàn). 執(zhí)行所有測試,確保這個新的測試是失敗的. 編寫代碼來使得測試通過. 執(zhí)行所有測試,確保所有測試通過. 重構新編寫的代碼并確保這些測試仍然能夠通過. 重復步驟1至5推進整體功能的實現(xiàn).構建測試環(huán)境Yii 提供的測試支持需要 PHPUnit 3.5+ 和 Selenium Remote Control 1.0+.請參照他們提供的文檔來安裝 PHPUnit 和 Selenium Remote Control.當我們使用 yiic webapp 控制臺命令來創(chuàng)建一個新的 Yii 應用時, 它將會生成以下文件和目錄供我們來編寫和完成測試.testdrive/
protected/ 包含了受保護的應用文件
tests/ 包含了應用測試
fixtures/ 包含了數(shù)據(jù) fixtures
functional/ 包含了功能測試
unit/ 包含了單元測試
report/ 包含了 coverage 報告
bootstrap.php 這個腳本在一開始執(zhí)行
phpunit.xml PHPUnit 配置文件
WebTestCase.php 基于 Web 的功能測試基類
如上所示的, 我們的測試代碼主要放在 fixtures, functional 和 unit 這三個目錄下, report 目錄則用于存儲生成的代碼 coverage 報告.我們可以在控制臺窗口執(zhí)行以下命令來執(zhí)行測試(無論是單元測試還是功能測試):% cd testdrive/protected/tests% phpunit functional/PostTest.php // 執(zhí)行單個測試% phpunit --verbose functional // 執(zhí)行 'functional' 下的所有測試% phpunit --coverage-html ./report unit上面的最后一條命令將執(zhí)行 unit 目錄下的所有測試然后在 report 目錄下生成出一份 code-coverage 報告. 注意要生成 code-coverage 報告必須安裝并開啟PHP的 xdebug 擴展 .測試的引導腳本讓我們來看看 bootstrap.php 文件里會有些什么. 首先這個文件有點特殊,因為它看起來很像是 入口腳本, 而它也正是我們執(zhí)行一系列測試的入口.$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);如上所示, 首先我們包含了來自 Yii 框架的 yiit.php 文件, 它初始化了一些全局常量以及必要的測試基類.然后我們使用 test.php 這個配置文件來創(chuàng)建一個應用實例.如果你查看 test.php 文件, 你會發(fā)現(xiàn)它是繼承自 main.php 這個配置文件的, 只不過它多加了一個類名為 [CDbFixtureManager] 的 fixture 應用組件.return CMap::mergeArray( require(dirname(__FILE__).'/main.php'), array( 'components'= array( 'fixture'= array( 'class'= 'system.test.CDbFixtureManager', /* 去除以下注釋可為測試提供一個數(shù)據(jù)庫連接. 'db'= array( 'connectionString'= 'DSN for test database',當我執(zhí)行那些涉及到數(shù)據(jù)庫操作的測試時, 我們應該提供一個測試專用的數(shù)據(jù)庫以便測試執(zhí)行不會干擾到正常的開發(fā)或者生產活動. 這樣一來, 我們紙需要去除上面 db 配置的注釋, 然后填寫 connectionString 屬性的用以連接到數(shù)據(jù)庫的DSN(數(shù)據(jù)源名稱)即可.通過這樣一個啟動腳本, 當我們執(zhí)行單元測試時, 我們便可以獲得一個與服務需求類似的應用實例, 而主要的不同就是測試擁有一個 fixture 管理器以及它專屬的測試數(shù)據(jù)庫.定義特定狀態(tài)(Fixtures)自動測試需要被執(zhí)行很多次.為了確保測試過程是可以重復的, 我們很想要在一些可知的狀態(tài)下進行測試, 這個狀態(tài)我們稱之為 特定狀態(tài). 舉個例子,在一個博客應用中測試文章創(chuàng)建特性, 每次當我們進行測試時, 與文章相關的表(例如. Post 表 , Comment 表)應該被恢復到一個特定的狀態(tài)下. PHPUnit 文檔 已經很好的描述了一般的特定狀態(tài)的構建. 而本節(jié)主要介紹怎樣像剛才描述的例子那樣構建數(shù)據(jù)庫特定狀態(tài).設置構建數(shù)據(jù)庫的特定狀態(tài),這恐怕是測試以數(shù)據(jù)庫為后端支持的應用最耗時的部分之一.Yii 引進的 [CBbFixtureManager] 應用組件可以有效的減輕這一問題.當進行一組測試的時候,它基本上會做以下這些事情:在所有測試運行之前,它重置測試相關數(shù)據(jù)為可知的狀態(tài).
在單個測試運行之前, 它將特定的表重置為可知狀態(tài).
在一個測試方法執(zhí)行過程中, 它提供了供給特定狀態(tài)的行數(shù)據(jù)的訪問接口.
請按如下使用我們在 應用配置 中配置的 [CDbFixtureManager].return array( 'components'= array( 'fixture'= array( 'class'= 'system.test.CDbFixtureManager',然后我們在目錄 protected/tests/fixtures下提供一個特定狀態(tài)數(shù)據(jù). 這個目錄可以通過配置應用配置文件中的 [CDbFixtureManager::basePath] 屬性指定為其他目錄.特定狀態(tài)數(shù)據(jù)是由多個稱之為特定狀態(tài)文件的PHP文件組合而成.每個特定狀態(tài)文件返回一個數(shù)組, 代表數(shù)據(jù)的一個特定表的初始行.文件名和表名相同.以下則是將 Post 表的特定狀態(tài)數(shù)據(jù)存儲于名為 Post.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,正如我們所見, 上面返回了兩行數(shù)據(jù). 每一行都表示一個數(shù)組,其鍵是表的字段名,其值則是對應的字段值.每行的索引都是稱之為行別名的字符串(例如: simple1, simple2). 稍后當我們編寫測試腳本的時候, 我們可以方便地通過它的別名調用這行數(shù)據(jù).你也許注意到了我們并未在上述特定狀態(tài)中指定 id 字段的值. 這是因為 id 字段已經被定義為自增主鍵了,它的值也會在我們插入新數(shù)據(jù)的時候自動生成.當 [CDbFixtureManager] 第一次被引用時, 它會仔細檢查所有的特定狀態(tài)文件然后使用他們重置對應的表.它通過清空表,重置表主鍵的自增序列值,然后插入來自特定狀態(tài)文件的數(shù)據(jù)行到表中來重置表.有時候,我們可能不想在一套測試前重置特定狀態(tài)文件里描述的每一個表, 因為重置太多的特定狀態(tài)文件可能需要很多時間.這種情況下,我們可以寫一個PHP腳本來定制這個初始化過程.這個腳本應該被保存在存放特定狀態(tài)文件的目錄下,并命名為 init.php.當 [CDbFixtureManager] 檢測到了這個腳本的存在, 它將執(zhí)行這個腳本而不是重置每一個表.不喜歡使用默認方式來重置表也是可以的,例如: 清空表然后插入特定狀態(tài)數(shù)據(jù). 如果是這種情況, 我們可以為指定的特定狀態(tài)文件編寫一個初始化腳本.這個腳本必須名稱為表名+.init.php. 例如: Post 表的初始化腳本文件就是 Post.init.php. 當 [CDbFixtureManager] 發(fā)現(xiàn)了這個腳本,它將執(zhí)行這個腳本而不是采用默認的方式去重置該表.Tip: 太多的特定狀態(tài)文件大大延長了測試時間.因此, 你應該只為那些在測試中數(shù)據(jù)會發(fā)生變化的表提供特定狀態(tài)文件. 那些做為查找服務的表不會改變,因此不需要特定狀態(tài)文件.PHP教程

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 交口县| 寻乌县| 镇原县| 西林县| 庆元县| 介休市| 平原县| 江华| 邳州市| 曲靖市| 崇礼县| 永吉县| 永修县| 湖口县| 曲周县| 墨江| 建湖县| 泗洪县| 潮州市| 四会市| 齐齐哈尔市| 虎林市| 宁阳县| 湾仔区| 青神县| 阿拉善左旗| 扶风县| 淮南市| 常熟市| 方正县| 襄樊市| 清新县| 汾阳市| 周至县| 高陵县| 桃园县| 洪湖市| 安西县| 恩施市| 临武县| 广西|