PHPUnit簡介及使用

  • 2020 年 2 月 25 日
  • 筆記

一、PHPUnit是什麼?

1、它是一款輕量級的PHP測試框架,地址:http://www.phpunit.cn

2、手冊:http://www.phpunit.cn/ 二、為什麼要用PHPUnit?

1、可以通過命令操控測試腳本

2、可以測試性能

3、可以測試程式碼覆蓋率

4、可以自動化的更新測試用例的參數數據

5、各種格式的日誌 三、phpunit安裝

    1、下載phpunit:wget https://phar.phpunit.de/phpunit.phar

    2、修改下載文件的許可權:chmod +x phpunit.phar

    3、將phpunit設置為全局變數:mv phpunit.phar /usr/local/bin/phpunit

    4、查看phpunit版本:phpunit -V

    5、還可以按照第三方工具包 cd path/項目 composer require phpunit/phpunit

四、編寫第一個單元測試用例

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

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

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

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

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

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

namespace Server;

class Connect {     public function connectToServer($serverName = null)     {         if ($serverName == null) {             throw new Exception("That's not a server name!");         }         $fp                 = fsockopen($serverName, 80);         $client             = new Client();         $client->serverNmae = $serverName;         return ($fp) ? true : false;     }

    public function returnSampleObject() { return $this; } }

    1     2     3     4     5     6     7     8     9     10     11     12     13     14     15     16     17     18

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

namespace tests;

use PHPUnitFrameworkTestCase;

use ServerConnect;

class ConnectTest extends TestCase {     public function setUp() { }

    public function tearDown() { }

