亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > PHP > 正文

在Mac OS上搭建PHP的Yii框架及相關測試環境

2024-05-04 23:43:02
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了在Mac OS上搭建PHP的Yii框架及相關測試環境的方法,Mac自帶Apache與PHP等軟件,因而搭建開發環境時非常舒適,需要的朋友可以參考下
 

YII集成了單元測試和功能測試,借助phpunit和selenium實現。筆者在配置過程中遇到了不少麻煩,紀錄在此。

必要概念
selenium

selenium是個著名的自動化測試工具,可以調起本地的瀏覽器來完成測試,所以可以用來自動化測試web項目。selenium分為服務端和客戶端,服務端使用java開發,所以需要一個jdk,服務端在啟動時,會啟動一個http服務,客戶端通過與服務端進行http通信,向服務端發起測試請求,服務端會自動調起瀏覽器完成測試。測試人員負責編寫客戶端腳本,支持大部分主流的編程語言,當然實際上這是由于開源社區強大的威力,為不同的語言開發了針對selenium的接口程序而已,服務端和客戶端之間的協議筆者并沒有研究,因為這并不重要。

phpunit
phpunit是php語言的測試框架和工具,在進行單元測試的時候是使用它的框架,在進行功能測試的時候是使用它的工具?;谶@個測試框架,有人在此基礎上做了selenium的php接口程序,作為phpunit的擴展存在。

YII框架如何集成
Yii在phpunit的基礎上,為測試做了一些簡單的封裝。因此,使用Yii來進行測試的時候,需要依賴上述兩者。

環境安裝
Firefox

selenium-server能夠識別的瀏覽器并不多,似乎是IE和Firefox,所以在OSX上先安裝好Firefox瀏覽器。安裝瀏覽器跟一般的軟件安裝沒有大的區別,這里不累述了。

JDK
由于selenium-server是使用java開發的,我們需要先安裝好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包的形式發布的,而框架部分是通過pear管理的。那么先來記錄一下這兩個概念。沒有興趣的可以跳過這節。

phar是一種php打包方案。也就是可以把一個php程序或者php網站打包在一起分發,甚至被作為一個功能模塊調用。因此,phpunit完全可以將工具程序打包成phar,執行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的可執行文件,可以看到這是個phar包

pear是php擴展庫的體系,因為早期php復用比較困難。編譯型語言由于語法比較緊湊和嚴謹,比較容易復用。而php由于靈活多變,復用起來學習成本比較高,于是pear就提出了一個編程規范和分發體系來實現php的功能復用,現在似乎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命令可以執行。安裝過程中會提示是否要修改php.ini文件:

WARNING! The include_path defined in the 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.Would you like to alter php.ini </etc/php.ini>? [Y/n] : Yphp.ini </etc/php.ini> include_path updated.Current include path      : .:Configured directory      : /usr/share/pearCurrently used php.ini (guess) : /etc/php.iniPress 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的可執行程序安裝在/usr/bin/pear
pear有個工作目錄是/usr/share/pear,這個工作目錄需要添加到php.ini中,如果讓安裝程序自動添加的話,將是這樣的:

;***** Added by go-pearinclude_path=".:/usr/share/pear";*****

當我們在php使用require等包含其他文件的函數時,php其實除了搜索當前目錄,還會搜索include_path。這樣配置就表明,通過pear安裝的程序代碼將存放在工作目錄,而且php能夠找到,默認在工作目錄下會有一個System.php,所以以下代碼是可以工作的:

<?php  require 'System.php';?>


使用composer安裝
本來,phpunit可以通過pear來安裝的,然而,時過境遷,在composer大行其道的時代,phpunit也宣布全面支持composer,并且放棄pear,原本通過pear的安裝方式果然都不行了。最后逼不得已,只能上composer(話說包管理工具真是多的十個手指不夠用了,將來有機會來個橫向比較)。

首先安裝composer,在翻墻狀態下:

$ brew update$ brew tap josegonzalez/homebrew-php$ brew tap homebrew/versions$ brew install php55-intl$ brew install josegonzalez/php/composer

這樣composer就裝好了。

在項目的根目錄下,創建一個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客戶端庫,詳見文后的參考資料。

然后在項目根目錄下,執行

$ sudo composer install

composer會根據這個composer.json文件在根目錄創建一個vendor目錄,并將依賴的東西全部下載到這個目錄中,其中vendor/bin下面有phpunit的可執行文件。

由于是Yii的項目,所以cd到/protected/tests目錄下,執行如下命令即可啟動默認的SiteTest.php里面的測試方法: (注意在執行前,保持selenium-server開啟狀態)

$ ../../vendor/bin/phpunit functional/SiteTest.php

會看到firefox會在執行過程中自動啟動,并由如下日志輸出:

