婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > PHPUnit + Laravel單元測試常用技能

PHPUnit + Laravel單元測試常用技能

熱門標簽:江西電銷機器人收費 高德地圖標注店鋪收費嗎 泊頭在哪里辦理400電話 天潤融通外呼系統好嗎 江門回撥外呼系統 高德地圖標注位置怎么標注 杭州語音電銷機器人 電銷機器人沒有效果怎么樣 欣思維地圖標注

1. 數據供給器

用來提供參數和結果,使用 @dataProvider 標注來指定使用哪個數據供給器方法。例如檢測app升級數據是否符合預期,addProviderAppUpdateData()提供測試的參數和結果。testAppUpdateData()檢測appUpdateData()返回的結果是否和給定的預期結果相等,即如果$appId='apple_3.3.2_117', $result=['status' => 0, 'isIOS' => false], 則$data中如果含有['status' => 0, 'isIOS' => false], 則斷言成功。建議在數據提供器,逐個用字符串鍵名對其命名,這樣在斷言失敗的時候將輸出失敗的名稱,更容易定位問題

示例代碼:

?php
  namespace Tests\Unit;

  use App\Services\ClientService;
  use Tests\TestCase;

  class ClientServiceTest extends TestCase
  {
    /**
     * @dataProvider addProviderAppUpdateData
     *
     * @param $appId
     * @param $result
     */
    public function testAppUpdateData($appId, $result)
    {
      $data = (new ClientService($appId))->appUpdateData();

      $this->assertTrue(count(array_intersect_assoc($data, $result)) == count($result));
    }

    public function addProviderAppUpdateData()
    {
      return [
        'null'         => [null, ['status' => 0, 'isIOS' => false, 'latest_version' => 'V']],
        'error app id'     => ['sdas123123', ['status' => 0, 'isIOS' => false, 'latest_version' => 'V']],
        'android force update' => ['bx7_3.3.5_120', ['status' => 0, 'isIOS' => false]],
        'ios force update'   => ['apple_3.3.2_117', ['status' => 1, 'isIOS' => true]],
        'android soft update' => ['sanxing_3.3.2_117', ['status' => 2, 'isIOS' => false]],
        'ios soft update'   => ['apple_3.3.3_118', ['status' => 2, 'isIOS' => true]],
        'android normal'    => ['fhqd_3.3.6_121', ['status' => 1, 'isIOS' => false]],
        'ios normal'      => ['apple_3.3.5_120', ['status' => 1, 'isIOS' => true]],
        'h5'          => ['h5_3.3.3', ['status' => 1, 'isIOS' => false]]
      ];
    }
  }

斷言成功結果:

2. 斷言方法

常用有assertTrue(), assertFalse(), assertNull(), assertEquals(), assertThat()。

assertThat()自定義斷言。常用的約束有isNull()、isTrue()、isFalse()、isInstanceOf();常用的組合約束logicalOr()、logicalAnd()。例如檢測返回的結果是否是null或ApiApp類。

示例代碼:

?php
  namespace Tests\Unit;

  use App\Models\ApiApp;
  use App\Services\SystemConfigService;
  use Tests\TestCase;

  class SystemConfigServiceTest extends TestCase
  {
    /**
     * @dataProvider additionProviderGetLatestUpdateAppApi
     *
     * @param $appType
     */
    public function testGetLatestUpdateAppApi($appType)
    {
      $result = SystemConfigService::getLatestUpdateAppApi($appType);
      $this->assertThat($result, $this->logicalOr($this->isNull(), $this->isInstanceOf(ApiApp::class)));
    }

    public function additionProviderGetLatestUpdateAppApi()
    {
      return [
        'apple'  => [1],
        'android' => [2],
        'null'  => [9999]
      ];
    }
  }

斷言成功結果:

3. 對異常進行測試

使用expectExceptionCode()對錯誤碼進行檢測,不建議對錯誤信息文案進行檢測。例如檢測設備被鎖后是否拋出3026錯誤碼。

示例代碼:

