自动生成测试数据

Back to series
开发HTTP API之前,一个无聊却又重要的事情,就是为测试准备好数据。这样,我们才可以方便的验证API的各种行为。好在,Laravel在创建表,生成记录结果,填充表到删除记录这些环节都提供了方便的自动化功能。

因此,在上手开发API之前,我们先来了解如何基于Laravel准备测试数据。在下面的例子中,所有的操作将基于Laravel Homestead。

创建数据库

新创建一个Laravel 5.3项目,例如:boxue_lite。并且,在Homestead.yaml中添加下面的配置:

  1. folders:
  2. - map: /Users/puretears/projects/boxue_lite
  3. to: /var/www/boxue_lite/current
  4. sites:
  5. - map: api.boxue.io
  6. to: /var/www/boxue_lite/current/public
  7. databases:
  8. - boxue_lite

之后,重启Homestead,我们就新建了一个boxue_lite的测试环境,并且在Homestead中创建了叫做boxue_lite的数据库。

最后,在项目根目录中的.env文件中,把DB_DATABASE改成boxue_lite:

DB_DATABASE=boxue_lite
创建表

创建好数据库之后,在项目的根目录,执行:

php artisan make:migration CreateEpisodeTable —create=”episodes”
这样,Laravel就会在database/migrations目录,创建一个名为时间戳_CreateEpisodeTable的migration文件,在其中的up方法里,我们可以看到表名已经设置成了我们在—create参数中传递的episodes:

  1. public function up()
  2. {
  3. Schema::create('episodes', function (Blueprint $table) {
  4. $table->increments('id');
  5. $table->timestamps();
  6. });
  7. }

我们将使用这个文件,来定义episodes表的Schema。为了简单起见,我们只是添加两个column:

title表示视频的标题;
description表示视频的简介;
把up中的Schema改成这样:

  1. Schema::create('episodes', function (Blueprint $table) {
  2. $table->increments('id');
  3. $table->string('title', 64);
  4. $table->text('description');
  5. $table->timestamps();
  6. });

其中:

string会被转换成SQL中的VARCHAR,第二个参数用于限定字符串的长度;
text则会被转换成SQL中的TEXT。完成后,在项目根目录,执行:php artisan migrate,Laravel就会根据Schema中指定的规格为我们自动创建episodes表了;
创建Model

接下来,为了在PHP中方便的访问episodes表中的记录,我们需要给它创建一个model。简单来说,一个Moel就是数据库中一个表的PHP类定义。

在项目的根目录,执行:php artisan make:model Episode。这样,Laravel就会自动在app/目录创建一个名为Episode.php的文件:

  1. namespace App;
  2. use Illuminate\Database\Eloquent\Model;
  3. class Episode extends Model
  4. {
  5. //
  6. }

Laravel怎么知道Episode对应的就是episodes表呢?

在Laravel里,有一些约定俗成的内容。例如,所有的model都是大写字母单数形式的单词,它对应的,就是数据库中,以小写字母开头的对应复数单词。因此,Episode model对应的就是episodes表。
当然,如果你不习惯上面约定俗成的内容,也可以通过重定义Model中的属性来明确它,例如:

  1. class Episode extends Model
  2. {
  3. //
  4. protected $table = 'episodes';
  5. }

这样,就明确指定了Episode对应的表的名字。不过建议你还是尊从Laravel中约定俗成的内容。

最后,我们在Episode中,通过$fillable属性指定哪些字段是可以批量赋值的。它是一个数组,存放可以批量赋值的列名。因为稍后,我们要给episodes表批量中添加一些测试数据,我们指定title和description就可以了:

  1. class Episode extends Model
  2. {
  3. //
  4. protected $fillable = [ 'title', 'description' ];
  5. }
  6. Factory & Seed

表和Model都创建好之后,我们就可以创建数据填充规则并执行填充动作了。在Laravel里,它们分别由ModelFactory和Seeder这两个类来完成。

首先,在database/factories目录,创建一个EpisodeFactory.php文件,然后添加下面的代码:

  1. $factory->define(App\Episode::class,
  2. function(Faker\Generator $faker) {
  3. return [
  4. 'title' => $faker->sentence(4),
  5. 'description' => $faker->paragraph(3)
  6. ];
  7. });

其中Faker是一个被Laravel集成进来的非常方便的生成各种不同类型测试数据的PHP library。大家可以在它的Github主页,了解更多详细的用法。在我们的例子里,只是随机生成了一个4个单词的句子,以及3个段落的描述。

其次,有了记录的生成规则之后,就可以通过Seeder来创建记录了。在项目根目录执行:php artisan make:seeder EpisodeSeeder。Laravel就会在database/seeds目录里,创建一个EpisodeSeeder.php文件,其中包含了一个叫做EpisodeSeeder class。在其中的run方法里,添加下面的代码:

  1. /**
  2. + Run the database seeds.
  3. *
  4. + @return void
  5. */
  6. public function run()
  7. {
  8. //
  9. factory(App\Episode::class, 20)->create();
  10. }

这样,我们就可以自动生成20条episodes表的随机记录,并写入episodes表了。

最后,在Laravel默认的DatabaseSeeder.php的run方法里,添加调用EpisodeSeeder的代码:

  1. // In DatabaseSeeder.php
  2. public function run()
  3. {
  4. Episode::truncate();
  5. $this->call(EpisodeSeeder::class);
  6. }

完成后,在项目根目录执行:php artisan db:seed,就完成episodes表的自动填充了。Laravel会给我们类似下面的提示:

  1. vagrant@homestead:/var/www/boxue_lite/current$ php artisan db:seed
  2. Seeded: EpisodeSeeder

What’s next?

准备好测试数据之后,我们就可以着手第一个HTTP API了。在下个例子中,我们向大家介绍如何把一个Eloquent对象的查询结果,通过JSON返回给客户端。

来自泊学网

分类: web

标签:   laravel