?
快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

輝煌煌國際hui137登陸l:利用單元測試在每個層上對PHP代碼進行檢查

?

測試驅動的開拓和單元測試是確保代碼在顛末改動和重大年夜調劑之后依然能如我們期望的一樣事情的最新措施。在本文中,您將進修到若何在模塊、數據庫和用戶界面(UI)層對自己的 PHP 代碼進行單元測試。

現在是早晨 3 點。我們如何才能知道自己的代碼依然在事情呢?

Web 利用法度榜樣是 24x7 不間斷運行的輝煌煌國際hui137登陸l,是以我的法度榜樣是否還在運行這個問題會在晚上不停困擾我。單元測試已經幫我對自己的代碼建立了足夠的信心 —— 這樣我就可以安穩地睡個好覺了。

單元測試 是一個為代碼編寫測試用例并自動運行這些測試的框架。測試驅動的開拓 是一種單元測試措施,其思惟是應該首先編寫測試法度榜樣,并驗證這些測試可以發明差錯,然后才開始編寫必要經由過程這些測試的代碼。當所有測試都經由過程期,我們開拓的特點也就完成了。這些單元測試的代價是我們可以隨時運行它們 —— 在簽入代碼之前,重大年夜改動之后,或者支配到正在運行的系統之后都可以。

PHP 單元測試

對付 PHP 來說,單元測試框架是 PHPUnit2。可以應用 PEAR 敕令行作為一個 PEAR 模塊來安裝這個系統:% pear install PHPUnit2。

在安裝這個框架之后,可以經由過程創建派生于 PHPUnit2_Framework_TestCase 的測試類來編寫單元測試。

模塊單元測試

我發明開始單元測試最好的地方是在利用法度榜樣的營業邏輯模塊中。我應用了一個簡單的例子:這是一個對兩個數字進行乞降的函數。為了開始測試,我們首先編寫測試用例,如下所示。

清單 1. TestAdd.php

assertTrue( add( 1, 2 ) == 3 ); }

function test2() { $this->assertTrue( add( 1, 1 ) == 2 ); }

}

?>

這個 TestAdd 類有兩個措施,都應用了 test 前綴。每個措施都定義了一個測試,這個測試可以與清單 1 一樣簡單,也可以十分繁雜。在本例中,我們在第一個測試中只是簡單地斷定 1 加 2 即是 3,在第二個測試中是 1 加 1 即是 2。

PHPUnit2 系統定義了 assertTrue() 措施,它用來測試參數中包孕的前提值是否為真。然后,我們又編寫了 Add.php 模塊,最初讓它孕育發生差錯的結果。

清單 2. Add.php

現在運行單元測試時,這兩個測試都邑掉敗。

清單 3. 測試掉敗

% phpunit TestAdd.php

PHPUnit 2.2.1 by Sebastian Bergmann.

FF

Time: 0.0031270980834961

There were 2 failures:

1) test1(TestAdd)

2) test2(TestAdd)

FAILURES!!!

Tests run: 2, Failures: 2, Errors: 0, Incomplete Tests: 0.

現在我知道這兩個測試都可以正常事情了。是以,可以改動 add() 函數來真正地做實際的工作了。

現在這兩個測試都可以經由過程了。

清單輝煌煌國際hui137登陸l 4. 測試經由過程

% phpunit TestAdd.php

PHPUnit 2.2.1 by Sebastian Bergmann.

..

Time: 0.0023679733276367

OK (2 tests)

%

只管這個測試驅動開拓的例子異常簡單,然則我們可以從中體會到它的思惟。我們起開創建了測試用例,并且有足夠多的代碼讓這個測試運行起來,不過結果是差錯的。然后我們驗證測試切實著實是掉敗的,接實在現了實際的代碼使這個測試能夠經由過程。

我發明在實今世碼時我會不停賡續地添加代碼,直到擁有一個覆蓋所有代碼路徑的完備測試為止。在本文的著末,您會看到有關編寫什么測試和若何編寫這些測試的一些建議。

數據庫測試

在進行模塊測試之后,就可以進行數據庫造訪測試了。數據庫造訪測試 帶來了兩個有趣的問題。首先,我們必須在每次測試之前將數據庫規復到某個已知點。其次,要留意這種規輝煌煌國際hui137登陸l復可能會對現稀有據庫造成破壞,是以我們必須對非臨盆數據庫進行測試,或者在編寫測試用例時留意不能影響現稀有據庫的內容。

最初孕育發生掉敗的 dblib.php PHP 數據庫造訪代碼版本如下所示。

清單 7. dblib.php

getMessage()); }

return $db;

}

public static function delete_all()

{

return false;

}

public static function insert( $name )

{

return false;

}

public static function get_all()

{

return null;

}

}

?>

對清單 8 中的代碼履行單元測試會顯示這 3 個測試整個掉敗了:

清單 8. dblib.php

% phpunit TestAuthors.php

PHPUnit 2.2.1 by Sebastian Bergmann.

FFF

Time: 0.007500171661377

There were 3 failures:

1) test_delete_all(TestAuthors)

2) test_insert(TestAuthors)

3) test_insert_and_get(TestAuthors)

FAILURES!!!

Tests run: 3, Failures: 3, Errors: 0, Incomplete Tests: 0.

%

