Laravel 测试教程
迁移文件
修改 database/migrations/2014_10_12_000000_create_users_table.php
。
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
// following table is storing the relationship between users
// user_id is following follow_user_id
Schema::create('following', function (Blueprint $table) {
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('follow_user_id')->unsigned()->index();
$table->foreign('follow_user_id')->references('id')->on('users')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('following');
Schema::dropIfExists('users');
}
}
执行迁移
php artisan migrate
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
User Model
修改 app/User.php
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function follows(User $user)
{
$this->following()->attach($user->id);
}
public function unfollows(User $user)
{
$this->following()->detach($user->id);
}
public function following()
{
return $this->belongsToMany('App\User', 'following', 'user_id', 'follow_user_id')->withTimestamps();
}
public function isFollowing(User $user)
{
return !is_null($this->following()->where('follow_user_id', $user->id)->first());
}
}
这里使用了多对多用户关系关联方法[1]。
种子文件
创建一个种子文件 database/seeds/UsersTableSeeder.php
php artisan make:seeder UsersTableSeeder
在种子文件中使用工厂方法[2]
use App\User;
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$users = factory(User::class, 10)->create();
}
}
执行种子文件
- 方式一
php artisan db:seed --class=UsersTableSeeder
- 方式二
在 database/seeds/DatabaseSeeder.php
中注册种子文件
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$this->call(UsersTableSeeder::class);
}
}
执行这个 DatabaseSeeder
这个大种子。
php artisan db:seed
测试用例
创建一个测试用例。
php artisan make:test Feature\UserTest
修改 tests/Feature/UserTest.php
的内容。
use App\User;
class UserTest extends TestCase
{
public function test_have_10_users()
{
$this->assertEquals(10, User::count());
}
}
执行测试
vendor\bin\phpunit
完整的测试文件
<?php
use App\User;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class UserTest extends TestCase
{
use DatabaseTransactions;
public function test_follows()
{
$userA = User::find(2);
$userB = User::find(3);
$userA->follows($userB);
$this->assertEquals(1, $userA->following()->count());
}
public function test_unfollows()
{
$userA = User::find(3);
$userB = User::find(2);
$userA->unfollows($userB);
$this->assertEquals(0, $userA->following()->count());
}
public function test_A_follows_B_and_C()
{
$userA = User::find(1);
$ids = collect([2, 3, 4, 5, 6, 7, 8, 9, 10]);
$random_ids = $ids->random(2);
$userB = User::find($random_ids->pop());
$userC = User::find($random_ids->pop());
$userA->follows($userB);
$userA->follows($userC);
$this->assertEquals(2, $userA->following()->count());
}
}
每执行一次测试,都会在数据库表中插入数据。因此这一次运行结果和前一次可能不一样。
我们不得不像下面这样,每执行一次测试,就得重新 refresh & seeding吗?
php artisan migrate:refresh --seed
vendor\bin\phpunit
不用!加上 DatabaseTransactions
就好了。
class UserTest extends TestCase
{
use DatabaseTransactions;
...
}
这个 Trait 将所有测试项放在一个事务中。无论执行结果如何(全部成功或者没全部成功)都不会对之前的数据库数据造成任何影响,也就是说这个事务在最后总是回滚。
tags: Laravel
项目
Laravel 测试教程的更多相关文章
- Laravel初级教程浅显易懂适合入门
整理了一些Laravel初级教程,浅显易懂,特适合入门,留给刚学习laravel想快速上手有需要的朋友 最适合入门的laravel初级教程(一)序言 最适合入门的laravel初级教程(二)安装使用 ...
- 最适合入门的Laravel中级教程(一)
Laravel 是一个全栈框架: 我们使用 Laravel 开发业务常见有 3 个方向: 前端页面和后端逻辑混合的应用 主要是面向对 SEO 有需求的项目: 比如说新闻资讯博客文章等: 一般在控制器中 ...
- MyCat安装与测试教程 超详细!
MyCat安装与测试教程 超详细! MyCat基础知识 一.什么是MYCAT? 1. 一个彻底开源的,面向企业应用开发的大数据库集群 2. 支持事务.ACID.可以替代MySQL的加强版数据库 3. ...
- Kail Linux渗透测试教程之免杀Payload生成工具Veil
Kail Linux渗透测试教程之免杀Payload生成工具Veil 免杀Payload生成工具——Veil Kail Linux渗透测试教程之免杀Payload生成工具Veil,Veil是一款利用M ...
- Kail Linux渗透测试教程之网络扫描和嗅探工具Nmap
Kail Linux渗透测试教程之网络扫描和嗅探工具Nmap 网络扫描和嗅探工具——Nmap Nmap也就网络映射器(Network Mapper),是一个免费开放的网络扫描和嗅探工具.该工具可以扫描 ...
- Mac环境下RabbitMq安装与测试教程
RabbitMq安装与测试教程 Installing on Mac I. 安装 123456789 brew install rabbitmq ## 进入安装目录cd /usr/local/Cella ...
- monkey测试===monkeyrunner测试教程(1)
1.安装测试环境 jdk 安装与配置 android sdk安装与配置 Python编辑器安装与配置 以上安装请自行百度教程 Monkeyrunner使用方法 http://www.android-d ...
- 深度相机Astra Pro测试教程
最近在微信群内,很多群友在群友的推荐下,购买了Astra pro的深度相机,价格地道,物超所值!群友反馈积极,所以这里出一波简单的教程. 以下内容知识抛砖引玉,主要讲解windows下和Ubunt ...
- Unity导出iOS真机测试教程
原地址:http://unity3d.9tech.cn/news/2014/0410/40177.html 学 习了两天的Android开发,我感觉Android开发跟IOS开发和.NET平台下的开发 ...
随机推荐
- 关于djangoadmin的一个博客
http://www.cnblogs.com/linxiyue/category/569717.html
- ORACLE系统表大全
下面全面是对Oracle系统表的一些介绍: 数据字典dict总是属于Oracle用户sys的. 1.用户: select username from dba_users; 改口令 alter user ...
- STM8S103 PB4和PB5
STM8S103的PB4和PB5只能配置成开漏输出,用作I2C通讯: PB4和PB5不能配置为推挽输出,来控制LED之类的,因为内部没有上拉电阻,IO拉高电压只有1.8V左右,要想控制LED,只能通过 ...
- Yii框架的一些系统函数
Yii::app()->request->baseUrl 返回app所在目录,可以用来挂模板. var_dump(Yii::app()->db); 可以用来测试数据库配置成功否
- yum安装报错“rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID 1e5e0159”
Do not forget to set gpgkey when installing the oracle-validated rpm Read more: http://oracletoday.b ...
- 杂项-公司:联邦快递百科-un
ylbtech-杂项-公司:联邦快递百科 联邦快递( FedEx)是一家国际性速递集团,提供隔夜快递.地面快递.重型货物运送.文件复印及物流服务,总部设于美国田纳西州,隶属于美国联邦快递集团(FedE ...
- thinkphp遇到的小问题,js文件中U方法不被解析
我想在js文件中写ajax, 写完发现异常, 本以为是js文件中不支持ajax 后来发现时地址解析错误. 也就是U方法在js文件中不被解析. 貌似thinkphp解析,tpl文件中的一些元素. js文 ...
- Py修行路 python基础 (九)作用域 函数嵌套 闭包
名称空间与作用域 变量,函数 分成三种 #内置名称空间 内置函数, 系统函数内部自定义的. python查看内置函数,命令: import builtins dir(builtins) #全局名称空 ...
- Lambda语句中创建自定义类型时,也可指定某种特定类型,方法是在new与{}之间写上类型名称
如: var fc =...ChildFath = fc.Select(c => new Child_Father { child = c.child, father = c.father }) ...
- mysql 存储过程变量的定义
Mysql变量: 1.DECLARE variable_name datatype(size) DEFAULT default_value; 此处声明的相当于一个局部变量 ,在end 之后便失效. 声 ...