测试资源
以用户身份认证
请确保在 TestCase 中已认证,以便访问应用:
use App\Models\User;
protected function setUp(): void
{
parent::setUp();
$this->actingAs(User::factory()->create());
}或者,若使用 Pest,可在测试文件顶部用 beforeEach() 函数进行认证:
use App\Models\User;
beforeEach(function () {
$user = User::factory()->create();
actingAs($user);
});测试资源列表页
要测试列表页能否加载,请将列表页作为 Livewire 组件进行测试,并调用 assertOk() 以确保 HTTP 响应为 200 OK。也可以使用 assertCanSeeTableRecords() 方法检查表格中是否显示了记录:
use App\Filament\Resources\Users\Pages\ListUsers;
use App\Models\User;
it('can load the page', function () {
$users = User::factory()->count(5)->create();
livewire(ListUsers::class)
->assertOk()
->assertCanSeeTableRecords($users);
});要测试表格搜索是否正常,可使用 searchTable() 方法搜索特定记录。也可以使用 assertCanSeeTableRecords() 和 assertCanNotSeeTableRecords() 方法检查表格中是否显示了正确的记录:
use App\Filament\Resources\Users\Pages\ListUsers;
use App\Models\User;
it('can search users by `name` or `email`', function () {
$users = User::factory()->count(5)->create();
livewire(ListUsers::class)
->assertCanSeeTableRecords($users)
->searchTable($users->first()->name)
->assertCanSeeTableRecords($users->take(1))
->assertCanNotSeeTableRecords($users->skip(1))
->searchTable($users->last()->email)
->assertCanSeeTableRecords($users->take(-1))
->assertCanNotSeeTableRecords($users->take($users->count() - 1));
});要测试表格排序是否正常,可使用 sortTable() 方法按特定列排序。也可以使用 assertCanSeeTableRecords() 方法检查记录是否按正确顺序显示:
use App\Filament\Resources\Users\Pages\ListUsers;
use App\Models\User;
it('can sort users by `name`', function () {
$users = User::factory()->count(5)->create();
livewire(ListUsers::class)
->assertCanSeeTableRecords($users)
->sortTable('name')
->assertCanSeeTableRecords($users->sortBy('name'), inOrder: true)
->sortTable('name', 'desc')
->assertCanSeeTableRecords($users->sortByDesc('name'), inOrder: true);
});要测试表格筛选是否正常,可使用 filterTable() 方法按特定列筛选表格。也可以使用 assertCanSeeTableRecords() 和 assertCanNotSeeTableRecords() 方法检查表格中是否显示了正确的记录:
use App\Filament\Resources\Users\Pages\ListUsers;
use App\Models\User;
it('can filter users by `locale`', function () {
$users = User::factory()->count(5)->create();
livewire(ListUsers::class)
->assertCanSeeTableRecords($users)
->filterTable('locale', $users->first()->locale)
->assertCanSeeTableRecords($users->where('locale', $users->first()->locale))
->assertCanNotSeeTableRecords($users->where('locale', '!=', $users->first()->locale));
});要测试表格 bulk action 是否正常,可使用 selectTableRecords() 方法在表格中选中多条记录。也可以使用 callAction() 方法对选中的记录调用特定 action:
use App\Filament\Resources\Users\Pages\ListUsers;
use App\Models\User;
use Filament\Actions\Testing\TestAction;
use function Pest\Laravel\assertDatabaseMissing;
it('can bulk delete users', function () {
$users = User::factory()->count(5)->create();
livewire(ListUsers::class)
->assertCanSeeTableRecords($users)
->selectTableRecords($users)
->callAction(TestAction::make(DeleteBulkAction::class)->table()->bulk())
->assertNotified()
->assertCanNotSeeTableRecords($users);
$users->each(fn (User $user) => assertDatabaseMissing($user));
});测试资源创建页
要测试创建页能否加载,请将创建页作为 Livewire 组件进行测试,并调用 assertOk() 以确保 HTTP 响应为 200 OK:
use App\Filament\Resources\Users\Pages\CreateUser;
use App\Models\User;
it('can load the page', function () {
livewire(CreateUser::class)
->assertOk();
});要测试表单是否正确创建记录,可使用 fillForm() 方法填写表单字段,然后使用 call('create') 方法创建记录。也可以使用 assertNotified() 方法检查是否显示了通知,以及 assertRedirect() 方法检查用户是否被重定向到其他页面:
use App\Filament\Resources\Users\Pages\CreateUser;
use App\Models\User;
use function Pest\Laravel\assertDatabaseHas;
it('can create a user', function () {
$newUserData = User::factory()->make();
livewire(CreateUser::class)
->fillForm([
'name' => $newUserData->name,
'email' => $newUserData->email,
])
->call('create')
->assertNotified()
->assertRedirect();
assertDatabaseHas(User::class, [
'name' => $newUserData->name,
'email' => $newUserData->email,
]);
});要测试表单验证是否正常,可使用 fillForm() 方法填写表单字段,然后使用 call('create') 方法创建记录。也可以使用 assertHasFormErrors() 方法检查表单是否有错误,以及 assertNotNotified() 方法检查是否未显示通知。还可以使用 assertNoRedirect() 方法检查用户是否未被重定向到其他页面。本例使用 Pest dataset 测试多条规则,而无需重复测试代码:
use App\Filament\Resources\Users\Pages\CreateUser;
use App\Models\User;
use Illuminate\Support\Str;
it('validates the form data', function (array $data, array $errors) {
$newUserData = User::factory()->make();
livewire(CreateUser::class)
->fillForm([
'name' => $newUserData->name,
'email' => $newUserData->email,
...$data,
])
->call('create')
->assertHasFormErrors($errors)
->assertNotNotified()
->assertNoRedirect();
})->with([
'`name` is required' => [['name' => null], ['name' => 'required']],
'`name` is max 255 characters' => [['name' => Str::random(256)], ['name' => 'max']],
'`email` is a valid email address' => [['email' => Str::random()], ['email' => 'email']],
'`email` is required' => [['email' => null], ['email' => 'required']],
'`email` is max 255 characters' => [['email' => Str::random(256)], ['email' => 'max']],
]);测试资源编辑页
要测试编辑页能否加载,请将编辑页作为 Livewire 组件进行测试,并调用 assertOk() 以确保 HTTP 响应为 200 OK。也可以使用 assertSchemaStateSet() 方法检查表单字段是否被设置为正确的值:
use App\Filament\Resources\Users\Pages\EditUser;
use App\Models\User;
it('can load the page', function () {
$user = User::factory()->create();
livewire(EditUser::class, [
'record' => $user->id,
])
->assertOk()
->assertSchemaStateSet([
'name' => $user->name,
'email' => $user->email,
]);
});use App\Filament\Resources\Users\Pages\EditUser;
use App\Models\User;
use function Pest\Laravel\assertDatabaseHas;
it('can update a user', function () {
$user = User::factory()->create();
$newUserData = User::factory()->make();
livewire(EditUser::class, [
'record' => $user->id,
])
->fillForm([
'name' => $newUserData->name,
'email' => $newUserData->email,
])
->call('save')
->assertNotified();
assertDatabaseHas(User::class, [
'id' => $user->id,
'name' => $newUserData->name,
'email' => $newUserData->email,
]);
});要测试表单验证是否正常,可使用 fillForm() 方法填写表单字段,然后使用 call('save') 方法保存记录。也可以使用 assertHasFormErrors() 方法检查表单是否有错误,以及 assertNotNotified() 方法检查是否未显示通知。本例使用 Pest dataset 测试多条规则,而无需重复测试代码:
use App\Filament\Resources\Users\Pages\EditUser;
use App\Models\User;
use Illuminate\Support\Str;
it('validates the form data', function (array $data, array $errors) {
$user = User::factory()->create();
$newUserData = User::factory()->make();
livewire(EditUser::class, [
'record' => $user->id,
])
->fillForm([
'name' => $newUserData->name,
'email' => $newUserData->email,
...$data,
])
->call('save')
->assertHasFormErrors($errors)
->assertNotNotified();
})->with([
'`name` is required' => [['name' => null], ['name' => 'required']],
'`name` is max 255 characters' => [['name' => Str::random(256)], ['name' => 'max']],
'`email` is a valid email address' => [['email' => Str::random()], ['email' => 'email']],
'`email` is required' => [['email' => null], ['email' => 'required']],
'`email` is max 255 characters' => [['email' => Str::random(256)], ['email' => 'max']],
]);要测试 action 是否正常,例如 DeleteAction,可使用 callAction() 方法调用删除 action。也可以使用 assertNotified() 方法检查是否显示了通知,以及 assertRedirect() 方法检查用户是否被重定向到其他页面:
use App\Filament\Resources\Users\Pages\EditUser;
use App\Models\User;
use Filament\Actions\DeleteAction;
use function Pest\Laravel\assertDatabaseMissing;
it('can delete a user', function () {
$user = User::factory()->create();
livewire(EditUser::class, [
'record' => $user->id,
])
->callAction(DeleteAction::class)
->assertNotified()
->assertRedirect();
assertDatabaseMissing($user);
});测试资源查看页
要测试查看页能否加载,请将查看页作为 Livewire 组件进行测试,并调用 assertOk() 以确保 HTTP 响应为 200 OK。也可以使用 assertSchemaStateSet() 方法检查 infolist 条目是否被设置为正确的值:
use App\Filament\Resources\Users\Pages\ViewUser;
use App\Models\User;
it('can load the page', function () {
$user = User::factory()->create();
livewire(ViewUser::class, [
'record' => $user->id,
])
->assertOk()
->assertSchemaStateSet([
'name' => $user->name,
'email' => $user->email,
]);
});测试 relation manager
要测试页面(例如资源的编辑页)上是否渲染了 relation manager,可使用 assertSeeLivewire() 方法检查 relation manager 是否正在渲染:
use App\Filament\Resources\Users\Pages\EditUser;
use App\Filament\Resources\Users\RelationManagers\PostsRelationManager;
use App\Models\User;
it('can load the relation manager', function () {
$user = User::factory()->create();
livewire(EditUser::class, [
'record' => $user->id,
])
->assertSeeLivewire(PostsRelationManager::class);
});由于 relation manager 是 Livewire 组件,也可以测试 relation manager 自身的功能,例如能否以 200 OK 响应成功加载,以及表格中是否有正确的记录。测试 relation manager 时,需要传入 ownerRecord(你所在资源中的记录)和 pageClass(当前页面的类):
use App\Filament\Resources\Users\Pages\EditUser;
use App\Filament\Resources\Users\RelationManagers\PostsRelationManager;
use App\Models\Post;
use App\Models\User;
it('can load the relation manager', function () {
$user = User::factory()
->has(Post::factory()->count(5))
->create();
livewire(PostsRelationManager::class, [
'ownerRecord' => $user,
'pageClass' => EditUser::class,
])
->assertOk()
->assertCanSeeTableRecords($user->posts);
});也可以测试 action,例如表格 header 中的 CreateAction:
use App\Filament\Resources\Users\Pages\EditUser;
use App\Filament\Resources\Users\RelationManagers\PostsRelationManager;
use App\Models\Post;
use App\Models\User;
use Filament\Actions\Testing\TestAction;
use function Pest\Laravel\assertDatabaseHas;
it('can create a post', function () {
$user = User::factory()->create();
$newPostData = Post::factory()->make();
livewire(PostsRelationManager::class, [
'ownerRecord' => $user,
'pageClass' => EditUser::class,
])
->callAction(TestAction::make(CreateAction::class)->table(), [
'title' => $newPostData->title,
'content' => $newPostData->content,
])
->assertNotified();
assertDatabaseHas(Post::class, [
'title' => $newPostData->title,
'content' => $newPostData->content,
'user_id' => $user->id,
]);
});测试创建 / 编辑页的 getFormActions()
在资源页面上测试 getFormActions() 中的 action 时,请使用 schemaComponent() 方法,并以 content schema 中的 form-actions 键为目标。例如,若在 CreateUser 页面的 getFormActions() 方法中有自定义的 Action::make('createAndVerifyEmail') action,可以这样测试:
use App\Filament\Resources\Users\Pages\CreateUser;
use App\Models\User;
use Filament\Actions\Testing\TestAction;
it('can create a user and verify their email address', function () {
livewire(CreateUser::class)
->fillForm([
'name' => 'Test User',
'email' => 'test@example.com',
])
->callAction(TestAction::make('createAndVerifyEmail')->schemaComponent('form-actions', schema: 'content'));
expect(User::query()->where('email', 'test@example.com')->first())
->hasVerifiedEmail()->toBeTrue();
});测试多个面板
若有多个面板且想测试非默认面板,需要告知 Filament 正在测试哪个面板。可在测试用例的 setUp() 方法中完成,也可以在某个测试的开头进行。通过请求访问面板时,Filament 通常在中间件中完成此事;因此若测试中没有发起请求(例如测试 Livewire 组件时),需要手动设置当前面板:
use Filament\Facades\Filament;
Filament::setCurrentPanel('app'); // Where `app` is the ID of the panel you want to test.测试多租户面板
在多租户面板中测试资源时,设置租户后可能需要调用 Filament::bootCurrentPanel(),以便应用租户作用域和模型事件监听器:
use Filament\Facades\Filament;
$team = Team::factory()->create();
Filament::setTenant($this->team);
Filament::setCurrentPanel('admin');
Filament::bootCurrentPanel();