PHPUnit 4.7.7 by Sebastian Bergmann and contributors.Warning: Deprecated configuration setting "selenium" used.Time: 11.52 seconds, Memory: 6.50MbOK (1 test, 1 assertion)

phpunit工具程序會自動找到tests/phpunit.xml這個配置文件并根據此來進行某些配置,而Yii會利用phpunit和phpunit-selenium的框架來與selenium-server端通信,server端會啟動瀏覽器,并將日志和結果等返回給客戶端。整個過程大致就是這樣的。

測試

測試是軟件開發中必不可少的環節.無論我們是否意識到,在開發Web應用的時候,我們始終都是在測試的.例如, 當我們用PHP寫了一個類時, 我們可能會用到一些注入 echo 或者 die 語句來顯示我們是否正確地實現了某個方法;當我們實現了包含一套復雜的HTML表單的web頁面時, 我們可能會試著輸入一些測試數據來確認頁面是否是按照我們的預期來交互的.更高級的開發者則會寫一些代碼來自動完成這個測試過程, 這樣一來每當我們需要測試一些東西的時候, 我們只需要調用代碼, 剩下來的就交給計算機了. 這就是所謂的 自動測試, 也是本章的主要話題.

Yii 提供的測試支持包括 單元測試 和 功能測試.

單元測試檢驗了代碼的一個獨立單元是否按照預期工作. 在面向對象編程中, 最基本的代碼單元就是類. 因此, 單元測試的主要職責就是校驗這個類所實現的每個方法工作都是正常的. 單元測試通常是由開發了這個類的人來編寫.

功能測試檢驗了特性是否按照預期工作(如:在一個博客系統里的提交操作).與單元測試相比, 功能測試通常要高級一些, 因為待測試的特性常常牽涉到多個類. 功能測試通常是由非常了解系統需求的人編寫.(這個人既可以是開發者也可以是質量工程師).

測試驅動開發

以下展示的便是所謂的 測試驅動開發 (TDD) 的開發周期:

  • 創建一個涵蓋要實現的特性的新的測試. 測試預計將在第一次執行的時候失敗, 因為特性尚未實現.
  • 執行所有測試,確保這個新的測試是失敗的.
  • 編寫代碼來使得測試通過.
  • 執行所有測試,確保所有測試通過.
  • 重構新編寫的代碼并確保這些測試仍然能夠通過.
  • 重復步驟1至5推進整體功能的實現.

構建測試環境

Yii 提供的測試支持需要 PHPUnit 3.5+ 和 Selenium Remote Control 1.0+.請參照他們提供的文檔來安裝 PHPUnit 和 Selenium Remote Control.

當我們使用 yiic webapp 控制臺命令來創建一個新的 Yii 應用時, 它將會生成以下文件和目錄供我們來編寫和完成測試.

testdrive/
   protected/                包含了受保護的應用文件
      tests/                 包含了應用測試
         fixtures/           包含了數據 fixtures
         functional/         包含了功能測試
         unit/               包含了單元測試
         report/             包含了 coverage 報告
         bootstrap.php       這個腳本在一開始執行
         phpunit.xml         PHPUnit 配置文件
         WebTestCase.php     基于 Web 的功能測試基類
如上所示的, 我們的測試代碼主要放在 fixtures, functional 和 unit 這三個目錄下, report 目錄則用于存儲生成的代碼 coverage 報告.

我們可以在控制臺窗口執行以下命令來執行測試(無論是單元測試還是功能測試):

% cd testdrive/protected/tests% phpunit functional/PostTest.php  // 執行單個測試% phpunit --verbose functional    // 執行 'functional' 下的所有測試% phpunit --coverage-html ./report unit

上面的最后一條命令將執行 unit 目錄下的所有測試然后在 report 目錄下生成出一份 code-coverage 報告. 注意要生成 code-coverage 報告必須安裝并開啟PHP的 xdebug 擴展 .

測試的引導腳本

讓我們來看看 bootstrap.php 文件里會有些什么. 首先這個文件有點特殊,因為它看起來很像是 入口腳本, 而它也正是我們執行一系列測試的入口.

$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 這個配置文件來創建一個應用實例.如果你查看 test.php 文件, 你會發現它是繼承自 main.php 這個配置文件的, 只不過它多加了一個類名為 [CDbFixtureManager] 的 fixture 應用組件.

return CMap::mergeArray( require(dirname(__FILE__).'/main.php'), array( 'components'=>array(  'fixture'=>array(  'class'=>'system.test.CDbFixtureManager',  ),  /* 去除以下注釋可為測試提供一個數據庫連接.  'db'=>array(  'connectionString'=>'DSN for test database',  ),  */ ), ));
當我執行那些涉及到數據庫操作的測試時, 我們應該提供一個測試專用的數據庫以便測試執行不會干擾到正常的開發或者生產活動. 這樣一來, 我們紙需要去除上面 db 配置的注釋, 然后填寫 connectionString 屬性的用以連接到數據庫的DSN(數據源名稱)即可.

