Laravel 影响数据库的测试用例 - 使用最佳实践
Laravel Test Cases affecting the database - Using best practices
我的 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
在 运行 执行以下某些命令时创建所需的 tables:
$ php artisan:migrate
$ php artisan:migrate --env=testing
我运行测试用例的命令是:
$ phpunit
上面的测试用例只有在测试数据库为空时才能正常工作。
然后我想知道 运行 测试用例的最佳实践是什么?例如,也许:
- 在 运行 测试用例之前清理每个 table?
- 使用另一种数据库,可能是
on-the-fly
数据库、SQLite
等(但请记住,实时数据库需要 MySQL
)。
对此有什么想法吗?我正在寻找最佳实践。
谢谢!
可以在内存中使用SQLite。另一个不错的选择是使用数据库事务,您可以在其中回滚每次测试后的查询。 Laravel 为测试提供了一个方便的 DatabaseTransactions
特征。
我的 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
在 运行 执行以下某些命令时创建所需的 tables:
$ php artisan:migrate
$ php artisan:migrate --env=testing
我运行测试用例的命令是:
$ phpunit
上面的测试用例只有在测试数据库为空时才能正常工作。
然后我想知道 运行 测试用例的最佳实践是什么?例如,也许:
- 在 运行 测试用例之前清理每个 table?
- 使用另一种数据库,可能是
on-the-fly
数据库、SQLite
等(但请记住,实时数据库需要MySQL
)。
对此有什么想法吗?我正在寻找最佳实践。
谢谢!
可以在内存中使用SQLite。另一个不错的选择是使用数据库事务,您可以在其中回滚每次测试后的查询。 Laravel 为测试提供了一个方便的 DatabaseTransactions
特征。