公告: 旧版文档请移步 -> http://v2.laravel-filament.cn/docs

Languages

Version

Theme

后台面板

测试

所有本指南内的示例都会使用 Pest 编写。

由于后台面板的所有页面都是 Livewire 组件,我们始终都在使用 Livewire 测试函数。 如果你之前从未测试过 Livewire 组件,请阅读 Livewire 文档下的这一向导

开始

确保你在测试案例(TestCase)中有权限访问后台面板:

protected function setUp(): void
{
parent::setUp();
 
$this->actingAs(User::factory()->create());
}

资源

页面

列表

路由 & 渲染

要确保 PostResource 的列表页渲染成功,需生成页面 URL、发送请求到该 URL 并检查是否成功:

it('can render page', function () {
$this->get(PostResource::getUrl('index'))->assertSuccessful();
});
表格

Filament 内含一系列辅助函数用来测试表格。表格测试全指南可查阅表格构造器文档

要使用表格测试辅助函数,在持有该表格的资源列表类中使用断言:

use function Pest\Livewire\livewire;
 
it('can list posts', function () {
$posts = Post::factory()->count(10)->create();
 
livewire(PostResource\Pages\ListPosts::class)
->assertCanSeeTableRecords($posts);
});

新建

路由 & 渲染

检查 PostResource 的新建页是否可以成功渲染,生成页面 URL,发起请求到该地址,检测是否成功。

it('can render page', function () {
$this->get(PostResource::getUrl('create'))->assertSuccessful();
});
新建

你可以通过设置(set())表单的每个属性,然后断言数据库是否包含这一记录,检查数据是否成功保存到数据库:

use function Pest\Livewire\livewire;
 
it('can create', function () {
$newData = Post::factory()->make();
 
livewire(PostResource\Pages\CreatePost::class)
->fillForm([
'author_id' => $newData->author->getKey(),
'content' => $newData->content,
'tags' => $newData->tags,
'title' => $newData->title,
])
->call('create')
->assertHasNoFormErrors();
 
$this->assertDatabaseHas(Post::class, [
'author_id' => $newData->author->getKey(),
'content' => $newData->content,
'tags' => json_encode($newData->tags),
'title' => $newData->title,
]);
});
验证

使用 assertHasFormErrors() 检查表单中的数据验证是否正确:

use function Pest\Livewire\livewire;
 
it('can validate input', function () {
 
livewire(PostResource\Pages\CreatePost::class)
->fillForm([
'title' => null,
])
->call('create')
->assertHasFormErrors(['title' => 'required']);
});

编辑

路由 & 渲染

检查 PostResource 的编辑页是否可以成功渲染,生成页面 URL,发起请求到该地址,检测是否成功:

it('can render page', function () {
$this->get(PostResource::getUrl('edit', [
'record' => Post::factory()->create(),
]))->assertSuccessful();
});
填充已有数据

检测当前表单是否正确填充了数据库的数据,你可以使用 assertFormSet() 断言表单中的数据是否匹配数据库记录:

use function Pest\Livewire\livewire;
 
it('can retrieve data', function () {
$post = Post::factory()->create();
 
livewire(PostResource\Pages\EditPost::class, [
'record' => $post->getKey(),
])
->assertFormSet([
'author_id' => $post->author->getKey(),
'content' => $post->content,
'tags' => $post->tags,
'title' => $post->title,
]);
});
保存

你可以在 fillForm() 使用表单数据,检查数据是否正确存入数据库,并断言数据库中是否包含匹配的记录:

use function Pest\Livewire\livewire;
 
it('can save', function () {
$post = Post::factory()->create();
$newData = Post::factory()->make();
 
livewire(PostResource\Pages\EditPost::class, [
'record' => $post->getKey(),
])
->fillForm([
'author_id' => $newData->author->getKey(),
'content' => $newData->content,
'tags' => $newData->tags,
'title' => $newData->title,
])
->call('save')
->assertHasNoFormErrors();
 
expect($post->refresh())
->author_id->toBe($newData->author->getKey())
->content->toBe($newData->content)
->tags->toBe($newData->tags)
->title->toBe($newData->title);
});
验证

