测试框架使用 Pest 测试框架,它提供了一个更优雅的测试语法。
页面渲染
首先,需要测试各个页面是否能够正确渲染:
use App\Models\Post;
use App\Filament\Resources\PostResource\Pages\EditPost;
use App\Filament\Resources\PostResource\Pages\CreatePost;
use App\Filament\Resources\PostResource\Pages\ListPosts;
use function Pest\Livewire\livewire;
it('can render the index page', function () {
livewire(ListPosts::class)->assertOk();
});
it('can render the create page', function () {
livewire(CreatePost::class)->assertOk();
});
it('can render the edit page', function () {
$record = Post::factory()->create();
livewire(EditPost::class, ['record' => $record->getRouteKey()])
->assertOk();
});
表格功能测试
列的存在性
使用 assertTableColumnExists
方法断言表格存在对应列,它仅检查列是否在表格定义中存在。
<?php
use App\Filament\Resources\PostResource\Pages\ListPosts;
it('has column', function (string $column) {
livewire(ListPosts::class)
->assertTableColumnExists($column);
})->with(['name', 'description', 'body', 'cover', 'status', 'created_at', 'updated_at']);
TIP
assertTableColumnExists
断言只检查列是否在表格的配置中定义,不会实际尝试渲染该列。
它的速度相比下面列的渲染断言 assertCanRenderTableColumn
方法较快,因为只是检查配置适用于确认列的存在性。
列的渲染
使用 assertCanRenderTableColumn
断言方法检查列是否可以实际渲染数据。
<?php
use App\Filament\Resources\PostResource\Pages\ListPosts;
it('can render column', function (string $column) {
livewire(ListPosts::class)
->assertCanRenderTableColumn($column);
})->with(['name', 'description', 'cover', 'status', 'created_at', 'updated_at']);
WARNING
检查列是否存在,实际尝试渲染该列的数据验证列的渲染逻辑是否正常工作。
可以发现渲染过程中的潜在问题,更全面但执行速度较慢。
列的排序
use App\Models\Post;
use App\Filament\Resources\PostResource\Pages\ListPosts;
it('can sort column', function (string $column) {
$records = Post::factory(5)->create();
livewire(ListPosts::class)
->sortTable($column)
->assertCanSeeTableRecords($records->sortBy($column), inOrder: true)
->sortTable($column, 'desc')
->assertCanSeeTableRecords($records->sortByDesc($column), inOrder: true);
})->with(['name', 'status', 'created_at', 'updated_at']);
列的搜索
use App\Models\Post;
use App\Filament\Resources\PostResource\Pages\ListPosts;
it('can search column', function (string $column) {
$records = Post::factory(5)->create();
$search = data_get($records->first(), $column);
livewire(ListPosts::class)
->searchTable($search instanceof BackedEnum ? $search->value : $search)
->assertCanSeeTableRecords($records->filter(fn (Post $record) => data_get($record, $column) === $search));
})->with(['name', 'description', 'body']);
增删改查测试
分别测试新增资源、编辑资源、删除资源和批量删除资源的操作。
创建
use App\Models\Post;
use App\Filament\Resources\PostResource\Pages\CreatePost;
it('can create a post', function () {
$record = Post::factory()->make();
livewire(CreatePost::class)
->fillForm([
'name' => $record->name,
'description' => $record->description,
'cover' => $record->cover,
'body' => $record->body,
'status' => $record->status,
])
->assertActionExists('create')
->call('create')
->assertHasNoFormErrors();
$this->assertDatabaseHas(Post::class, [
'name' => $record->name,
'description' => $record->description,
'cover' => $record->cover,
'body' => $record->body,
'status' => $record->status,
]);
});
更新
use App\Models\Post;
use App\Filament\Resources\PostResource\Pages\EditPost;
it('can update a post', function () {
$record = Post::factory()->create();
$newRecord = Post::factory()->make();
livewire(EditPost::class, ['record' => $record->getRouteKey()])
->fillForm([
'name' => $newRecord->name,
'description' => $record->description,
'cover' => $record->cover,
'body' => $record->body,
'status' => $record->status,
])
->assertActionExists('save')
->call('save')
->assertHasNoFormErrors();
$this->assertDatabaseHas(Post::class, [
'name' => $newRecord->name,
'description' => $record->description,
'cover' => $record->cover,
'body' => $record->body,
'status' => $record->status,
]);
});
删除
use App\Models\Post;
use Filament\Actions\DeleteAction;
it('can delete a post', function () {
$record = Post::factory()->create();
livewire(EditPost::class, ['record' => $record->getRouteKey()])
->assertActionExists('delete')
->callAction(DeleteAction::class);
$this->assertModelMissing($record);
});
批量删除
use App\Models\Post;
use Filament\Tables\Actions\DeleteBulkAction;
it('can bulk delete posts', function () {
$records = Post::factory(5)->create();
livewire(ListCompanies::class)
->assertTableBulkActionExists('delete')
->callTableBulkAction(DeleteBulkAction::class, $records);
$records->each(fn ($record) => $this->assertModelMissing($record));
});
验证测试
required
<?php
use App\Models\Post;
use Illuminate\Support\Str;
use App\Filament\Resources\PostResource\Pages\CreatePost;
it('can validate required', function (string $column) {
livewire(CreatePost::class)
->fillForm([$column => null])
->assertActionExists('create')
->call('create')
->assertHasFormErrors([$column => ['required']]);
})->with(['name', 'cover', 'body', 'status']);
max
it('can validate max length', function (string $column) {
livewire(CreatePost::class)
->fillForm([$column => Str::random(256)])
->assertActionExists('create')
->call('create')
->assertHasFormErrors([$column => ['max:255']]);
})->with(['name', 'description']);
enum
it('can validate status enum', function () {
$record = Post::factory()->make();
livewire(CreatePost::class)
->fillForm([
'name' => $record->name,
'description' => $record->description,
'cover' => $record->cover,
'body' => $record->body,
'status' => 'invalid-status',
])
->assertActionExists('create')
->call('create')
->assertHasFormErrors([
'status' => ['Illuminate\Validation\Rules\Enum'],
]);
});