現在我們可以開始添加精確造訪數據庫的代碼 —— 一個措施一個措施地添加 —— 直到所有這 3 個測試都可以經由過程。終極版本的 dblib.php 代碼如下所示。

清單 9. 完備的 dblib.php

getMessage()); }

return $db;

}

public static function delete_all()

{

$db = Authors::get_db();

$sth = $db->prepare( 'DELETE FROM authors' );

$db->execute( $sth );

return true;

}

public static function insert( $name )

{

$db = Authors::get_db();

$sth = $db->prepare( 'INSERT INTO authors VALUES (null,?)' );

$db->execute( $sth, array( $name ) );

return true;

}

public static function get_all()

{

$db = Authors::get_db();

$res = $db->query( "SELECT * FROM authors" );

$rows = array();

while( $res->fetchInto( $row ) ) { $rows []= $row; }

return $rows;

}

}

?>

這個測試應用了 PEAR 供給的 HTTP Client 模塊。我發明它比內嵌的 PHP Client URL Library(CURL)更簡單一點兒,不過也可以應用后者。

有一個測試會反省所返回的頁面,并判斷這個頁面是否包孕 HTML。第二個測試會經由過程將值放到哀求的 URL 中來哀求謀略 10 和 20 的和,然后反省返回的頁面中的結果。

這個頁面的代碼如下所示。

清單 11. TestPage.php

" /> +

" /> =

這個頁面相稱簡單。兩個輸入域顯示了哀求中供給確當前值。結果 span 顯示了這兩個值的和。 標記標出了所有差別:它對付用戶來說是弗成見的,然則對付單元測試來說卻是可見的。是以單元測試并不必要繁雜的邏輯來找到這個值。相反,它會檢索一個特定標記的值。這樣當界面發生變更時,只要 span 存在,測試就可以經由過程。

與前面一樣,首先編寫測試用例,然后創建一個掉敗版本的頁面。我們對掉敗環境進行測試,然后改動頁面的內容使其可以事情。結果如下:

清單 12. 測試掉敗環境,然后改動頁面

這些測試確保利用編程接口(API)可以精確地分配并開釋資本 —— 例如,繼續幾回調用打開、寫入以及關閉基于文件的 API,從而確保沒有文件依然是被打開的。

回調測試

對付具有回調措施的 API 來說,這些測試可以確保假如沒有定義回調函數,代碼可以正常運行。別的,這些測試還可以確保在定義了回調函數然則這些回調函數操作有誤或孕育發生非常時,代碼依然可以正常運行。

這是有關單元測試的幾點設法主見。有關若何編寫單元測試,我也有幾點建議:

不要應用隨機數輝煌煌國際hui137登陸l據

只管在一個界面中孕育發生隨機數據看起來貌似一個好主見,然則我們要避免這樣做,由于這些數據會變得異常難以調試。假如數據是在每次調用時隨機天生的,那么就可能孕育發生一次測試時呈現了差錯而別的一次測試卻沒有呈現差錯的環境。假如測試必要隨機數據,可以在一個文件中天生這些數據,然后每次運行時都應用這個文件。采納這種措施,我們就得到了一些 “噪音” 數據,然則仍舊可以對差錯進行調試。

分組測試

我們很輕易累積起數千個測試,必要幾個小時才能履行完。這沒什么問題,然則對這些測試進行分組使我們可以快速運行某組測試并對主要關注的問題進行反省,然后晚上運行完備的測試。

編寫穩健的 API 和穩健的測試

編寫 API 和測試時要留意它們不能在增添新功能或改動現有功能時很輕易就會崩潰,這一點異常緊張。這里沒有通用的絕招,然則有一條準則是那些 “振蕩的” 測試(一下子掉敗,一下子成功,反復不絕的測試)應該很快地丟棄。

停止語

單元測試對付工程師來說意義重大年夜。它們是敏捷開拓歷程(這個歷程異常強調編碼的感化,由于文檔必要一些證據證實代碼是按照規范進行事情的)的一個根基。單元測試就供給了這種證據。這個歷程從單元測試開始入手,這定義了代碼應該 實現但今朝尚未 實現的功能。是以,所有的測試最初都邑掉敗。然后現代碼靠近完成時,測試就經由過程了。當所有測試整個經由過程期,代碼也就變得異常完善了。

我從來沒有在不應用單元測試的環境下輝煌煌國際hui137登陸l編寫大年夜型代碼或改動大年夜型或繁雜的代碼塊。我平日都是在改動代碼之前就為現有代碼編寫了單元測試,這樣可以確保自己清楚在改動代碼時破壞了什么(或者沒有破壞什么)。這為我對自己供給給客戶的代碼供給了很大年夜的信心,信托它們正在精確運行 —— 即就是在早晨 3 點。

免責聲明:以上內容源自網絡,版權歸原作者所有,如有侵犯您的原創版權請告知,我們將盡快刪除相關內容。

您可能還會對下面的文章感興趣:

河北十一选五开奖的 老友棋牌内蒙麻将群 山东时时彩 集中盈配资 山西天星麻将下载安装 竞彩篮球大小分 11选甘肃5开奖结 佐々木2017作品无码 长峰河南个人资料 临汾股指期货配资 步兵番号网站 赤井美月EBOD一339 长春一条龙服务多少钱 河北时时彩 有富策略 尚盈配资 吉林十一选五走势