PHPUnit 下使用 PHP_CodeCoverage 函式庫

我們在前一篇有介紹說,如何在兩大作業系統上安裝 PHPUnit 環境,接著程式測試完之後,我們有時候需要知道 line coverage 程式碼行涵蓋率並做為測試的其中一個標準。

在 PHPUnit 本身環境中並無提供這個功能,需要靠另外一個 PHP_CodeCoverage 函式庫做支援。安裝這個函式庫需要用到 Composer 做為安裝,Composer 是一個 PHP 的套件安裝管理工具,讓我們能夠較易管理 PHP 的相關的套件。下面的步驟兩大作業系統皆適用。

第一步:如果我們沒有 Composer ,先去官網下載 Composer ,我建議是下載 composer.phar,使用手動安裝。

第二步:把下載回來的 composer.phar 放到測試專案目錄底下,接著建立一個 composer.json ,裡面輸入下面的文字。


{
     "require": {
        "phpunit/php-code-coverage": "^3"
      }
}

第三步:接著再打開 cmd.exe 輸入下面指令:


php composer.phar install

接著就會開始把 php-code-coverage 函式庫安裝起來了。安裝過程中大概的截圖如下:

 

[備註]

如果出現:

Warning: This development build of composer is over 60 days old. It is recommend
ed to update it by running "composer.phar self-update" to get the latest version
.

 

等相關字樣,意思是警告說,composer.phar 有60天沒有更新了,建議輸入 composer.phar self-update 指令做更新到最新的版本。如果是手動安裝的話,就要輸入下面的指令:


php composer.phar self-update

就只是在前面多加了一個 php 。

第四步:安裝完成之後,就會出現下面相關的截圖:

php-v

第五步:我們就可以在測試專案裡面使用 php-code-coverage 函式庫相關的功能了。

第六步:我們延續上一篇測試,使用兩數相加函式做測試,接著新增一個 phpunit.xml 做為設定檔,這個設定檔目的是要讓 php-code-coverage 知道是哪一個檔案要做涵蓋率的分析。

內容大概像下面這樣:


<?xml version="1.0" encoding="utf-8" ?>
    <phpunit
       colors="true"
       bootstrap="./vendor/autoload.php"
       type="coverage-text" target="reports/" charset="UTF-8">

       <filter>
           <whitelist processUncoveredFilesFromWhitelist="true">
              <directory suffix=".php">C:\wamp\bin\php\php-5.6.15\phpunit\test_sum.php</directory>
           </whitelist>
       </filter>
    </phpunit>

其中,屬性值 type 是要呈現 coverage 使用方式,有純文字和 HTML 可以選擇,如果使用後者的話,那 target 就很重要,因為需要把相關 html 檔案產生到設定 target 的目錄中。

再來就是這行:<directory suffix=”.php”>C:\wamp\bin\php\php-5.6.15\phpunit\test_sum.php</directory> 定義是哪個 PHP 檔案要做 line coverage。

設定好之後,我們就可以來測試涵蓋率了。

第七步:在這個 test 目錄下打開 cmd.exe,或是終端機。輸入下面的指令:


php phpunit.phar test_sum.php --coverage-text

完畢後,會發現出現資訊會跟下面截圖一樣,部分都無法顯示出來或是要等很久才會顯示,所以我們要換個方式把文字資訊截取出來。

php-v

過了一段時間之後,相關涵蓋率訊息才會顯示。

php-v2


php phpunit.phar test_sum.php --coverage-text > res.txt

我們把訊息存到一個自己定義檔名的文字檔裡面,這樣就不用等,cmd.exe. 顯示訊息了。

第八步:我們會使用純文字顯示涵蓋率之後,接著介紹一下用 html 方式呈現,使用這個方式呈現比純文字好處是,呈現出來的相關資訊會顯得比較好看,而且有圖表以及程式碼覆蓋率等較多資訊可以做為參考。

首先先修改 phpunit.xml 設定檔。


<?xml version="1.0" encoding="utf-8" ?>
    <phpunit
       colors="true"
       bootstrap="./vendor/autoload.php"
       type="coverage-html" target="reports/" charset="UTF-8">

       <filter>
          <whitelist processUncoveredFilesFromWhitelist="true">
               <directory suffix=".php">C:\Users\lee\Downloads\php-5.6.15-Win32-VC11-x64\php\test\test_sum.php</directory>
          </whitelist>
       </filter>
    </phpunit>

與上面不一樣的事就是這一段:type=”coverage-html” target=”reports/” ,要確定目標目錄檔存在。

第九步:接著載 終端機 / cmd.exe 中輸入指令:


php phpunit.phar test_sum.php --coverage-html reports/

後面要接目標目錄,檔名需要與 phpunit.xml 一致。

php-v

執行完成之後,就輸出產生 html 分析結果接著去查看 reports 目錄底下。就會發現這樣的檔案結構:

files

我們直接用瀏覽器,開啟 index.html 就會出現涵蓋率分析結果了。

coverage

還有這個程式碼的圖表分析:

coverage

 

[後記]

基本上 PHPUnit 基本用法就到這裡了,要做 coverage 分析之前,建議需要最基本測試,也就是後面不需要帶任何的參數,像是 –coverage-text 等,先看測試 assert(斷言)結果 是不是正確和我們要的,以免使用 assert 相關方法錯誤,導致涵蓋率分析執行下去難以找到錯誤。

PHPUnit 環境安裝與測試筆記