通過這樣一個啟動腳本, 當我們執行單元測試時, 我們便可以獲得一個與服務需求類似的應用實例, 而主要的不同就是測試擁有一個 fixture 管理器以及它專屬的測試數據庫.

定義特定狀態(Fixtures)

自動測試需要被執行很多次.為了確保測試過程是可以重復的, 我們很想要在一些可知的狀態下進行測試, 這個狀態我們稱之為 特定狀態. 舉個例子,在一個博客應用中測試文章創建特性, 每次當我們進行測試時, 與文章相關的表(例如. Post 表 , Comment 表)應該被恢復到一個特定的狀態下. PHPUnit 文檔 已經很好的描述了一般的特定狀態的構建. 而本節主要介紹怎樣像剛才描述的例子那樣構建數據庫特定狀態.

設置構建數據庫的特定狀態,這恐怕是測試以數據庫為后端支持的應用最耗時的部分之一.Yii 引進的 [CBbFixtureManager] 應用組件可以有效的減輕這一問題.當進行一組測試的時候,它基本上會做以下這些事情:

在所有測試運行之前,它重置測試相關數據為可知的狀態.
在單個測試運行之前, 它將特定的表重置為可知狀態.
在一個測試方法執行過程中, 它提供了供給特定狀態的行數據的訪問接口.
請按如下使用我們在 應用配置 中配置的 [CDbFixtureManager].

return array( 'components'=>array( 'fixture'=>array(  'class'=>'system.test.CDbFixtureManager', ), ),);

然后我們在目錄 protected/tests/fixtures下提供一個特定狀態數據. 這個目錄可以通過配置應用配置文件中的 [CDbFixtureManager::basePath] 屬性指定為其他目錄.特定狀態數據是由多個稱之為特定狀態文件的PHP文件組合而成.每個特定狀態文件返回一個數組, 代表數據的一個特定表的初始行.文件名和表名相同.以下則是將 Post 表的特定狀態數據存儲于名為 Post.php 文件里的例子.

<?phpreturn 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, ),);

正如我們所見, 上面返回了兩行數據. 每一行都表示一個數組,其鍵是表的字段名,其值則是對應的字段值.每行的索引都是稱之為行別名的字符串(例如: simple1, simple2). 稍后當我們編寫測試腳本的時候, 我們可以方便地通過它的別名調用這行數據.你也許注意到了我們并未在上述特定狀態中指定 id 字段的值. 這是因為 id 字段已經被定義為自增主鍵了,它的值也會在我們插入新數據的時候自動生成.

當 [CDbFixtureManager] 第一次被引用時, 它會仔細檢查所有的特定狀態文件然后使用他們重置對應的表.它通過清空表,重置表主鍵的自增序列值,然后插入來自特定狀態文件的數據行到表中來重置表.

有時候,我們可能不想在一套測試前重置特定狀態文件里描述的每一個表, 因為重置太多的特定狀態文件可能需要很多時間.這種情況下,我們可以寫一個PHP腳本來定制這個初始化過程.這個腳本應該被保存在存放特定狀態文件的目錄下,并命名為 init.php.當 [CDbFixtureManager] 檢測到了這個腳本的存在, 它將執行這個腳本而不是重置每一個表.

不喜歡使用默認方式來重置表也是可以的,例如: 清空表然后插入特定狀態數據. 如果是這種情況, 我們可以為指定的特定狀態文件編寫一個初始化腳本.這個腳本必須名稱為表名+.init.php. 例如: Post 表的初始化腳本文件就是 Post.init.php. 當 [CDbFixtureManager] 發現了這個腳本,它將執行這個腳本而不是采用默認的方式去重置該表.

Tip: 太多的特定狀態文件大大延長了測試時間.因此, 你應該只為那些在測試中數據會發生變化的表提供特定狀態文件. 那些做為查找服務的表不會改變,因此不需要特定狀態文件.



