之前错误认为程序编写完成后测试项目直接手工测试即可,编写测试用例只是花费时间,没有多大的用处。
那为什么要写单元/功能测试?
手工测试存在测试时间长还会漏测,项目越庞大,耗费的时间越多,漏测的可能性越大。比如你的某个功能代码存在复用,在依次功能修改后当前功能块正常,却漏测了其他模块内是否正常。没人可以避免不漏测,如何才能快速且准确的测出所有功能模块是否work?测试用例就派上用场了
编写测试用例/tests/ExampleTest.php
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
//访问默认首页文档中是否有 Laravel 5 关键字
$this->visit('/')
->see('Laravel 5');
//模拟点击首页About Us的a标签是否跳转到/accessor/index
$this->visit('/')
->click("About Us")
->seePageIs("/accessor/index");
//模拟点击Register按钮表单提交后跳转到/dashboard页面
$this->visit("/")
->type("Taylor",'username')
->check('terms')
->press("Register")
->seePageIs("/dashboard");
//模拟post提交后检查json返回是否含有指定的字段和值
$this->post("/user0",['name'=>'Sally'])
->seeJson([
'created'=>true
]);
//验证完全匹配的JSON
$this->post('/user1',['name'=>'Sally'])
->seeJsonEquals([
'created'=>true
]);
//验证JSON结构一致,如果存在多余的字段,seeJsonStructure不会报错
$this->get("/user2")
->seeJsonStructure([
'name',
'pet'=>[
'name',
'age'
]
]);
//每一个列表里至少拥有id,name和email 属性
$this->get('/user3')
->seeJsonStructure([
'*'=>[
'id','name','age'
]
]);
$this->get('/user4')
->seeJsonStructure([
'id','name','email','pets'=>[
'*'=>[
'name','age'
]
]
]);
//Sessions和认证
$this->withSession([
'foo'=>'bar'
])->visit('/user5')
->see("true");
$user=factory(App\User::class)->create();
$this->actingAs($user)
->withSession(['foo'=>'bar'])
->visit('/user6')
->see("Hello, ".$user->name);
}
}
控制器 app/Http/Controller/UserController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use Validator;
use DB;
class UserController extends Controller
{
public function index(){
}
public function dashboard(){
return '';
}
public function register(){
return redirect('/dashboard');
}
public function user0(){
return ['created'=>true,'abc'=>123];
}
public function user1(){
return ['created'=>true];
}
public function user2(){
return['name'=>1,'pet'=>['name'=>2,'age'=>1,'gg'=>2]];
}
public function user3(){
return [['name'=>1,'age'=>2,'id'=>3],['name'=>4,'id'=>5,'age'=>6,'s']];
}
public function user4(){
return ['id'=>1,'name'=>2,'email'=>3,'pets'=>[['name'=>5,'age'=>6]]];
}
public function user5(){
if(session('foo')=='bar'){
return "true";
}
return "false";
}
public function user6(){
$user=Auth::user();
return "Hello, ".$user->name;
}
}
编写路由app/Http/routes.php
Route::get("/accessor/index","UserController@index");
Route::post("/register","UserController@register");
Route::get("/dashboard","UserController@dashboard");
Route::post("/user0","UserController@user0");
Route::post("/user1","UserController@user1");
Route::get("/user2","UserController@user2");
Route::get("/user3","UserController@user3");
Route::get("/user4","UserController@user4");
Route::get("/user5","UserController@user5");
Route::get("/user6","UserController@user6");
编写测试页面 home.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Laravel</title>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
<style>
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
width: 100%;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
}
</style>
</head>
<body>
<div class="container">
<div class="content">
<div class="title">Laravel 5</div>
<a href="/accessor/index">About Us</a>
<form action="/register" method="POST">
<input type="hidden" name="_token" value="{{csrf_token()}}"/>
<div>
Name:<input type="text" name="username"/>
</div>
<div>
<input type="checkbox" value="yes" name="terms"> Accept Terms
</div>
<div>
<input type="submit" value="Register">
</div>
</form>
</div>
</div>
</body>
</html>
运行测试用例
#进入项目根目录
ln -s ./vendor/bin/phpunit ./phpunit
#运行测试用例
php ./phpunit
#没有报错说明定义的所有测试用例正常