新聞中心
你是否在程序開(kāi)發(fā)的過(guò)程中遇到以下的情況:當(dāng)你花了很長(zhǎng)的時(shí)間開(kāi)發(fā)一個(gè)PHP應(yīng)用后,你認(rèn)為應(yīng)該是大功告成了,可惜在調(diào)試的時(shí)候,老是不斷的發(fā)現(xiàn)bug,而且最可怕的是,這些bug是重復(fù)出現(xiàn)的,你可能發(fā)現(xiàn)這些bug之間會(huì)有關(guān)聯(lián),但卻老是找不到問(wèn)題的所在。

成都創(chuàng)新互聯(lián)公司2013年開(kāi)創(chuàng)至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站建設(shè)、成都網(wǎng)站制作網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元贛榆做網(wǎng)站,已為上家服務(wù),為贛榆各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18980820575
當(dāng)你遇到以上這些令你沮喪的情況時(shí),你一定會(huì)想能有什么更好的辦法去解決呢?辦法當(dāng)然是有的!這就是使用單元測(cè)試。單元測(cè)試不但可以在一定程度上解決上述頭疼的問(wèn)題,而且能讓代碼變的容易維護(hù),還可以能讓你更多地對(duì)代碼進(jìn)行重構(gòu)。
一旦你編寫好單元測(cè)試用例,當(dāng)你需要修改你的代碼時(shí),你要做的事情就是重新運(yùn)行你的單元測(cè)試用例并觀察這些單元測(cè)試用例能否通過(guò),如果通過(guò)了的話,證明代碼是沒(méi)問(wèn)題的。
人們往往會(huì)說(shuō):既然單元測(cè)試這么好,為什么那么多人還是不大愿意去寫單元測(cè)試呢?有以下幾種理解上的誤曲:
1、認(rèn)為編寫單元測(cè)試太浪費(fèi)時(shí)間。雖然目前很多IDE工具都為編寫單元測(cè)試建立好了框架,但還是要開(kāi)發(fā)者編寫一些單元測(cè)試的代碼的。就象很多開(kāi)發(fā)中的***實(shí)踐一樣,用正確的方法去做正確的事情會(huì)為開(kāi)發(fā)節(jié)省大量的時(shí)間。每當(dāng)新增加新功能時(shí),你可能通過(guò)訪問(wèn)你的網(wǎng)頁(yè)到處去點(diǎn)擊手動(dòng)測(cè)試,而運(yùn)行建立好的單元測(cè)試用例其速度其實(shí)比通過(guò)手工去測(cè)試的速度更快。
2、認(rèn)為既然代碼能運(yùn)行了,不需要再編寫單元測(cè)試。但假設(shè)團(tuán)隊(duì)中有新的成員,如果沒(méi)有良好的單元測(cè)試用例,新成員很有可能隨意地去編碼而不考慮各種后果。如果有編寫良好的單元測(cè)試,在程序運(yùn)行時(shí)進(jìn)行各種測(cè)試,則能***程度避免bug的產(chǎn)生。
3、認(rèn)為編寫單元測(cè)試代碼枯燥無(wú)味。程序員的天性是解決問(wèn)題,而很多程序員認(rèn)為在緊張的編碼工作時(shí),還要編寫單元測(cè)試代碼,會(huì)很枯燥。但要知道的是,如果能通過(guò)編寫單元測(cè)試在很早的階段就能盡可能發(fā)現(xiàn)代碼中多的錯(cuò)誤的話,那么既節(jié)省時(shí)間減少了出錯(cuò),何樂(lè)而不為?
開(kāi)始動(dòng)手安裝PHPUnit
本文中將通過(guò)介紹PHP中的單元測(cè)試?yán)鱌HPUnit(http://phpunit.de/),并通過(guò)實(shí)際例子來(lái)講解如何在實(shí)際工作中運(yùn)用PHPUnit。首先安裝PHPUnit的方法可以通過(guò)PHP下的pear去安裝:
pear channel-discover pear.phpunit.de
pear channel-discover components.ez.no
pear channel-discover pear.symfony-project.com
pear install phpunit/PHPUnit
如果你想通過(guò)手動(dòng)方式去安裝,可以參考PHPUnit的手冊(cè)去安裝(http://www.phpunit.de/manual/3.0/en/installation.html)。
編寫***個(gè)單元測(cè)試用例
下面我們開(kāi)始編寫***個(gè)單元測(cè)試用例。在編寫測(cè)試用例時(shí),要遵守如下的PHPUnit的規(guī)則:
1 一般地,在測(cè)試用例中,可以擴(kuò)展PHPUnit_Framework_TestCase類,這樣就可以使用象setUp(),tearDown()等方法了。
2 測(cè)試用例的名字***是使用約定俗成的格式,即在被測(cè)試類的后面加上”Test”,比如要測(cè)試的類為RemoteConnect,則測(cè)試用例的命名為RemoteConnectTest。
3 在一個(gè)測(cè)試用例中的所有的測(cè)試方法,在命名時(shí)都應(yīng)該以test+測(cè)試方法名去命名,如testDoesLikeWaffles(),要注意的是該方法必須是聲明為public類型的。當(dāng)然可以在你的測(cè)試用例中包含private的方法,但它們不能被phpunit所調(diào)用。
4 測(cè)試方法中是不能接收參數(shù)的。
下面首先舉個(gè)簡(jiǎn)單的例子,代碼如下:
- class RemoteConnect
- {
- public function connectToServer($serverName=null)
- {
- if($serverName==null){
- throw new Exception(“That's not a server name!”);
- }
- $fp = fsockopen($serverName,80);
- return ($fp) ? true : false;
- }
- public function returnSampleObject()
- {
- return $this;
- }
- }
- ?>
上面的代碼其實(shí)是實(shí)現(xiàn)連接到一個(gè)指定的服務(wù)器的功能,那么我們可以編寫測(cè)試代碼如下:
- require_once('RemoteConnect.php');
- class RemoteConnectTest extends PHPUnit_Framework_TestCase
- {
- public function setUp(){ }
- public function tearDown(){ }
- public function testConnectionIsValid()
- {
- // test to ensure that the object from an fsockopen is valid
- $connObj = new RemoteConnect();
- $serverName = 'www.google.com';
- $this->assertTrue($connObj->connectToServer($serverName) !== false);
- }
- }
- ?>
在上面的代碼中,由于繼承了PHPUnit_Framework_TestCase類,因此在setUp和tearDown方法中,不需要編寫任何代碼。SetUp方法是在每個(gè)測(cè)試用例運(yùn)行前進(jìn)行一些初始化的工作,而tearDown則在每個(gè)測(cè)試用例運(yùn)行后進(jìn)行一些比如資源的釋放等工作。在測(cè)試方法中,通過(guò)使用PHPUnit的斷言assertTrue去判斷所返回的布爾值是否為真,這里是通過(guò)調(diào)用RemoteConnect.php中的connectToServe方法去判斷能否連接上服務(wù)器。
接下來(lái)我們運(yùn)行這個(gè)單元測(cè)試,在命令行下輸入代碼:
phpunit /path/to/tests/RemoteConnectTest.php即可,可以看到測(cè)試順利通過(guò)的話,會(huì)輸出以下結(jié)果:
PHPUnit 3.4 by Sebastian Bergmann . Time: 1 second Tests: 1, Assertions: 1, Failures 0
可以看到,上面是通過(guò)了測(cè)試。默認(rèn)情況下,PHPUnit是會(huì)運(yùn)行測(cè)試用例中的所有測(cè)試方法的。下面再介紹下PHPUnit中相關(guān)的幾個(gè)斷言:
AssertTrue/AssertFalse 斷言是否為真值還是假 AssertEquals 判斷輸出是否和預(yù)期的相等 AssertGreaterThan 斷言結(jié)果是否大于某個(gè)值,同樣的也有LessThan(小于),GreaterThanOrEqual(大于等于), LessThanOrEqual(小于等于). AssertContains 判斷輸入是否包含指定的值 AssertType 判斷是否屬于指定類型 AssertNull 判斷是否為空值 AssertFileExists 判斷文件是否存在 AssertRegExp 根據(jù)正則表達(dá)式判斷
舉個(gè)例子來(lái)說(shuō)明下比如AssertType的使用,依然以上面的例子來(lái)說(shuō),可以用AssertType去判斷returnSampleObject返回的對(duì)象實(shí)例是否為remoteConnect,代碼如下:
- function testIsRightObject() {
- $connObj = new RemoteConnect();
- $returnedObject = $connObj->returnSampleObject();
- $this->assertType('remoteConnect', $returnedObject);
- }
- ?>
目前PHP框架對(duì)單元測(cè)試的支持
目前很多優(yōu)秀的PHP框架(如Zend Framework,Symfony等),都提供了對(duì)單元測(cè)試很好的支持。以Zend Framework為例,說(shuō)明下其中是如何運(yùn)行單元測(cè)試的。
- class CommentControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
- {
- public function setUp()
- {
- parent::setUp();
- }
- public function tearDown()
- {
- parent::tearDown();
- }
- public function appBootstrap()
- {
- $this->frontController->registerPlugin(new Initializer('test'));
- }
- public function testGoHome()
- {
- $this->dispatch('/home');
- $this->assertController('home');
- }
- }
- ?>
以上代碼其實(shí)是對(duì)Zend本身的框架進(jìn)行了一個(gè)單元測(cè)試而已,可以看到,在Zend中,是通過(guò)繼承Zend_Test_PHPUnit_ControllerTestCase去對(duì)Zend的controller去進(jìn)行單元測(cè)試的,可以看到,在zend中的單元測(cè)試跟PHPUnit中的差不多,但增加了另外一些新的斷言,比如上面的assertController,具體的可以參考Zend的參考手冊(cè)。
PHPUnit是一個(gè)輕量級(jí)的PHP測(cè)試框架。它是在PHP5下面對(duì)JUnit3系列版本的完整移植,是xUnit測(cè)試框架家族的一員(它們都基于模式先鋒Kent Beck的設(shè)計(jì))。
單元測(cè)試是幾個(gè)現(xiàn)代敏捷開(kāi)發(fā)方法的基礎(chǔ),使得PHPUnit成為許多大型PHP項(xiàng)目的關(guān)鍵工具。這個(gè)工具也可以被Xdebug擴(kuò)展用來(lái)生成代碼覆蓋率報(bào)告 ,并且可以與phing集成來(lái)自動(dòng)測(cè)試,最后它還可以和Selenium整合來(lái)完成大型的自動(dòng)化集成測(cè)試。
本文標(biāo)題:初探PHP單元測(cè)試?yán)鳎篜HPUnit
路徑分享:http://m.5511xx.com/article/cdedecg.html


咨詢
建站咨詢
