PHP單元測試利器:PHPUNIT初探

2021-02-19 PHP老楊

你是否在程序開發的過程中遇到以下的情況:當你花了很長的時間開發一個應用後,你認為應該是大功告成了,可惜在調試的時候,老是不斷的發現bug,而且最可怕的是,這些bug是重複出現的,你可能發現這些bug之間會有關聯,但卻老是找不到問題的所在。

  當你遇到以上這些令你沮喪的情況時,你一定會想能有什麼更好的辦法去解決呢?辦法當然是有的!這就是使用單元測試。單元測試不但可以在一定程度上解決上述頭疼的問題,而且能讓代碼變的容易維護,還可以能讓你更多地對代碼進行重構。

  一旦你編寫好單元測試用例,當你需要修改你的代碼時,你要做的事情就是重新運行你的單元測試用例並觀察這些單元測試用例能否通過,如果通過了的話,證明代碼是沒問題的。

  人們往往會說:既然單元測試這麼好,為什麼那麼多人還是不大願意去寫單元測試呢?有以下幾種理解上的誤曲:

  1、認為編寫單元測試太浪費時間。雖然目前很多IDE工具都為編寫單元測試建立好了框架,但還是要開發者編寫一些單元測試的代碼的。就象很多開發中的最佳實踐一樣,用正確的方法去做正確的事情會為開發節省大量的時間。每當新增加新功能時,你可能通過訪問你的網頁到處去點擊手動測試,而運行建立好的單元測試用例其速度其實比通過手工去測試的速度更快。

  2、認為既然代碼能運行了,不需要再編寫單元測試。但假設團隊中有新的成員,如果沒有良好的單元測試用例,新成員很有可能隨意地去編碼而不考慮各種後果。如果有編寫良好的單元測試,在程序運行時進行各種測試,則能最大程度避免bug的產生。

  3、認為編寫單元測試代碼枯燥無味。程式設計師的天性是解決問題,而很多程式設計師認為在緊張的編碼工作時,還要編寫單元測試代碼,會很枯燥。但要知道的是,如果能通過編寫單元測試在很早的階段就能儘可能發現代碼中多的錯誤的話,那麼既節省時間減少了出錯,何樂而不為?

  開始動手安裝phpunit

  本文中將通過介紹php中的單元測試利器phpunit(http://phpunit.de/),並通過實際例子來講解如何在實際工作中運用phpunit。首先安裝phpunit的方法可以通過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

  如果你想通過手動方式去安裝,可以參考phpunit的手冊去安裝(http://www.phpunit.de/manual/3.0/en/installation.html)。

  編寫第一個單元測試用例

  下面我們開始編寫第一個單元測試用例。在編寫測試用例時,要遵守如下的phpunit的規則:

  1 一般地,在測試用例中,可以擴展PHPUnit_Framework_TestCase類,這樣就可以使用象setUp(),tearDown()等方法了。

  2 測試用例的名字最好是使用約定俗成的格式,即在被測試類的後面加上」Test」,比如要測試的類為RemoteConnect,則測試用例的命名為RemoteConnectTest。

  3 在一個測試用例中的所有的測試方法,在命名時都應該以test+測試方法名去命名,如testDoesLikeWaffles(),要注意的是該方法必須是聲明為public類型的。當然可以在你的測試用例中包含private的方法,但它們不能被phpunit所調用。

  4 測試方法中是不能接收參數的。

  下面首先舉個簡單的例子,代碼如下:

<?php
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;
  }
}
?>

   上面的代碼其實是實現連接到一個指定的伺服器的功能,那麼我們可以編寫測試代碼如下:

<?php
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方法是在每個測試用例運行前進行一些初始化的工作,而tearDown則在每個測試用例運行後進行一些比如資源的釋放等工作。在測試方法中,通過使用phpunit的斷言assertTrue去判斷所返回的布爾值是否為真,這裡是通過調用RemoteConnect.php中的connectToServe方法去判斷能否連接上伺服器。

接下來我們運行這個單元測試,在命令行下輸入代碼:

  phpunit /path/to/tests/RemoteConnectTest.php即可,可以看到測試順利通過的話,會輸出以下結果:

PHPUnit 3.4 by Sebastian Bergmann
.
Time: 1 second
Tests: 1, Assertions: 1, Failures 0

   可以看到,上面是通過了測試。默認情況下,phpunit是會運行測試用例中的所有測試方法的。下面再介紹下phpunit中相關的幾個斷言:

AssertTrue/AssertFalse    斷言是否為真值還是假
AssertEquals    判斷輸出是否和預期的相等
AssertGreaterThan    斷言結果是否大於某個值,同樣的也有LessThan(小於),GreaterThanOrEqual(大於等於),
LessThanOrEqual(小於等於).
AssertContains    判斷輸入是否包含指定的值
AssertType    判斷是否屬於指定類型
AssertNull    判斷是否為空值
AssertFileExists    判斷文件是否存在
AssertRegExp    根據正則表達式判斷

   舉個例子來說明下比如AssertType的使用,依然以上面的例子來說,可以用AssertType去判斷returnSampleObject返回的對象實例是否為remoteConnect,代碼如下:

<?php
function testIsRightObject() {
  $connObj = new RemoteConnect();
  $returnedObject = $connObj->returnSampleObject();
  $this->assertType('remoteConnect', $returnedObject);
}
?>

   目前PHP框架對單元測試的支持

  目前很多優秀的php框架(如Zend Framework,Symfony等),都提供了對單元測試很好的支持。以Zend Framework為例,說明下其中是如何運行單元測試的。

<?php
class CommentControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
  public function setUp()
  {
    parent::setUp();
  }
  public function tearDown()
  {
    parent::tearDown();
  }
  public function appBootstrap()

