Laravel测试用例影响数据库-使用最佳做法

时间:2018-10-14 03:38:05

标签: php mysql laravel phpunit laravel-5.7

我的Laravel应用程序具有以下控制器:

class ProjectController extends Controller {
    ...
    public function index() {
        $projects = Project::where('is_completed', false)
            ->orderBy('created_at', 'desc')
            ->withCount(['tasks' => function ($query) {
                $query->where('is_completed', false);
            }])->get();
        return response()->json($projects);
    }
    public function store(Request $request) {
        $validatedData = $request->validate([
            'name' => 'required',
            'description' => 'required',
        ]);
        $project = Project::create([
            'name' => $validatedData['name'],
            'description' => $validatedData['description'],
        ]);
        return response()->json('Project created!');
    }
    ...
}

由以下路由引用:

Route::get('projects', 'ProjectController@index');
Route::post('projects', 'ProjectController@store');

我还有以下测试文件:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ProjectTest extends TestCase
{
    public function testCreateProjects()
    {
        $response = $this->post(
            '/api/projects',
            [
                'name' => 'Project 01 Title',
                'description' => 'Project 01 Description',
            ]
        );
        $response = $this->post(
            '/api/projects',
            [
                'name' => 'Project 02 Title',
                'description' => 'Project 02 Description',
            ]
        );

        $response = $this->get('/api/projects');
        $data = $response->json();

        $this->assertSame(2, count($data));
    }
}

作为实时数据库,我使用:MySQL。这是必须的。

在文件/.env.testing上,我指定了一个测试MySQL数据库,因此我不对实时数据库进行更改。

文件很少,如下所示:

/database/migrations/<TIMESTAMP>_create_projects_table.php

在运行以下某些命令时创建所需表:

$ php artisan:migrate
$ php artisan:migrate --env=testing

我使用以下命令运行测试用例:

$ phpunit

仅当测试数据库为空时,上述测试用例才能正常工作。

然后我想知道运行测试用例的最佳实践是什么?例如,也许:

  • 在运行测试用例之前清理每个表?
  • 使用另一种数据库,例如on-the-fly数据库,SQLite等(但要记住实时数据库需要为MySQL)。

对此有任何想法吗?我正在寻找最佳实践。

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以在内存中使用SQLite。另一个不错的选择是使用数据库事务,您可以在其中在每次测试后回滚查询。 Laravel为测试提供了方便的DatabaseTransactions特性。