使用 assertHasFormErrors() 检测表单中的数据是否被正确验证:

use function Pest\Livewire\livewire;
 
it('can validate input', function () {
$post = Post::factory()->create();
 
livewire(PostResource\Pages\EditPost::class, [
'record' => $post->getKey(),
])
->fillForm([
'title' => null,
])
->call('save')
->assertHasFormErrors(['title' => 'required']);
});
删除

你可以使用 callPageAction() 测试 DeleteAction:

use Filament\Pages\Actions\DeleteAction;
use function Pest\Livewire\livewire;
 
it('can delete', function () {
$post = Post::factory()->create();
 
livewire(PostResource\Pages\EditPost::class, [
'record' => $post->getKey(),
])
->callPageAction(DeleteAction::class);
 
$this->assertModelMissing($post);
});

你可以使用 assertPageActionHidden() 断言 DeleteAction 对特定用户隐藏:

use Filament\Pages\Actions\DeleteAction;
use function Pest\Livewire\livewire;
 
it('can not delete', function () {
$post = Post::factory()->create();
 
livewire(PostResource\Pages\EditPost::class, [
'record' => $post->getKey(),
])
->assertPageActionHidden(DeleteAction::class);
});

查看

路由 & 渲染

检查 PostResource 的查看页是否可以成功渲染,生成页面 URL,发起请求到该地址,检测是否成功:

it('can render page', function () {
$this->get(PostResource::getUrl('view', [
'record' => Post::factory()->create(),
]))->assertSuccessful();
});
填充已有数据

检测当前表单是否正确填充了数据库的数据,你可以使用 assertFormSet() 断言表单中的数据是否匹配数据库记录:

use function Pest\Livewire\livewire;
 
it('can retrieve data', function () {
$post = Post::factory()->create();
 
livewire(PostResource\Pages\ViewPost::class, [
'record' => $post->getKey(),
])
->assertFormSet([
'author_id' => $post->author->getKey(),
'content' => $post->content,
'tags' => $post->tags,
'title' => $post->title,
]);
});

关联管理器

渲染

要检测关联管理器是否渲染成功,挂载 Livewire 组件:

use function Pest\Livewire\livewire;
 
it('can render relation manager', function () {
$category = Category::factory()
->has(Post::factory()->count(10))
->create();
 
livewire(CategoryResource\RelationManagers\PostsRelationManager::class, [
'ownerRecord' => $category,
])
->assertSuccessful();
});
表格

Filament 内含一系列辅助函数用于测试表格。表格测试全指南可查阅表格构造器文档

要使用表格测试辅助函数,在持有该表格的关联管理器类中使用断言:

use function Pest\Livewire\livewire;
 
it('can list posts', function () {
$category = Category::factory()
->has(Post::factory()->count(10))
->create();
 
livewire(CategoryResource\RelationManagers\PostsRelationManager::class, [
'ownerRecord' => $category,
])
->assertCanSeeTableRecords($category->posts);
});

页面操作

调用操作

你可以在 callPageAction() 中传入操作名或类调用页面操作:

use function Pest\Livewire\livewire;
 
it('can send invoices', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callPageAction('send');
 
expect($invoice->refresh())
->isSent()->toBeTrue();
});

使用 data 参数,将数组数据传入操作:

use function Pest\Livewire\livewire;
 
it('can send invoices', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callPageAction('send', data: [
'email' => $email = fake()->email(),
])
->assertHasNoPageActionErrors();
 
expect($invoice->refresh())
->isSent()->toBeTrue()
->recipient_email->toBe($email);
});

如果你只需要设置页面 Action 数据,而不需要立即调用,你可以使用 setPageActionData()

use function Pest\Livewire\livewire;
 
it('can send invoices', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->mountPageAction('send')
->setPageActionData('send', data: [
'email' => $email = fake()->email(),
])
});

执行

要检测 Action 是否被中断,你可以使用 assertPageActionHalted()

use function Pest\Livewire\livewire;
 