相關焦點

  • PHPUnit單元測試簡單入門、使用
    /phpunit ^8一定要注意PHPUnit版本對應的PHP版本,PHPUnit 9支持7.3、7.4版本,PHPUnit 8支持7.2、7.3、7.4,按需引入即可,具體可參考:http://www.phpunit.cn/。
  • Laravel 測試之 —— PHPUnit 入門教程
    介紹PHPUnit 是最古老和最著名的 PHP 單元測試包之一。它主要用於單元測試,這意味著可以用儘可能小的組件測試代碼,但是它也非常靈活,可以用於很多不僅僅是單元測試。PHPUnit 包含許多簡單和靈活的斷言允許您輕鬆地測試代碼,當您測試特定的組件時,這些斷言非常有效。
  • PHPUnit基本使用
    cd myapptouch composer.jsoncomposer.json{ "autoload": { "classmap": [ "src/" ] }}composer安裝PHPUnitcomposer require --dev phpunit
  • 玩玩 PHPUnit 的資料庫測試 (上)
    實際測試是重中之重,正常下來一個需求應當先寫測試用例後實現功能代碼,如果沒有在開發前做測試,那你可以選擇寫一個錯誤的斷言,使用錯誤斷言來驗證代碼是否符合預期,而不是根據功能去寫測試,這是寫測試的一種逆向思維。啥是資料庫測試?很多人可能玩過單元測試,設定呀,斷言呀,等等條件。
  • 途牛原創 大話權限中心的PHP架構之道
    |   |-- Rule.php|   |   |-- User.php|   |-- Orm.php|   |-- Utils.php|-- tests //測試|   |-- bootstrap.php|   |-- fixtures|   |   |-- null.yml|   |   |-- rbac|   |   |   |-- app.yml|   |   |   |-- auth.yml
  • 各種實用的 PHP 開源庫推薦(2)
    它提供的功能包括:在發送郵時指定多個收件人,抄送地址,暗送地址和回復地址支持多種郵件編碼包括:8bit,base64,binary和quoted-printable支持SMTP驗證支持冗餘SMTP伺服器支持帶附件的郵件和Html格式的郵件自定義郵件頭支持在郵件中嵌入圖片調試靈活經測試兼容的
  • 狂擼一款 PHP 現代化框架 (一)
    3、創建一個composer.json文件用於進行包管理,灰常簡單,phpunit搞進來。通過psr-4加載個項目命名。    {      "name": "z framework",      "require-dev": {        "phpunit/phpunit": "^7.0"      },      "autoload": {        "psr-4": {
  • 狂擼一款PHP現代化框架 (準備工作)
    創建一個composer.json文件用於進行包管理,灰常簡單,phpunit搞進來。通過psr-4加載個項目命名{ "name": "z framework", "require-dev": { "phpunit/phpunit": "^7.0" }, "autoload": { "psr-4": { "Zero\\": "src/Zero", } },
  • Android單元測試——初探
    本文主要包含以下內容:什麼是單元測試為什麼需要進行單元測試如何進行單元測試什麼是單元測試首先總結一下什麼是單元測試,單元測試中的單元在Android或Java中可以理解為某個類中的某一個方法,因此單元測試就是針對Android或Java中某個類中的某一個方法中的邏輯代碼進行驗證即測試該方法是不是可以正常工作
  • 用PHP讀取excel文件內容、獲取單元格數據
    源 / php中文網      源 / www.php.cn本篇文章主要介紹如何使用PHP讀取excel文件內容即每個單元格數據,希望對大家有所幫助。PHP腳本的內存量,使用它來調試PHP代碼性能⑥var_dump() 用來列印數組,或者輸出字符串php讀取excel文件,並進行相應處理的具體方法代碼示例如下:<?
  • 研究Laravel框架的測試方法
    單元測試和功能測試如果您已經接觸過 PHPUnit 框架,那麼您應該知道,它支持兩種類型特性 -- 「單元測試」和「功能測試」。「單元測試」的目的是用於測試函數或方法的正確性。更重要的是,我們可以輕鬆實現代碼邏輯的正確性。
  • Nginx Unit 入門教程
    安裝 PHP安裝 WordPress 需要的 PHP 環境和相關 PHP 擴展,這裡我們安裝比較新的 PHP 7.0 版本:$ sudo apt-get install -y php7.0 php7.0-common php7.0-mbstring php7.0-gd php7.0-intl php7.0-xml php7.0-mysql php7.0-mcrypt
  • PHP基礎教程(2):PHP安裝
    所以在這裡網頁教學網站長建議大家下載PHPNOW軟體或者CMS提供的安裝環境軟體進行安裝然後測試PHP程序!有什麼不懂的可以找我交流:QQ76312395,註明PHP安裝交流!你需要做什麼?本教程不會為您講解如何安裝 PHP、MySQL 或 Apache 伺服器。如果您的伺服器支持 PHP - 那麼您不需要做任何事情!
  • 一份經過時間檢驗的 Laravel PHPUnit 測試經驗分享
    利用 Laravel 提供的測試工具Laravel 對請求進行了封裝,我們可以非常方便地在測試中發起各種請求,比如說測試用戶列表。phpuse Illuminate\Database\Seeder;use DB;class UsersTableSeeder extends Seeder{ public function run(){ DB::table('users')->insert([ 'name' => 'baijunyao', ]);
  • PHP7.2、PHP7.1 性能對比
    關於怎麼樣做好一個語言的測試,也沒有經驗,應該從哪些更多的角度去測試,大家多多指點。Zend/bench.php的腳本測試未開啟 opcache$ for i in `seq 1 10`;do /data/local/php71/bin/php /data/soft/php-7.2.0RC3/Zend/bench.php|grep 'Total'|awk '{print $0}' ;done Total              1.381Total
  • php cli模式PHP command line interface
    phpvar_dump($argv, $argc);看結果:用法:php [options] [-f] [--] [args...]php [options] -r [--] [args...]php [options] [-B ] -R [-E ] [--] [args...]
  • 在 macOS 下使用 PHP-version 切換 PHP 版本
    方法一:安裝 php-version(如果沒有用 valet,這個應該是可以的)step 1、使用 brew 安裝多個 php 版本brew install php71 // 原本有就不需要brew install php72step 2、發現 brew 安轉
  • php怎麼設置下拉框的值
    源 / php中文網      源 / www.php.cn用php獲取設置下拉框的值,我們可以通過PHP foreach循環來實現,PHP foreach循環方法可以創建或填充HTML <select&
  • 自動化測試:六個值得參考的 Laravel 開源項目
    這是 Miguel Piedrafita 的一個非常簡單的項目,Orgmanager 的測試也是非常簡單易懂的。還分為單元,功能和 API 測試。    我在這裡看到一個有趣的示例 —— 從測試中調用 Artisan 命令,例如 unit/JoinTest.php:public function testJoinCommand(){
  • php學習筆記day1-php環境安裝
    php是伺服器端語言,需要放到伺服器中才能執行需準備1.ide編輯器,如 phpstorm