?php
  namespace Tests\Unit;

  use App\Services\UserSecurityService;
  use Illuminate\Support\Facades\Cache;
  use Tests\TestCase;

  class UserSecurityServiceTest extends TestCase
  {
    public static $userId = 4;

    /**
     * 設備鎖檢測
     * @throws \App\Exceptions\UserException
     */
    public function testDeviceCheckLock()
    {
      $this->expectExceptionCode(3026);
      Cache::put('device-login-error-account-', '1,2,3,4,5', 300);
      UserSecurityService::$request = null;
      UserSecurityService::$udid  = null;
      UserSecurityService::deviceCheck(self::$userId);
    }
  }

斷言成功結果:

4. 測試私有屬性和私有方法使用反射機制

如果只測試私有方法可使用ReflectionMethod()反射方法,使用setAccessible(true)設置方法可訪問,并使用invokeArgs()或invoke()調用方法(invokeArgs將參數作為數組傳遞)。例如檢測IP是否在白名單中。

示例代碼:

被檢測代碼:

namespace App\Facades\Services;

  /**
   * Class WebDefender
   */
  class WebDefenderService extends BaseService
  {
     //ip白名單
    private $ipWhiteList = [
      '10.*', 
      '172.18.*', 
      '127.0.0.1' 
    ];

    /**
     * ip是否在白名單中
     *
     * @param string $ip
     *
     * @return bool
     */
    private function checkIPWhiteList($ip)
    {
      if (!$this->ipWhiteList || !is_array($this->ipWhiteList)) {
        return false;
      }
      foreach ($this->ipWhiteList as $item) {
        if (preg_match("/{$item}/", $ip)) {
          return true;
        }
      }

      return false;
    }
   }

檢測方法:

?php

  namespace Tests\Unit;

  use App\Facades\Services\WebDefenderService;
  use Tests\TestCase;

  class WebDefenderTest extends TestCase
  {
    /**
     * 測試IP白名單
     * @dataProvider additionProviderIp
     *
     * @param $ip
     * @param $result
     *
     * @throws \ReflectionException
     */
    public function testIPWhite($ip, $result)
    {
      $checkIPWhiteList = new \ReflectionMethod(WebDefenderService::class, 'checkIPWhiteList');
      $checkIPWhiteList->setAccessible(true);
      $this->assertEquals($result, $checkIPWhiteList->invokeArgs(new WebDefenderService(), [$ip]));
    }

    public function additionProviderIp()
    {
      return [
        '10 ip' => ['10.1.1.7', true],
        '172 ip' => ['172.18.2.5', true],
        '127 ip' => ['127.0.0.1', true],
        '192 ip' => ['192.168.0.1', false]
      ];
    }
   }

測試私有屬性可使用ReflectionClass(), 獲取屬性用getProperty(), 設置屬性的值用setValue(), 獲取方法用getMethod(), 設置屬性和方法可被訪問使用setAccessible(true)。例如檢測白名單路徑。

示例代碼:

被檢測代碼:

?php
  namespace App\Facades\Services;

  use App\Exceptions\ExceptionCode;
  use App\Exceptions\UserException;
  use Illuminate\Support\Facades\Cache;

  /**
   * CC攻擊防御器
   * Class WebDefender
   */
  class WebDefenderService extends BaseService
  {
    //路徑白名單(正則)
    private $pathWhiteList = [
      //'^auth\/(.*)',
    ];

    private static $request = null;

     /**
     * 請求路徑是否在白名單中
     *
     * @return bool
     */
    private function checkPathWhiteList()
    {
      $path = ltrim(self::$request->getPathInfo(), '/');
      if (!$path || !$this->pathWhiteList || !is_array($this->pathWhiteList)) {
        return false;
      }
      foreach ($this->pathWhiteList as $item) {
        if (preg_match("/$item/", $path)) {
          return true;
        }
      }

      return false;
    }
  }

檢測方法:

?php
  namespace Tests\Unit;

  use App\Facades\Services\WebDefenderService;
  use Illuminate\Http\Request;
  use Tests\TestCase;

  class WebDefenderTest extends TestCase
  {
     /**
     * 檢測白名單路徑
     * @dataProvider additionProviderPathWhiteList
     *
     * @param $pathProperty
     * @param $request
     * @param $result
     *
     * @throws \ReflectionException
     */
    public function testCheckPathWhiteList($pathProperty, $request, $result)
    {
      $reflectedClass = new \ReflectionClass('App\Facades\Services\WebDefenderService');

      $webDefenderService   = new WebDefenderService();
      $reflectedPathWhiteList = $reflectedClass->getProperty('pathWhiteList');
      $reflectedPathWhiteList->setAccessible(true);
      $reflectedPathWhiteList->setValue($webDefenderService, $pathProperty);

      $reflectedRequest = $reflectedClass->getProperty('request');
      $reflectedRequest->setAccessible(true);
      $reflectedRequest->setValue($request);

      $reflectedMethod = $reflectedClass->getMethod('checkPathWhiteList');
      $reflectedMethod->setAccessible(true);
      $this->assertEquals($result, $reflectedMethod->invoke($webDefenderService));
    }

    public function additionProviderPathWhiteList()
    {
      $allPath      = ['.*'];
      $checkPath     = ['^auth\/(.*)'];
      $authSendSmsRequest = new Request([], [], [], [], [], ['HTTP_HOST' => 'api.dev.com', 'REQUEST_URI' => '/auth/sendSms']);
      $indexRequest    = new Request([], [], [], [], [], ['HTTP_HOST' => 'api.dev.com', 'REQUEST_URI' => '/']);
      $noMatchRequest   = new Request([], [], [], [], [], ['HTTP_HOST' => 'api.dev.com', 'REQUEST_URI' => '/product/sendSms']);

      return [
        'index'        => [[], $authSendSmsRequest, false],
        'no request'     => [$allPath, $indexRequest, false],
        'all request'     => [$allPath, $authSendSmsRequest, true],
        'check auth sms'   => [$checkPath, $authSendSmsRequest, true],
        'check path no match' => [$checkPath, $noMatchRequest, false]
      ];
    }
  }

5. 代碼覆蓋率

使用--coverage-html導出的報告含有類與特質覆蓋率、行覆蓋率、函數與方法覆蓋率。可查看當前單元測試覆蓋的范圍。例如輸出WebDefenderTest的代碼覆蓋率到桌面(phpunit tests/unit/WebDefenderTest --coverage-html ~/Desktop/test)

6. 指定代碼覆蓋率報告要包含哪些文件

在配置文件(phpunit.xml)里設置whitelist中的processUncoveredFilesFromWhitelist=true, 設置目錄用directory>標簽,設置文件用file>標簽。例如指定app/Services目錄下的所有文件和app/Facades/Services/WebDefenderService.php在報告中。

示例代碼:

 ?xml version="1.0" encoding="UTF-8"?>
  phpunit backupGlobals="false"
       backupStaticAttributes="false"
       bootstrap="tests/bootstrap.php"
       colors="true"
       convertErrorsToExceptions="true"
       convertNoticesToExceptions="true"
       convertWarningsToExceptions="true"
       processIsolation="false"
       stopOnFailure="false">
    testsuites>
      testsuite name="Unit">
        directory suffix="Test.php">./tests/Unit/directory>
      /testsuite>

      testsuite name="Feature">
        directory suffix="Test.php">./tests/Feature/directory>
      /testsuite>
    /testsuites>
    filter>
      whitelist processUncoveredFilesFromWhitelist="true">
        directory suffix=".php">./app/Services/directory>
        file>./app/Facades/Services/WebDefenderService.php/file>
      /whitelist>
    /filter>
    php>
      server name="APP_ENV" value="local"/>
      server name="BCRYPT_ROUNDS" value="4"/>
      server name="CACHE_DRIVER" value="credis"/>
      server name="MAIL_DRIVER" value="array"/>
      server name="QUEUE_CONNECTION" value="sync"/>
      server name="SESSION_DRIVER" value="array"/>
      server name="APP_CONFIG_CACHE" value="bootstrap/cache/config.phpunit.php"/>
      server name="APP_SERVICES_CACHE" value="bootstrap/cache/services.phpunit.php"/>
      server name="APP_PACKAGES_CACHE" value="bootstrap/cache/packages.phpunit.php"/>
      server name="APP_ROUTES_CACHE" value="bootstrap/cache/routes.phpunit.php"/>
      server name="APP_EVENTS_CACHE" value="bootstrap/cache/events.phpunit.php"/>
    /php>
  /phpunit>

