国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - PHPUnit + Laravel單元測試常用技能

PHPUnit + Laravel單元測試常用技能

2021-09-16 15:48小青蛙 PHP教程

這篇文章主要介紹了PHPUnit + Laravel單元測試常用技能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

1. 數據供給器

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

示例代碼:

  1. <?php
  2. namespace Tests\Unit;
  3.  
  4. use App\Services\ClientService;
  5. use Tests\TestCase;
  6.  
  7. class ClientServiceTest extends TestCase
  8. {
  9. /**
  10. * @dataProvider addProviderAppUpdateData
  11. *
  12. * @param $appId
  13. * @param $result
  14. */
  15. public function testAppUpdateData($appId, $result)
  16. {
  17. $data = (new ClientService($appId))->appUpdateData();
  18.  
  19. $this->assertTrue(count(array_intersect_assoc($data, $result)) == count($result));
  20. }
  21.  
  22. public function addProviderAppUpdateData()
  23. {
  24. return [
  25. 'null' => [null, ['status' => 0, 'isIOS' => false, 'latest_version' => 'V']],
  26. 'error app id' => ['sdas123123', ['status' => 0, 'isIOS' => false, 'latest_version' => 'V']],
  27. 'android force update' => ['bx7_3.3.5_120', ['status' => 0, 'isIOS' => false]],
  28. 'ios force update' => ['apple_3.3.2_117', ['status' => 1, 'isIOS' => true]],
  29. 'android soft update' => ['sanxing_3.3.2_117', ['status' => 2, 'isIOS' => false]],
  30. 'ios soft update' => ['apple_3.3.3_118', ['status' => 2, 'isIOS' => true]],
  31. 'android normal' => ['fhqd_3.3.6_121', ['status' => 1, 'isIOS' => false]],
  32. 'ios normal' => ['apple_3.3.5_120', ['status' => 1, 'isIOS' => true]],
  33. 'h5' => ['h5_3.3.3', ['status' => 1, 'isIOS' => false]]
  34. ];
  35. }
  36. }

斷言成功結果:

PHPUnit + Laravel單元測試常用技能

2. 斷言方法

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

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

示例代碼:

  1. <?php
  2. namespace Tests\Unit;
  3.  
  4. use App\Models\ApiApp;
  5. use App\Services\SystemConfigService;
  6. use Tests\TestCase;
  7.  
  8. class SystemConfigServiceTest extends TestCase
  9. {
  10. /**
  11. * @dataProvider additionProviderGetLatestUpdateAppApi
  12. *
  13. * @param $appType
  14. */
  15. public function testGetLatestUpdateAppApi($appType)
  16. {
  17. $result = SystemConfigService::getLatestUpdateAppApi($appType);
  18. $this->assertThat($result, $this->logicalOr($this->isNull(), $this->isInstanceOf(ApiApp::class)));
  19. }
  20.  
  21. public function additionProviderGetLatestUpdateAppApi()
  22. {
  23. return [
  24. 'apple' => [1],
  25. 'android' => [2],
  26. 'null' => [9999]
  27. ];
  28. }
  29. }

斷言成功結果:

PHPUnit + Laravel單元測試常用技能

3. 對異常進行測試

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

示例代碼:

  1. <?php
  2. namespace Tests\Unit;
  3.  
  4. use App\Services\UserSecurityService;
  5. use Illuminate\Support\Facades\Cache;
  6. use Tests\TestCase;
  7.  
  8. class UserSecurityServiceTest extends TestCase
  9. {
  10. public static $userId = 4;
  11.  
  12. /**
  13. * 設備鎖檢測
  14. * @throws \App\Exceptions\UserException
  15. */
  16. public function testDeviceCheckLock()
  17. {
  18. $this->expectExceptionCode(3026);
  19. Cache::put('device-login-error-account-', '1,2,3,4,5', 300);
  20. UserSecurityService::$request = null;
  21. UserSecurityService::$udid = null;
  22. UserSecurityService::deviceCheck(self::$userId);
  23. }
  24. }

斷言成功結果:

PHPUnit + Laravel單元測試常用技能

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

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

示例代碼:

被檢測代碼:

  1. namespace App\Facades\Services;
  2.  
  3. /**
  4. * Class WebDefender
  5. */
  6. class WebDefenderService extends BaseService
  7. {
  8. //ip白名單
  9. private $ipWhiteList = [
  10. '10.*',
  11. '172.18.*',
  12. '127.0.0.1'
  13. ];
  14.  
  15. /**
  16. * ip是否在白名單中
  17. *
  18. * @param string $ip
  19. *
  20. * @return bool
  21. */
  22. private function checkIPWhiteList($ip)
  23. {
  24. if (!$this->ipWhiteList || !is_array($this->ipWhiteList)) {
  25. return false;
  26. }
  27. foreach ($this->ipWhiteList as $item) {
  28. if (preg_match("/{$item}/", $ip)) {
  29. return true;
  30. }
  31. }
  32.  
  33. return false;
  34. }
  35. }

檢測方法:

  1. <?php
  2.  
  3. namespace Tests\Unit;
  4.  
  5. use App\Facades\Services\WebDefenderService;
  6. use Tests\TestCase;
  7.  
  8. class WebDefenderTest extends TestCase
  9. {
  10. /**
  11. * 測試IP白名單
  12. * @dataProvider additionProviderIp
  13. *
  14. * @param $ip
  15. * @param $result
  16. *
  17. * @throws \ReflectionException
  18. */
  19. public function testIPWhite($ip, $result)
  20. {
  21. $checkIPWhiteList = new \ReflectionMethod(WebDefenderService::class, 'checkIPWhiteList');
  22. $checkIPWhiteList->setAccessible(true);
  23. $this->assertEquals($result, $checkIPWhiteList->invokeArgs(new WebDefenderService(), [$ip]));
  24. }
  25.  
  26. public function additionProviderIp()
  27. {
  28. return [
  29. '10 ip' => ['10.1.1.7', true],
  30. '172 ip' => ['172.18.2.5', true],
  31. '127 ip' => ['127.0.0.1', true],
  32. '192 ip' => ['192.168.0.1', false]
  33. ];
  34. }
  35. }

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

示例代碼:

被檢測代碼:

  1. <?php
  2. namespace App\Facades\Services;
  3.  
  4. use App\Exceptions\ExceptionCode;
  5. use App\Exceptions\UserException;
  6. use Illuminate\Support\Facades\Cache;
  7.  
  8. /**
  9. * CC攻擊防御器
  10. * Class WebDefender
  11. */
  12. class WebDefenderService extends BaseService
  13. {
  14. //路徑白名單(正則)
  15. private $pathWhiteList = [
  16. //'^auth\/(.*)',
  17. ];
  18.  
  19. private static $request = null;
  20.  
  21. /**
  22. * 請求路徑是否在白名單中
  23. *
  24. * @return bool
  25. */
  26. private function checkPathWhiteList()
  27. {
  28. $path = ltrim(self::$request->getPathInfo(), '/');
  29. if (!$path || !$this->pathWhiteList || !is_array($this->pathWhiteList)) {
  30. return false;
  31. }
  32. foreach ($this->pathWhiteList as $item) {
  33. if (preg_match("/$item/", $path)) {
  34. return true;
  35. }
  36. }
  37.  
  38. return false;
  39. }
  40. }

檢測方法:

  1. <?php
  2. namespace Tests\Unit;
  3.  
  4. use App\Facades\Services\WebDefenderService;
  5. use Illuminate\Http\Request;
  6. use Tests\TestCase;
  7.  
  8. class WebDefenderTest extends TestCase
  9. {
  10. /**
  11. * 檢測白名單路徑
  12. * @dataProvider additionProviderPathWhiteList
  13. *
  14. * @param $pathProperty
  15. * @param $request
  16. * @param $result
  17. *
  18. * @throws \ReflectionException
  19. */
  20. public function testCheckPathWhiteList($pathProperty, $request, $result)
  21. {
  22. $reflectedClass = new \ReflectionClass('App\Facades\Services\WebDefenderService');
  23.  
  24. $webDefenderService = new WebDefenderService();
  25. $reflectedPathWhiteList = $reflectedClass->getProperty('pathWhiteList');
  26. $reflectedPathWhiteList->setAccessible(true);
  27. $reflectedPathWhiteList->setValue($webDefenderService, $pathProperty);
  28.  
  29. $reflectedRequest = $reflectedClass->getProperty('request');
  30. $reflectedRequest->setAccessible(true);
  31. $reflectedRequest->setValue($request);
  32.  
  33. $reflectedMethod = $reflectedClass->getMethod('checkPathWhiteList');
  34. $reflectedMethod->setAccessible(true);
  35. $this->assertEquals($result, $reflectedMethod->invoke($webDefenderService));
  36. }
  37.  
  38. public function additionProviderPathWhiteList()
  39. {
  40. $allPath = ['.*'];
  41. $checkPath = ['^auth\/(.*)'];
  42. $authSendSmsRequest = new Request([], [], [], [], [], ['HTTP_HOST' => 'api.dev.com', 'REQUEST_URI' => '/auth/sendSms']);
  43. $indexRequest = new Request([], [], [], [], [], ['HTTP_HOST' => 'api.dev.com', 'REQUEST_URI' => '/']);
  44. $noMatchRequest = new Request([], [], [], [], [], ['HTTP_HOST' => 'api.dev.com', 'REQUEST_URI' => '/product/sendSms']);
  45.  
  46. return [
  47. 'index' => [[], $authSendSmsRequest, false],
  48. 'no request' => [$allPath, $indexRequest, false],
  49. 'all request' => [$allPath, $authSendSmsRequest, true],
  50. 'check auth sms' => [$checkPath, $authSendSmsRequest, true],
  51. 'check path no match' => [$checkPath, $noMatchRequest, false]
  52. ];
  53. }
  54. }

