成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

PHP 單元測試

娣辯孩 / 2368人閱讀

摘要:上面的規(guī)定是必須遵守的,如果代碼沒有遵守規(guī)定不會(huì)把他當(dāng)做單元測試代碼。每個(gè)單元測試類以被測試的類名開頭。每個(gè)單元測試函數(shù)應(yīng)該為被測試函數(shù)名結(jié)尾。函數(shù)可能在測試環(huán)境不可執(zhí)行,那么無法獲取的執(zhí)行結(jié)果,從而無法對(duì)進(jìn)行單元測試。

本文首發(fā)于 https://jaychen.cc/article/34
作者 Jaychen

朋友,你聽說過安。。。不是,寫過單元測試嗎。

單元測試是開發(fā)過程中必不可少的一環(huán),一個(gè)項(xiàng)目有良好的單元測試代碼,重構(gòu)的勇氣都大很多。這次寫一篇小文來介紹一下 PHP 的單元測試工具 PHPUnit 的使用。

PHPUnit 的使用并不難,這篇文章主要還是充當(dāng)一個(gè)引子,介紹基本概念和使用,有了這篇文章的基礎(chǔ)之后,去看官網(wǎng)的文檔就會(huì)更加順風(fēng)順?biāo)?/pre>
安裝

安裝 PHPUnit 的方式很簡單,使用 composer 可以一行代碼就可以安裝。

composer require --dev phpunit/phpunit

安裝之后,在 vendor/bin 目錄下有一個(gè) phpunit 的可執(zhí)行文件,這個(gè)就是 phpunit 本體了。假設(shè)我們項(xiàng)目的目錄結(jié)構(gòu)如下:

?  phpunit tree .

├── controller
├── model
├── service
├── test
└── vendor
├── composer.json

其中我們的單元測試代碼都放在 test 目錄下。使用 composer 來為我們解決 autoload 的問題。

{
  "autoload": {
    "psr-4": {
      "Controller": "controller/",
      "Model": "model/",
      "Service": "service/",
      "Test": "test/",
    }
  },
}

如果你還不懂 composer 自動(dòng)加載的使用,可以參考這篇文章。最后執(zhí)行 composer dumpautoload -o 讓自動(dòng)加載生效。

到這里我們的安裝就算結(jié)束了。如果你使用 phpstorm 進(jìn)行開發(fā),那么你需要進(jìn)行如下的配置:

這里指明了從哪里加載 PHPUnit,由于我們使用 composer 安裝,所以,這里的文件選擇 composer 生成的 autoload.php 文件即可。

使用

好了,假設(shè)我們現(xiàn)在進(jìn)行開發(fā),在 service 目錄中添加了一個(gè) CalculateService 的文件,并且編寫了一個(gè) abs 的函數(shù)。

namespace Service;

class CalculateService
{
    public function abs($num)
    {
        return abs($num);
    }
}

現(xiàn)在我們對(duì) abs 函數(shù)進(jìn)行單元測試,PHPUnit 規(guī)定了一個(gè)測試類必須遵守如下的規(guī)定:

單元測試類名必須以 Test 結(jié)尾,必須繼承 PHPUnitFrameworkTestCase 基類。

每個(gè)測試函數(shù)必須以 test 開頭。

上面的規(guī)定是必須遵守的,如果代碼沒有遵守規(guī)定 PHPUnit 不會(huì)把他當(dāng)做單元測試代碼。除了以上的兩條,還有一些良好的編碼習(xí)慣可以參考:

單元測試代碼都放在 test 目錄下。

每個(gè)單元測試類以被測試的類名開頭。例如被測試類為 CalculateService,那么單元測試類應(yīng)該為 CalculateServiceTest。

每個(gè)單元測試函數(shù)應(yīng)該為被測試函數(shù)名結(jié)尾。例如被測試函數(shù)為 abs,那么單元測試函數(shù)應(yīng)該為 testAbs。

根據(jù)上面的規(guī)范,編寫單元測試代碼

class UserServiceTest extends PHPUnitFrameworkTestCase
{
    public function testAbs()
    {
        $userService = new ServiceCalculateService();
        $this->assertEquals(4, $userService->abs(4));
    }
}

在上面的測試代碼中,調(diào)用了我們要測試的函數(shù) abs,然后斷言 $userService->abs(4) 的結(jié)果為 4。在 phpstorm 中直接在 testAbs 函數(shù)處右鍵選擇 run UserServiceTest 執(zhí)行:

發(fā)現(xiàn)在控制臺(tái)會(huì)輸出如下內(nèi)容

Time: 17 ms, Memory: 4.00MB

OK (1 test, 1 assertion)