    public function testConnectionIsValid()     {         // test to ensure that the object from an fsockopen is valid         $connObj    = new Connect();         $serverName = 'www.baidu.com';         $this->assertTrue($connObj->connectToServer($serverName) !== false);     } }

    1     2     3     4     5     6     7     8     9     10     11     12     13     14     15     16     17     18     19     20     21

在上面的程式碼中,由於繼承了PHPUnitFrameworkTestCase類,因此在setUp和tearDown方法中,不需要編寫任何程式碼。SetUp方法是在每個測試用例運行前進行一些初始化的工作,而tearDown則在每個測試用例運行後進行一些比如資源的釋放等工作。在測試方法中,通過使用phpunit的斷言assertTrue去判斷所返回的布爾值是否為真,這裡是通過調用Connect.php中的connectToServe方法去判斷能否連接上伺服器。

    接下來我們運行這個單元測試,在命令行下輸入程式碼:     phpunit /path/to/tests/ConnectTest.php     即可,可以看到測試順利通過的話,會輸出以下結果:

PHPUnit 6.5.3 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 260 ms, Memory: 10.00MB

OK (1 test, 1 assertion)

    1     2     3     4     5     6     7     8

記錄測試日誌:

    日誌多種格式:http://www.phpunit.cn/manual/5.7/zh_cn/textui.html#textui.clioptions

phpunit ArrayTest.php –log-tap log.txt

TAP version 13 ok 1 – ArrayTest::testArrayIsEmpty ok 2 – ArrayTest::testarrayHasKey 1..2

    1     2     3     4     5     6

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

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

    1     2     3     4     5     6     7     8     9

五、PHPUnit測試程式碼覆蓋率

可以通過配置phpunit.xml設置需要測試的程式碼路徑或文件

例如:phpunit.xml的配置(放在項目根目錄)

<<?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="vendor/autoload.php"          backupGlobals="false"          backupStaticAttributes="false"          colors="true"          convertErrorsToExceptions="true"          convertNoticesToExceptions="true"          convertWarningsToExceptions="true"          processIsolation="false"          stopOnFailure="false"          syntaxCheck="false">     <testsuites>         <testsuite name="Application Test Suite">             <directory suffix=".php">./tests/</directory>         </testsuite>     </testsuites>     <filter>         <whitelist>             <directory suffix=".php">src/</directory>         </whitelist>     </filter>     <logging>         <log type="coverage-html" target="./runtime/tests/report" lowUpperBound="35"              highLowerBound="70"/>         <log type="coverage-clover" target="./runtime/tests/coverage.xml"/>         <log type="coverage-php" target="./runtime/tests/coverage.serialized"/>         <log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>         <log type="junit" target="./runtime/tests/logfile.xml" logIncompleteSkipped="false"/>         <log type="testdox-html" target="./runtime/tests/testdox.html"/>         <log type="testdox-text" target="./runtime/tests/testdox.txt"/>     </logging>

</phpunit>

    1     2     3     4     5     6     7     8     9     10     11     12     13     14     15     16     17     18     19     20     21     22     23     24     25     26     27     28     29     30     31     32     33

    <filter><whitelist> 必須要寫不然會報錯Error: Incorrect whitelist config, no code coverage will be generated.(沒有程式碼可測試)

    1、通過生成html頁面查看程式碼覆蓋率

通過執行命令:phpunit –coverage-html ./coverage ./src/test

命令解釋:

–coverage-html:生成覆蓋率結果的html coverage:html生成目錄,可以重新定義 ./src/test:測試用例目錄(也可以是單個測試用例文件)

    1     2     3

覆蓋率結果 2、通過生成的text文件查看程式碼覆蓋率

通過執行命令:phpunit –coverage-text ./src/test > test.log

命令解釋:

`–coverage-html`:生成覆蓋率結果的text `./src/test`:測試用例目錄(也可以是單個測試用例文件) `> test.log`:存放覆蓋率結果的文件(文件名稱自己定義)

    1     2     3

可以清晰的看到總覆蓋率和每個文件的覆蓋率。

    覆蓋率計算問題:     1、類:只有類中所有程式碼都執行了,覆蓋率才為100%;     2、方法:類中的方法每一行都執行了,覆蓋率才算100%。例如:類中有5個方法,有兩個方法每一行執行了,覆蓋率為:40%;     3、行:每一行程式碼都執行了就是100%;

六、PHPUnit.xml 配置文件

具體xml看上方。添加PHPUnit.xml之後就可以通過命令phpunit可批量執行單元測試;下面來講講他的配置選項。

bootstrap="./booten.php"

在測試之前載入的的PHP 文件,一般可以做一個初始化工作

<testsuite name="actionsuitetest">       <directory suffix=".php">action</directory>       <file>HuiyuanZhanghuOrder.php</file> </testsuite>

    1     2     3     4

測試套件,如果想測試頁面,action,model 可以多加幾個測試套件

name: 套件名稱

directory :套件測試的目錄,目錄下一般放測試文件的用例

suffix :測試文件後綴,如果不填寫,則默認後綴為Test.php,即phpunit 默認會執行Test.php 的文件

action:測試目錄名

file:可以單獨設置測試文件

exclude:排除不需要測試的文件

 <php>   <includePath>.</includePath>   <ini name="foo" value="bar"/>   <const name="foo" value="bar"/>   <var name="foo" value="bar"/>   <env name="foo" value="bar"/>   <post name="foo" value="bar"/>   <get name="foo" value="bar"/>   <cookie name="foo" value="bar"/>   <server name="foo" value="bar"/>   <files name="foo" value="bar"/>   <request name="foo" value="bar"/> </php>  

    1     2     3     4     5     6     7     8     9     10     11     12     13

這段xml 可以對應以下PHP 程式碼

includePath

ini_set('foo', 'bar'); define('foo', 'bar'); $GLOBALS['foo'] = 'bar'; $_ENV['foo'] = 'bar'; $_POST['foo'] = 'bar'; $_GET['foo'] = 'bar'; $_COOKIE['foo'] = 'bar'; $_SERVER['foo'] = 'bar'; $_FILES['foo'] = 'bar'; $_REQUEST['foo'] = 'bar';

    1     2     3     4     5     6     7     8     9     10     11     12

具體參考:https://phpunit.readthedocs.io/zh_CN/latest/configuration.html#

源碼地址,歡迎start Introduction

單元測試是幾個現代敏捷開發方法的基礎,使得PHPUnit成為許多大型PHP項目的關鍵工具。這個工具也可以被Xdebug擴展用來生成程式碼覆蓋率報告 ,並且可以與phing集成來自動測試,最後它還可以和Selenium整合來完成大型的自動化集成測試。 這是對PHPUnit的一個Demo。一步步帶你走入PHPUnit。基礎文檔 Getting started

# clone the project git clone https://github.com/AndyYoungCN/PHPUnitDemo

# install dependency composer install

# install phpunit if uninstall wget https://phar.phpunit.de/phpunit.phar chmod +x phpunit.phar mv phpunit.phar /usr/local/bin/phpunit phpunit -V

cd PHPUnitDemo phpunit

    1     2     3     4     5     6     7     8     9     10     11     12     13     14     15

結果