5. 代碼覆蓋率

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

PHPUnit + Laravel單元測試常用技能

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

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

示例代碼:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <phpunit backupGlobals="false"
  3. backupStaticAttributes="false"
  4. bootstrap="tests/bootstrap.php"
  5. colors="true"
  6. convertErrorsToExceptions="true"
  7. convertNoticesToExceptions="true"
  8. convertWarningsToExceptions="true"
  9. processIsolation="false"
  10. stopOnFailure="false">
  11. <testsuites>
  12. <testsuite name="Unit">
  13. <directory suffix="Test.php">./tests/Unit</directory>
  14. </testsuite>
  15.  
  16. <testsuite name="Feature">
  17. <directory suffix="Test.php">./tests/Feature</directory>
  18. </testsuite>
  19. </testsuites>
  20. <filter>
  21. <whitelist processUncoveredFilesFromWhitelist="true">
  22. <directory suffix=".php">./app/Services</directory>
  23. <file>./app/Facades/Services/WebDefenderService.php</file>
  24. </whitelist>
  25. </filter>
  26. <php>
  27. <server name="APP_ENV" value="local"/>
  28. <server name="BCRYPT_ROUNDS" value="4"/>
  29. <server name="CACHE_DRIVER" value="credis"/>
  30. <server name="MAIL_DRIVER" value="array"/>
  31. <server name="QUEUE_CONNECTION" value="sync"/>
  32. <server name="SESSION_DRIVER" value="array"/>
  33. <server name="APP_CONFIG_CACHE" value="bootstrap/cache/config.phpunit.php"/>
  34. <server name="APP_SERVICES_CACHE" value="bootstrap/cache/services.phpunit.php"/>
  35. <server name="APP_PACKAGES_CACHE" value="bootstrap/cache/packages.phpunit.php"/>
  36. <server name="APP_ROUTES_CACHE" value="bootstrap/cache/routes.phpunit.php"/>
  37. <server name="APP_EVENTS_CACHE" value="bootstrap/cache/events.phpunit.php"/>
  38. </php>
  39. </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

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

原文鏈接:https://segmentfault.com/a/1190000020925586

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 手机av在线 | 精品国精品国产自在久不卡 | 国产精品一二 | 精品中文字幕一区 | 天天躁人人躁人人躁狂躁 | 日韩在线中文字幕 | 国产高清在线精品一区二区三区 | 久久综合久久综合久久综合 | 日韩一区免费在线观看 | 亚洲人成在线播放 | 久久精品99国产精品日本 | 久在线草 | 在线观看免费视频黄 | 欧美二区三区 | 玖玖综合网 | 美女视频一区二区三区 | 在线观看成人国产 | 九九综合九九 | 国产精品免费高清 | 在线一级片 | 国产亚洲精品美女久久久久久久久久 | 国产高清一区二区三区 | 日本高清一区 | 日日躁夜夜躁狠狠躁 | 久色视频在线观看 | 中文字幕欧美日韩 | 国产视频一区二区视频 | 国产麻豆乱码精品一区二区三区 | 国产精品视频一二三区 | 一本久久a久久精品亚洲 | 午夜视频在线免费观看 | 国产成人久久一区二区三区 | www久| 国产在线中文字幕 | 欧美高清一区 | 三区影院| 午夜成人在线视频 | 黄片毛片免费观看 | 国产精品毛片久久久久久久 | 国产v日产∨综合v精品视频 | 国产999精品久久久影片官网 |