基于 Laravel 框架的 phpunit 单元测试爬坑记录
基于 Laravel 框架的 phpunit 单元测试爬坑记录
单元测试的目录结构
- 测试文件一般位于项目根目录下的 tests 文件夹或者 models 下的项目中的 tests 文件夹。
- 在命令行中执行以下命令:
这种方式生成的测试文件创建在项目根目录下的 tests/Feature
php artisan make:test DemoTest //可以生成 DemoTest.php 测试文件
在命令行中执行以下命令:
执行所有 test 方法
phpunit
执行所有 BackendTest.php 里的 test 方法
phpunit tests/Feature/BackendTest.php
测试代码编写
- 带入参数请求访问接口
- 获取返回值断言
举个栗子:
class AccountTest extends TestCase
//所有测试类必须基于TestCase
{
/**
* 测试用户信息详情页接口
* 所有测试方法命名,必须以 test 小写开头命名
* 或者在注释中写明标注 @test
* @return mixed
*/
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();
简单列几个常见的断言方法,具体更多的断言方法–点此跳转链接
assertJsonFragment
andassertJsonFragment
判断返回的JSON数值里是否包含$params
当返回值有 json 格式的 msg 信息
$this->assertJsonFragment($params) ;
$this->assertJsonFragment([ 'msg' => '头像修改成功']);
assertJsonStructure
andassertJsonStructure
判断返回的JSON数据里是否包含$params数据结构
当返回值中不存在 msg 时(例如用户详情查出来基本为 data 时)可以用来判断是否存在数据。
$this->assertJsonStructure($params);
$this->assertJsonStructure(['data'=>[]]);
assertEquals
断返回值是否与$params相同
$this->assertEquals(1, $result['code']);
assertResponseOk
断言客户端返回的响应状态码是否是200
$this->assertResponseOk();
token+版本信息
由于大部分接口都做了用户登录的判断,所以在对接口进行测试的时候需要带上用户登录的信息(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 协议》,转载必须注明作者和本文链接
文档:基于 Laravel 框架的 phpunit 单元测试...
链接:http://note.youdao.com/noteshare?id=606bd3...
内容不错, 格式有点乱
可以单独执行测试某个方法或者接口吗? phpunit tests/Feature/BackendTest.php 这个是执行test文件里面所有方法