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
結果