表明 abs 通過了 $userService->abs(4) == 4 的測試用例。這里注意一點(diǎn),這里并不表明 abs 函數(shù)已經(jīng)通過測試,一個(gè)良好的測試應(yīng)該包含多個(gè)測試用例來覆蓋盡可能多的可能性。

現(xiàn)在 PHPUnit 基本的單元測試已經(jīng)運(yùn)行成功了,在 PHPUnit 的文檔中,有更多關(guān)于測試的用法。由于 PHPUnit 的用法過多,這里不能一一說明,這里提一些其他用法。

PHPUnit 提供了 @test 的注解,如果一個(gè)測試函數(shù)添加了 @test 注解,那么測試函數(shù)名字就不必以 test 開頭。

PHPUnitFrameworkTestCase 有一個(gè) setUp 函數(shù),如果自己編寫的測試類重寫了這個(gè)函數(shù),那么每次在開始執(zhí)行測試函數(shù)之前,會(huì)先執(zhí)行 setUp 進(jìn)行測試之前的初始化。同樣,也有一個(gè) tearDown 的函數(shù),如果重寫,那么在測試函數(shù)執(zhí)行完畢之后調(diào)用 tearDown 函數(shù)。

.... 更多的內(nèi)容需參考 PHPUnit 的文檔。

phpunit.xml 文件

在上面的例子中,我們使用 phpstorm 逐個(gè)執(zhí)行測試函數(shù),但是如果我們需要一次性執(zhí)行所有的單元測試,那么我們可以編寫 phpunit.xml 文件來實(shí)現(xiàn)。

給出一個(gè) phpunit.xml 的編寫例子來講解 phpunit.xml 的作用



    
        
            test
        
    

這里 test 指定了測試代碼都放在 test 目錄下,在 phpstorm 下右鍵點(diǎn)擊 phpunit.xml 文件選擇 Run phpunit.xml,phpunit 就會(huì)到 test 目錄下查找所有單元測試并逐個(gè)執(zhí)行。

除了使用 phpunit.xml 來一次性執(zhí)行所有的單元測試,還可以在 phpunit.xml 中配置單元測試結(jié)果的輸出日志。



    .....
    
        
    

此時(shí)在執(zhí)行 phpunit.xml 文件,就會(huì)在項(xiàng)目目錄下生成一個(gè) tmp/log.html 文件,這個(gè)文件記錄了所有單元測試的結(jié)果。

當(dāng)然,,,更多 phpunit.xml 配置相關(guān)的內(nèi)容,還是需要查看文檔。

Mock 測試

PHPUnit 還提供了 Mock 測試。這里先介紹一下什么是 Mock 測試。

假設(shè) foo 函數(shù)調(diào)用了 bar 函數(shù),那么在對(duì) foo 函數(shù)進(jìn)行單元測試會(huì)有兩個(gè)問題:

foo 函數(shù)依賴于 bar 函數(shù)的結(jié)果,那么在對(duì) foo 進(jìn)行單元測試的時(shí)候必然會(huì)引入 bar ,那么這樣子單元測試就沒意義了,如果測試不通過,那么無法保證 bug 出在 foo 還是 bar。

bar 函數(shù)可能在測試環(huán)境不可執(zhí)行,那么 foo 無法獲取 bar 的執(zhí)行結(jié)果,從而無法對(duì) foo 進(jìn)行單元測試。

Mock 測試就是為了解決上面的問題而出現(xiàn)的,使用 Mock 我們可以虛擬出一個(gè) bar 的調(diào)用,并且假設(shè) bar 調(diào)用返回結(jié)果。如果還是聽不懂,上一段代碼就知道了。

class MockTest extends PHPUnitFrameworkTestCase {
    public function testGet()
    {  
        $stub = $this->createMock(AppUserService::class);     //1
        $stub->method("get")->willReturn(3);                     //2
        $this->assertEquals(3,$stub->get(1));                      //3
    } 
}

上面的測試函數(shù)就使用到了 Mock,一行一行代碼來分析:

第一行創(chuàng)建了一個(gè)虛擬的 UserService 對(duì)象。

第二行假設(shè) UserService 中的 get 函數(shù)的返回值為 3。

第三行調(diào)用 $stub->get(1) 不會(huì)真的去執(zhí)行 get 函數(shù),而是根據(jù)第二行的 willReturn 函數(shù)直接返回 3。

以上就是一個(gè)簡單的 Mock 測試,當(dāng)然 Mock 測試還有很多復(fù)雜的用法,這里沒辦法一一展開,其實(shí)掌握基本的用法,更多復(fù)雜的高級(jí)用法在實(shí)踐中碰到了再去查看文檔也不遲。