it('stops sending if invoice has no email address', function () {
$invoice = Invoice::factory(['email' => null])->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callPageAction('send')
->assertPageActionHalted('send');
});

错误

assertHasNoPageActionErrors() 用于断言提交操作表单时没有出现验证错误。

要断言数据出现验证错误,像在 Livewire 中使用 assertHasErrors() 一样,使用 assertHasPageActionErrors()

use function Pest\Livewire\livewire;
 
it('can validate invoice recipient email', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callPageAction('send', data: [
'email' => Str::random(),
])
->assertHasPageActionErrors(['email' => ['email']]);
});

预填充数据

使用 assertPageActionDataSet() 断言页面操作是否预装了数据:

use function Pest\Livewire\livewire;
 
it('can send invoices to the primary contact by default', function () {
$invoice = Invoice::factory()->create();
$recipientEmail = $invoice->company->primaryContact->email;
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->mountPageAction('send')
->assertPageActionDataSet([
'email' => $recipientEmail,
])
->callMountedPageAction()
->assertHasNoPageActionErrors();
expect($invoice->refresh())
->isSent()->toBeTrue()
->recipient_email->toBe($recipientEmail);
});

Action 状态

要断言一个 Action 存在或者不在表格中,你可以使用 assertPageActionExists() 或者 assertPageActionDoesNotExist() 方法:

use function Pest\Livewire\livewire;
 
it('can send but not unsend invoices', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertPageActionExists('send')
->assertPageActionDoesNotExist('unsend');
});

使用 assertPageActionHidden()assertPageActionVisible() 断言页面操作是否对用户隐藏。

use function Pest\Livewire\livewire;
 
it('can not send invoices', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertPageActionHidden('send')
->assertPageActionVisible('print');
});

要断言一个页面 Action 对某个用户启用或者禁用,你可以使用 assertPageActionEnabled 或者 assertPageActionDisabled() 方法:

use function Pest\Livewire\livewire;
 
it('can only print a sent invoice', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertPageActionDisabled('send')
->assertPageActionEnabled('print');
});

要断言一套 Action 以正确的顺序排列,你可以使用 assertPageActionsExistInOrder():

use function Pest\Livewire\livewire;
 
it('can not send invoices', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertPageActionsExistInOrder(['send', 'export']);
});

按钮外观

使用 assertPageActionHasLabel()assertPageActionDoesNotHaveLabel(),可以断言 Action 标签是否正确:

use function Pest\Livewire\livewire;
 
it('send action has correct label', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertPageActionHasLabel('send', 'Email Invoice')
->assertPageActionDoesNotHaveLabel('send', 'Send');
});

使用 assertPageActionHasIcon()assertPageActionDoesNotHaveIcon(),可以断言 Action 按钮是否正确显示图标:

use function Pest\Livewire\livewire;
 
it('when enabled the send button has correct icon', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertPageActionEnabled('send')
->assertPageActionHasIcon('send', 'envelope-open')
->assertPageActionDoesNotHaveIcon('send', 'envelope');
});

使用 assertPageActionHasColor()assertPageActionDoesNotHaveColor(),可以断言 Action 按钮是否显示正确颜色:

use function Pest\Livewire\livewire;
 
it('actions display proper colors', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertPageActionHasColor('delete', 'danger')
->assertPageActionDoesNotHaveColor('print', 'danger');
});

URL

使用 assertPageActionHasUrl()assertPageActionDoesNotHaveUrl()assertPageActionShouldOpenUrlInNewTab()assertPageActionShouldNotOpenUrlInNewTab(),你可以断言 Action 的 URL 是否正确。

use function Pest\Livewire\livewire;
 
it('links to the correct Filament sites', function () {
$invoice = Invoice::factory()->create();
 
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertPageActionHasUrl('filament', 'https://filamentphp.com/')
->assertPageActionDoesNotHaveUrl('filament', 'https://github.com/filamentphp/filament')
->assertPageActionShouldOpenUrlInNewTab('filament')
->assertPageActionShouldNotOpenUrlInNewTab('github');
});
Edit on GitHub

Still need help? Join our Discord community or open a GitHub discussion