我們在開發網站的時候,很多人的習慣都是開發完之後再做測試,或是不測試,或是只使用黑箱測試而已,其他就沒有了。這樣是一個不正常的開發流程,因為測試的目的是要找錯,找到錯誤之後才可以修正錯誤(Debug),如此軟體才會進步與更加穩固,如果沒有測試的話,就會有潛在的錯誤風險,就可能等到網站上線之後,萬一出錯,就要承擔較高的風險,因此及早找到錯誤,改正錯誤,所花的成本較低。

本筆記是在介紹,我們使用 PHP 開發完網站時,需要遇到白箱測試或黑箱測試時,對裡面 code 做 unit testing. 我們會用到這個工具:PHPUnit 它可以測試 PHP 的 function 與 PHP 的 class

作業系統:LXDE + Ubuntu 14.04

第一步:到官網下載PHPUnit.phar 檔,也可以利用套件管理,Composer 做安裝,不過這裡為了安裝方便,所以直接手動安裝下載 phar 檔使用。

第二步:新版的需要使用PHP 5.6,如果直接在終端機輸入:php phpunit.phar 則會跳出


This version of PHPUnit requires PHP 5.6; using the latest version of PHP is highly recommended.

第三步:我們可以改成下載比較舊的版本,像是 4.8 就可以支援。

第四步:如果最初一開始連 PHP 都沒有裝的話,這一步需要做,如果已經安裝而且也安裝了 Xdebug 套件的話,那這一步可以跳過。打開終端機輸入下列的指令:


sudo apt-get install php5-cli

sudo apt-get install php5-xdebug

這樣安裝好之後,PHP 的版本為  5.5.9 不過這沒有關係,我們用舊版的 PHPUnit 4.8 就可以解決了。舊版的在官網上有一欄上面寫著:Old Stable Release 下面就有提供舊版的 PHPUnit.phar

第五步:這樣我們的測試環境就已經算完成了。

第六步:我們試著撰寫一個測試案例來測試。下面是一個簡單的輸出 Hello World 字串的函式。


<?php
       function hello($num1, $num2)
      {
           return $num1 + $num2;
      }

      class testHello extends PHPUnit_Framework_TestCase
      {
           /** @test */
          public function helloTest()
          {
                $test = hello(1, 3);
                $this->assertEquals(4, $test);
          }
     }
?>

接著在終端機上輸入指令:

php phpunit-old.phar test.php

之後,就會在終端機上看到下面測試的結果:

PHPUnit 4.8.20 by Sebastian Bergmann and contributors.

.

Time: 277 ms, Memory: 7.75Mb

OK (1 test, 1 assertion)

這樣一個基本的測試就結束了,當然在測試的時候,測試案例,test case 是要自己產生的,PHPUnit 並沒有內建功能可以產生 test case 的。之後會有介紹如何安裝 code coverage 可以作為觀看程式碼的含蓋率。需要注意的是, /** @test */ 這一行的註解是需要的,要用來給 PHPUnit 標示測試的函式。

否則的話會出現 No tests found in class “testHello”. 在終端機上。

[後記]

因為 Lubuntu 14.10 升級到 Lubuntu 15.04 了,所以連 PHP 版本也跟著升級到 5.6.4 了 XD 所以上面的問題幾乎都迎刃而解,直接跳過第三步從第四步開始,PHPUnit 也可以用最新版,也不需要自行編譯 PHP 5.6 ,所以不需要繁複的過程,就自行升級 Lubuntu 15.04  吧(誤

作業系統:Windows 系列

PHP 官網下載 binaries for windows 使用。下載 VC11 x64 Thread Safe (2015-Nov-26 04:33:59) 的 zip 檔並解壓縮到自己定義的目錄下。如果想要設定全域變數,避免不需要打一長串的路徑,可以到控制台設定環境變數。如果不設定的話,就每次要使用 PHP 指令時,切換到壓縮的目錄底下即可。

設定變數如下截圖,就把壓縮目錄,加一行到 Path 變數值中,記得要打分號隔開。

php5.6

打開 cmd.exe 切換到 PHP 5.6.16 壓縮的目錄底下,或是直接打 PHP 相關指令 (如果有設定環境變數的話),接著輸入下面的指令:


php -v

接著會看到 PHP 相關本版本訊息,如下截圖。

php-v

這樣 PHP-cli 環境就建置完成了,安裝 PHPUnit 就按照上面下載 phpunit.phar,下來使用,就可以開始測試了。

另外,截圖上面,是沒有安裝 xDebug 的外掛的,要安裝的話,可以自行到 XDebug 官網下載的,建議下載最新的穩定版本,比較不會有問題。

接著把其中一個 php.ini 改成正確的附檔名,有兩個可以選擇,一個是開發階段設定檔,另一個是發佈產品使用的,我們用開發階段那個,把它改成正確的副檔名:ini

打開設定檔並編輯,並把下面這段文字複製到最下面:


zend_extension = "c:/wamp/bin/php/php-5.6.15/zend_ext/php_xdebug-2.2.5-5.6-vc11-x86_64.dll"
;
[xdebug]
xdebug.remote_enable = off
xdebug.profiler_enable = off
xdebug.profiler_enable_trigger = off
xdebug.profiler_output_name = cachegrind.out.%t.%p
xdebug.profiler_output_dir = "c:/wamp/tmp"
xdebug.show_local_vars=0

其中,c:/wamp/bin/php/php-5.6.15/zend_ext/php_xdebug-2.2.5-5.6-vc11-x86_64.dll 這一行改成自己確切存放 xDebug 的位置,接著再輸入一次下面的指令。


php -v

 

就會看當下面截圖的樣子:就會多 with Xdebug v2.3.3, Copyright (c) 2002-2015, by Derick Rethans 相關的訊息了。

php-v

這樣環境就建置完成了。下一篇將會介紹,使用 php-code-coverage