好了,PHPUnit 的基本操作就這些了,單元測試本身并不是一個(gè)很難的東西,阻礙單元測試的進(jìn)行并不是在技術(shù)上,更多的是一個(gè)項(xiàng)目時(shí)間安排的衡量與考慮。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/26256.html

相關(guān)文章

  • PHPUnit實(shí)踐一(初識(shí))

    摘要:另外一些單元測試可能會(huì)測試負(fù)向路徑的場景,保證代碼不僅會(huì)產(chǎn)生錯(cuò)誤,而且是預(yù)期的錯(cuò)誤。是一個(gè)面向程序員的測試框架,這是一個(gè)的體系結(jié)構(gòu)的單元測試框架。 本系列教程所有的PHPUnit測試基于PHPUnit6.5.9版本,Lumen 5.5框架 前置 日常我們的普通用到的測試: 代碼直接echo,debug等方法測試 -> 跟蹤細(xì)節(jié)斷點(diǎn)型測試 log日志輔助測試 -> 跟蹤細(xì)節(jié)斷點(diǎn)型測試 ...

    weapon 評(píng)論0 收藏0
  • PHPUnit實(shí)踐一(初識(shí))

    摘要:另外一些單元測試可能會(huì)測試負(fù)向路徑的場景,保證代碼不僅會(huì)產(chǎn)生錯(cuò)誤,而且是預(yù)期的錯(cuò)誤。是一個(gè)面向程序員的測試框架,這是一個(gè)的體系結(jié)構(gòu)的單元測試框架。 本系列教程所有的PHPUnit測試基于PHPUnit6.5.9版本,Lumen 5.5框架 前置 日常我們的普通用到的測試: 代碼直接echo,debug等方法測試 -> 跟蹤細(xì)節(jié)斷點(diǎn)型測試 log日志輔助測試 -> 跟蹤細(xì)節(jié)斷點(diǎn)型測試 ...

    hss01248 評(píng)論0 收藏0
  • 寫一個(gè)“特殊”的查詢構(gòu)造器 - (八、單元測試、收尾工作)

    摘要:單元測試的好處是給開發(fā)人員的,并不是給機(jī)器的。對(duì)于查詢構(gòu)造器這個(gè)項(xiàng)目,我們可以讓其在遠(yuǎn)程運(yùn)行環(huán)境安裝相關(guān)數(shù)據(jù)庫軟件,執(zhí)行數(shù)據(jù)表建立,數(shù)據(jù)導(dǎo)入,執(zhí)行單元測試等操作。查詢構(gòu)造器的完整代碼查詢構(gòu)造器的單元測試完整代碼。 debug 模式 對(duì)查詢構(gòu)造器進(jìn)行調(diào)試并不難,從其構(gòu)造 SQL -> 數(shù)據(jù)綁定 -> SQL 執(zhí)行的過程中就能發(fā)現(xiàn),要方便調(diào)試,只要可以觀察以下信息: 構(gòu)造的 SQL 綁定...

    Steve_Wang_ 評(píng)論0 收藏0
  • PHP單元測試框架PHPUnit的使用

    摘要:以前在學(xué)習(xí)開發(fā)時(shí)有專門寫過的單元測試的文章,開發(fā)學(xué)習(xí)之單元測試,今天再總結(jié)下怎么在中使用單元測試。是一個(gè)用編程語言開發(fā)的開源軟件,是一個(gè)單元測試框架。單元測試框架經(jīng)常會(huì)包含每個(gè)測試的報(bào)告,以及給出你已經(jīng)覆蓋到的代碼覆蓋率。 以前在學(xué)習(xí)IOS開發(fā)時(shí)有專門寫過Objective-C的單元測試的文章,IOS開發(fā)學(xué)習(xí)之單元測試,今天再總結(jié)下怎么在PHP中使用單元測試。 一、前言 在這篇文章中,...

    Bryan 評(píng)論0 收藏0
  • PHP 單元測試與數(shù)據(jù)庫測試

    摘要:只實(shí)例化一次,供測試的清理和裝載基境使用對(duì)于每個(gè)測試,只實(shí)例化一次至今為止,完成了最基礎(chǔ)和入門的單元測試和數(shù)據(jù)庫測試,最終數(shù)據(jù)庫無非就是查看數(shù)據(jù)增刪改查是否和預(yù)期一樣。恭喜你,你已經(jīng)構(gòu)建完自己的單元測試環(huán)境了。 我總感覺 PHP 的開發(fā)者們并沒有對(duì) PHP 的質(zhì)量有所追求,可能是因?yàn)?PHP 的機(jī)制問題吧,讓大部分的開發(fā)者總以為瀏覽器訪問就沒有問題,所以很多時(shí)候,做 PHP 開發(fā)的,就...

    hersion 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<