注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人免费网站在线| xxxxx91麻豆| 欧美富婆性猛交| 91精品国产乱码久久久久久蜜臀| 精品亚洲va在线va天堂资源站| 国产免费一区二区三区在线能观看| 欧美激情精品久久久久久久变态| 亚洲开心激情网| 91国在线精品国内播放| 久热爱精品视频线路一| 国内精品美女av在线播放| 亚洲自拍偷拍网址| 岛国av午夜精品| 日韩av资源在线播放| 一区二区三区四区视频| 久久精品成人欧美大片古装| 在线日韩日本国产亚洲| 精品久久久久久中文字幕大豆网| 久久频这里精品99香蕉| 日韩在线观看免费av| 国产精品久久久av久久久| 911国产网站尤物在线观看| 久久夜色精品亚洲噜噜国产mv| 久久精品亚洲一区| 亚洲精品美女视频| 中文字幕一区二区三区电影| 91精品久久久久久久久久久久久| 久久天天躁狠狠躁夜夜躁2014| 91久久精品一区| xxxxxxxxx欧美| 久久久久久久激情视频| 久久精品精品电影网| 久久九九国产精品怡红院| 成人免费视频在线观看超级碰| 亚洲一级片在线看| 91视频88av| 欧美激情videoshd| 日韩美女免费观看| 国产精品丝袜视频| 久久久伊人欧美| 亚洲自拍另类欧美丝袜| 国产精品夫妻激情| www.日韩不卡电影av| 欧美日韩中国免费专区在线看| 欧洲亚洲女同hd| 日韩高清电影免费观看完整版| 亚洲国语精品自产拍在线观看| 在线不卡国产精品| 九九热r在线视频精品| 久久久在线视频| 国产成人一区二区三区| 国产精品都在这里| 97在线精品视频| 国产成人97精品免费看片| 国产精品激情av在线播放| 亚洲精品日韩激情在线电影| 日韩中文字幕不卡视频| 欧美精品在线播放| 亚洲美腿欧美激情另类| 日韩一区二区福利| 国产丝袜一区视频在线观看| 青青草原成人在线视频| 午夜精品视频网站| 国产91在线视频| 欧美日韩国产页| 中文字幕欧美精品日韩中文字幕| 神马国产精品影院av| 7m精品福利视频导航| xxxxxxxxx欧美| 日韩免费看的电影电视剧大全| 国产美女精彩久久| 亚洲一区二区久久久久久久| 日韩专区中文字幕| 欧美一级免费视频| 夜夜嗨av色一区二区不卡| 久久精品久久久久电影| 欧美精品国产精品日韩精品| 亚洲一区二区三区sesese| 国产精品免费看久久久香蕉| 精品香蕉一区二区三区| 久久精品这里热有精品| 日韩成人在线视频网站| 91色视频在线观看| 欧美在线视频网| 亚洲精品永久免费| 日韩欧美成人区| 国产精品丝袜视频| 亚洲国产精久久久久久| 国产精品吹潮在线观看| 国产精品久在线观看| 国产成人在线一区二区| 亚洲一区制服诱惑| 中文字幕精品在线| 国产精品免费久久久| 国产成人97精品免费看片| 九九久久久久久久久激情| 欧美精品日韩三级| 欧美专区国产专区| 亚洲美女激情视频| 欧美日韩国产一中文字不卡| 欧美激情第99页| xvideos亚洲| 欧美xxxx做受欧美.88| 91在线视频成人| 一本色道久久88精品综合| 中文字幕亚洲情99在线| 国产美女精品视频免费观看| 亚洲free性xxxx护士白浆| 亚洲人午夜精品免费| 国产亚洲美女久久| 国外成人在线直播| 亚洲精品一区av在线播放| 国产午夜精品视频免费不卡69堂| 国产免费一区二区三区香蕉精| 国产成人亚洲精品| 日韩电影中文 亚洲精品乱码| 亚洲国产精品专区久久| 亚洲欧美综合区自拍另类| 欧美色另类天堂2015| 成人免费在线视频网站| 久久精品男人天堂| 视频一区视频二区国产精品| 亚洲bt天天射| 亚洲福利视频在线| 国产免费成人av| 国产精品pans私拍| 亚洲精品国产suv| 亚洲男人的天堂在线| 欧美午夜片在线免费观看| 色婷婷综合久久久久| 777午夜精品福利在线观看| 日韩精品在线私人| 久久精品精品电影网| 亚洲美女黄色片| 日韩av电影在线播放| 亚洲欧美日韩网| 91精品免费视频| 亚洲视频网站在线观看| 亚洲免费福利视频| 91精品国产沙发| 国产精品免费一区二区三区都可以| 欧美黄色www| 日韩成人久久久| 欧洲日韩成人av| 91久久精品日日躁夜夜躁国产| 国产精品网址在线| 久久影视电视剧免费网站清宫辞电视| 一区二区欧美在线| 日韩中文字在线| 精品国偷自产在线视频| 日韩极品精品视频免费观看| 欧美国产日韩在线| 欧美日韩一二三四五区| 国产精品视频区| 91精品视频在线| 欧美激情va永久在线播放| 91精品在线播放| 国产精品91久久| 91精品国产沙发| 亚洲一区免费网站| 性日韩欧美在线视频| 日韩成人黄色av| 国产专区欧美专区| 日韩精品高清视频|