基於 Laravel 框架的 phpunit 單元測試爬坑記錄
1、單元測試的目錄結構
測試檔案一般位於專案根目錄下的 tests 資料夾或者 models 下的專案中的 tests 資料夾。
在命令列中執行以下命令:
php artisan make:test DemoTest //可以生成 DemoTest.php 測試檔案
//這種方式生成的測試檔案建立在專案根目錄下的 tests/Feature
> - 在命令列中執行以下命令:
phpunit //會執行所有 test 方法`
phpunit tests/Feature/BackendTest.php //會執行所有 BackendTest.php 裡的 test 方法
---
2、測試程式碼編寫
1. 帶入引數請求訪問介面
1. 獲取返回值斷言
舉個例子:
---
class AccountTest extends TestCase
//所有測試類必須基於TestCase
{
/**
- 測試使用者資訊詳情頁介面
- @return mixed
*/
//所有測試方法命名,必須以 test 小寫開頭命名
//(或者在註釋中寫明標註 @test )
public function testuserinfo_detail()
{
$response = $this->get('http://ideabuy.xin.cn/api/userinfo-detail',$this->authHeader)
// $this->assertEquals('ture',$response->getcontent());
//當下面斷言失敗時,將這行程式碼取消註釋,將下面註釋,上面程式碼最後加上分號,再次執行,即可看到報錯具體資訊。
->assertJsonFragment([
'msg'=>'查詢成功',
//斷言返回的JSON值中包含一個 msg:‘查詢成功’ 的物件
]);
}
}
介紹幾個介面訪問方式:
- GET 請求
get($uri, array $headers = []);
- POST 請求
post($uri, array $data = [], array $headers = []);
- JSON 請求
json('POST', $uri, $data, $headers);
- CALL 請求
call('PUT', $uri, $data, [], [], $server);
獲取介面返回值方法:
$response->getcontent();
$response->getOriginalContent();
獲取介面返回值方法:
簡單列幾個常見的斷言方法,具體更多的斷言方法--點此跳轉連結
- $this->assertJsonFragment($params)
// 判斷返回的JSON數值裡是否包含$params
當返回值有 json 格式的 msg 資訊
$this->assertJsonFragment([
'msg'=>'頭像修改成功',
]);
- $this->assertJsonStructure($params);
// 判斷返回的JSON資料裡是否包含$params資料結構
當返回值中不存在 msg 時(例如使用者詳情查出來基本為 data 時)可以用來判斷是否存在資料。
$this->assertJsonStructure([
'data'=>[],
]);
- $this->assertEquals(1,$params);
// 斷返回值是否與$params相同
$this->assertEquals(1, $result['code']);
- assertResponseOk();
// 斷言客戶端返回的響應狀態碼是否是200
$this->assertResponseOk();
2、測試程式碼編寫
由於大部分介面都做了使用者登入的判斷,所以在對介面進行測試的時候需要帶上使用者登入的資訊(token+版本資訊)。
- 獲取token的時候(即模擬登陸的時候--userlogin方法)如果報 ==data== 錯誤,先檢查一下本地環境是不是需要全拼路由才能訪問介面。
例:
$response = $this->get('http://ideabuy.xin.cn/backend/constype-list', $this->authHeader)
- 如果token可以列印的情況下,還報錯。檢查一下 setup 方法是否新增了重新整理語句。
即:
例:
$this->refreshApplication();
- 下面的程式碼舉了一個userlogin登入的操作,backend登入可以仿照下面操作,在 Common 裡的方法中新增一個adminlogin,然後繼承這個類去呼叫登入後的token
嗯,我還是貼程式碼吧:
==路徑:test/common/ApiTestCase.php==
public function adminLogin($params = [])
{
$response = $this->post(
'http://ideabuy.xin.cn/backend/admin-login',
$params
);
$admins = $response->getOriginalContent();
return $admins;
}
==路徑:test/BackendTest.php==
public function setUp()
{
parent::setUp();
$this->params = $this->readyApiParams();
$admin = $this->adminLogin($this->params['login']);
$this->admin = $admin;
$this->authHeader = $this->headers($admin);
$this->refreshApplication();
}
- 接下來在你寫的test方法裡的頭部資訊就可以直接$this->authHeader 進行呼叫了!
類似於這樣:$response = $this->get('http://ideabuy.xin.cn/backend/order-detail?order_id=282', $this->authHeader)
附上登入用例程式碼:
==路徑:test/common/ApiTestCase.php==
<?php
namespace Modules\Api\Tests\Common;
use Tests\TestCase;
/**
* Class ApiTestCase
* @package Modules\Api\Tests\Common
*/
class ApiTestCase extends TestCase
{
/**
* User login
* @param array $params
* @return mixed
*/
public function userLogin($params = [])
{
$response = $this->post(
#路由看個人環境配置是否需要加上 http://ideabuy.xin.cn
'http://ideabuy.xin.cn/api/user-login',
$params,
#呼叫下面拼接token的方法
$this->headers()
);
$users = $response->getOriginalContent();
return $users;
}
/**
* Setting request header
* @param null $user
* @param array $addition
* @return array
*/
protected function headers($user = null, $addition = [])
{
#新增版本號頭部資訊
$headers = ['Accept' => 'application/vnd.ideabuy.v1+json'];
#拼接 token
if (!is_null($user)) {
$headers['Authorization'] = 'Bearer '.$user['data']['token'];
}
if($addition){
$headers = array_merge($headers,$addition);
}
return $headers;
}
}
==路徑:test/AccountTest.php==
<?php
namespace Modules\Api\Tests;
use Modules\Api\Tests\Common\ApiTestCase;
class AccountTest extends ApiTestCase
{
public $authHeader;
public $params;
public $data;
public $user;
/**
* ready for data & params
*/
public function setUp()
{
#每個test方法之前都會呼叫一次這個方法
parent::setUp();
$this->params = $this->readyApiParams();
/** Get auth info include token */
#呼叫使用者登入的操作
$user = $this->userLogin($this->params['login']);
$this->user = $user;
#獲取使用者 token
$this->authHeader = $this->headers($user);
#重新整理應用。該操作由TestCase的setup()方法自動呼叫,不然會使用過期的token
$this->refreshApplication();
}
/**
* Ready for test params
*/
protected function readyApiParams()
{
#這個方法用來放test裡需要的引數
$params = [];
/** login params for test **/
$login = [
'user_mobile' => '13777979098',
'user_password' => 'a12345678'
];
$params['login'] = $login;
/** register user params for test **/
$register = [
'user_mobile' => '13777979098',
'user_password' => 'a12345678',
'confirm_password' => 'a12345678',
'code' => '1234'
];
$params['register'] = $register;
/** setting user paypassword params for test **/
$payPassword = ['pay_password' => 'b11111111'];
$params['payPassword'] = $payPassword;
return $params;
}
/**
* Clean test data
*/
protected function cleanData()
{
//todo logic data
//Artisan::call('migrate:reset');
}
/**
* this is case for user login
*/
public function testUserLogin()
{
$this->assertEquals(1, $this->user['code']);
}
/**
* This is case for setting pay password
* @test
*/
public function SetPayPassword()
{
$response = $this->post(
'http://ideabuy.xin.cn/api/user-setpaypwd',
$this->params['payPassword'],
#獲取token
$this->authHeader
);
$result = $response->getOriginalContent();
#getOriginalContent()是將返回值轉成陣列,getcontent()是直接將物件返回
$this->assertEquals(1, $result['code']);
}
/**
* Drop something test data
*/
public function tearDown()
{
$this->cleanData();
parent::tearDown();
}
}
歡迎大家給意見和補充。
本作品採用《CC 協議》,轉載必須註明作者和本文連結