7. 參考文檔

PHPUnit官方文檔 https://phpunit.readthedocs.io/zh_CN/latest/index.html
反射類 https://www.php.net/manual/en/class.reflectionclass.php
反射方法 https://www.php.net/manual/en/class.reflectionmethod.php

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • 詳解Yaf框架PHPUnit集成測試方法
  • PHP單元測試配置與使用方法詳解
  • PHP使用phpunit進行單元測試示例
  • php使用yield對性能提升的測試實例分析
  • 高質量PHP代碼的50個實用技巧必備(下)
  • 高質量PHP代碼的50個實用技巧必備(上)
  • 很讓人受教的 提高php代碼質量36計
  • 寫出高質量的PHP程序
  • 淺談如何提高PHP代碼質量之端到端集成測試

標簽:大同 平涼 深圳 內江 江門 石嘴山 雙鴨山 駐馬店

巨人網絡通訊聲明:本文標題《PHPUnit + Laravel單元測試常用技能》,本文關鍵詞  PHPUnit,Laravel,單元,測試,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《PHPUnit + Laravel單元測試常用技能》相關的同類信息!
  • 本頁收集關于PHPUnit + Laravel單元測試常用技能的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    欧美日韩综合不卡| 日韩精品色哟哟| 国产精品美女久久久久久久 | 99久久免费国产| 在线观看91av| 午夜天堂影视香蕉久久| 91黄色免费网站| 日本一区二区在线不卡| 国产一区二区不卡| 精品国产sm最大网站| 国产mv日韩mv欧美| 欧美高清在线精品一区| 成人午夜伦理影院| 亚洲激情图片一区| 91精品婷婷国产综合久久 | 国产成人精品免费在线| 国产精品美女久久久久久久久 | 久久午夜免费电影| 久久 天天综合| 中文字幕成人av| 日本精品视频一区二区| 天天操天天色综合| 精品久久久网站| 成人午夜免费视频| 五月激情综合婷婷| 久久久精品tv| 99re热视频这里只精品| 水野朝阳av一区二区三区| 精品日韩99亚洲| 91国产福利在线| 韩国欧美一区二区| 国产精品入口麻豆九色| 欧美伊人久久久久久久久影院| 久久精品久久综合| 国产欧美日韩精品a在线观看| 在线观看日韩av先锋影音电影院| 五月婷婷激情综合| 亚洲欧洲另类国产综合| 91精品午夜视频| 91免费观看国产| 久久99国产精品麻豆| 国产精品毛片久久久久久| 亚洲精品一区二区三区在线观看| 成人性色生活片| 日本不卡一二三| 亚洲欧美色一区| 国产精品久久毛片| 久久亚洲欧美国产精品乐播 | 国产精品久久久久久久久免费桃花 | 日韩欧美色电影| 日本福利一区二区| 96av麻豆蜜桃一区二区| 国产一区二区久久| 国内精品免费在线观看| 久久激情五月婷婷| 男女激情视频一区| 日韩福利电影在线| 日本亚洲三级在线| 五月天视频一区| 视频一区在线视频| 三级影片在线观看欧美日韩一区二区| 亚洲精品国产视频| 一区二区三区在线视频观看| 香蕉乱码成人久久天堂爱免费| 久久69国产一区二区蜜臀| 免播放器亚洲一区| 亚洲精品日韩一| 亚洲欧美日韩国产手机在线| 精品国产露脸精彩对白| 日韩一区二区精品葵司在线| 欧美日韩久久久| 欧美在线啊v一区| 一本大道av伊人久久综合| 国产美女娇喘av呻吟久久| 国产一区二区在线看| 国产一区二区福利视频| 国产成a人亚洲精品| 国产福利视频一区二区三区| 国产成人免费av在线| 97se亚洲国产综合在线| 欧美伊人久久大香线蕉综合69| 97成人超碰视| 91麻豆精品91久久久久同性| 日韩免费视频一区| 久久久www免费人成精品| 国产精品嫩草99a| 亚洲一区国产视频| 亚洲综合免费观看高清完整版在线| 久久精品亚洲麻豆av一区二区| 国产欧美精品在线观看| 中文字幕在线一区| 久久一夜天堂av一区二区三区| 国产日韩精品一区二区三区| 久久欧美一区二区| 欧美国产日韩精品免费观看| 亚洲欧美福利一区二区| 日韩1区2区3区| 99久久久久久| 91精品国产综合久久福利软件| 欧美成人一级视频| 欧美国产欧美综合| 日韩av不卡一区二区| 东方欧美亚洲色图在线| 欧美精品色一区二区三区| 日本一区二区动态图| 香蕉久久夜色精品国产使用方法| 久久99精品久久久| 91激情在线视频| 久久久亚洲精华液精华液精华液| 亚洲免费在线电影| 麻豆精品久久精品色综合| 91在线精品秘密一区二区| 日韩欧美成人一区| 亚洲在线视频免费观看| 成人激情电影免费在线观看| 欧美一区二区精品| 亚洲国产精品久久一线不卡| 国产91对白在线观看九色| 91麻豆精品国产自产在线观看一区| 国产精品私人自拍| 国产毛片一区二区| 欧美成人一级视频| 日本一不卡视频| 911精品产国品一二三产区| 成人免费视频在线观看| 国产成人av网站| 久久综合给合久久狠狠狠97色69| 日本午夜精品一区二区三区电影 | 精品一区二区三区久久久| 色8久久精品久久久久久蜜| 中文字幕制服丝袜成人av| 国产精品一区在线观看你懂的| 欧美日韩国产片| 亚洲成人综合网站| 色成人在线视频| 亚洲日本va午夜在线影院| 成人在线视频一区| 国产精品午夜春色av| 国产白丝精品91爽爽久久| 久久久久99精品国产片| 高清视频一区二区| 国产精品免费人成网站| 成人h版在线观看| 亚洲欧洲日本在线| 91激情在线视频| 亚洲成av人影院在线观看网| 欧美老肥妇做.爰bbww| 蜜桃视频在线观看一区二区| 日韩一区二区不卡| 国产一区二区三区四| 国产亚洲精品aa| 97久久超碰国产精品电影| 亚洲激情男女视频| 欧美老女人第四色| 韩国av一区二区| 中文字幕av一区二区三区| 国产精品77777| 国产精品美女久久久久aⅴ| 在线这里只有精品| 免费在线视频一区| 亚洲国产电影在线观看| www.欧美日韩| 五月天久久比比资源色| 精品免费视频.| 91玉足脚交白嫩脚丫在线播放| 亚洲毛片av在线| 色婷婷久久久久swag精品| 亚洲精品视频在线观看网站| 777a∨成人精品桃花网| 国产精品一线二线三线| 亚洲影视在线观看| 日韩欧美国产麻豆| 91在线视频18| 毛片av中文字幕一区二区| 亚洲人成伊人成综合网小说| 日韩欧美精品在线视频| 国产精品一区二区不卡| 亚洲欧洲综合另类| 日韩午夜中文字幕| 99精品视频在线播放观看| 三级不卡在线观看| 久久久久久久久久久99999| 欧美色视频一区| av一二三不卡影片| 精油按摩中文字幕久久| 亚洲最新在线观看| 久久久久88色偷偷免费| 欧美日韩成人一区| 91丨九色丨黑人外教| 国产一区在线精品| 亚洲福利视频导航| 一色屋精品亚洲香蕉网站| 日韩美女视频在线| 91免费视频网址| 国产在线国偷精品免费看| 三级在线观看一区二区| 国产精品进线69影院| 久久人人爽爽爽人久久久| 日韩美女一区二区三区四区| 在线视频国内一区二区|