跳到主要内容
版本:3.x

测试

概述

所有本指南内的示例都使用 Pest 编写。不过,你可以将其适配到 PHPUnit。

因为表单构造器是基于 Livewire 组件的,因此你也可以使用 Livewire 测试辅助函数。不过,我们自定义了一些测试辅助函数,让你可以用于表单测试:

填充表单

要填充表单,请将数据传入 fillform()

use function Pest\Livewire\livewire;

livewire(CreatePost::class)
->fillForm([
'title' => fake()->sentence(),
// ...
]);

如果一个 Livewire 组件中有多个表单,你可以使用 fillForm([...], 'createPostForm') 指定你想要填充哪个表单。

使用 assertFormSet() 断言表单中有数据:

use Illuminate\Support\Str;
use function Pest\Livewire\livewire;

it('can automatically generate a slug from the title', function () {
$title = fake()->sentence();

livewire(CreatePost::class)
->fillForm([
'title' => $title,
])
->assertFormSet([
'slug' => Str::slug($title),
]);
});

注意,如果一个 Livewire 组件中有多个表单,你可以使用 assertFormSet([...], 'createPostForm') 指定你想要检测哪个表单。

验证

使用 assertHasFormErrors() 断言对表单中的数据进行有效验证:

use function Pest\Livewire\livewire;

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

同时 assertHasNoFormErrors() 断言没有验证错误:

use function Pest\Livewire\livewire;

livewire(CreatePost::class)
->fillForm([
'title' => fake()->sentence(),
// ...
])
->call('create')
->assertHasNoFormErrors();

注意,如果一个 Livewire 组件中有多个表单,你可以将指定表单名作为第二个参数传入,像这样 assertHasFormErrors(['title' => 'required'], 'createPostForm')assertHasNoFormErrors([], 'createPostForm')

表单存在

断言 Livewire 组件中有一个表单,请使用 assertFormExists():

use function Pest\Livewire\livewire;

it('has a form', function () {
livewire(CreatePost::class)
->assertFormExists();
});

如果一个 Livewire 组件中有多个表单,你可以将指定的表单名传入 assertFormExists('createPostForm')

字段

断言表单中有某个给定字段,请将字段名传入到 assertFormFieldExists()

use function Pest\Livewire\livewire;

it('has a title field', function () {
livewire(CreatePost::class)
->assertFormFieldExists('title');
});

你也可以传入函数作为额外的参数,来断言一个字段传入了一个"真值测试”"。着对断言一个字段有某个特定配置非常有用:

use function Pest\Livewire\livewire;

it('has a title field', function () {
livewire(CreatePost::class)
->assertFormFieldExists('title', function (TextInput $field): bool {
return $field->isDisabled();
});
});

如果 Livewire 组件有多个表单,你可以指定哪个表单要断言字段是否存在。比如 assertFormFieldExists('title', 'createPostForm')

Hidden 字段

断言表单中有某个字段可见,将字段名传入到 assertFormFieldIsVisible():

use function Pest\Livewire\livewire;

test('title is visible', function () {
livewire(CreatePost::class)
->assertFormFieldIsVisible('title');
});

或者断言表单中隐藏某个字段,将字段名传入到 assertFormFieldIsHidden():

use function Pest\Livewire\livewire;

test('title is hidden', function () {
livewire(CreatePost::class)
->assertFormFieldIsHidden('title');
});

对于 assertFormFieldIsHidden()assertFormFieldIsVisible(),你可以传递该字段所属表单的名称作为第二个参数,比如 assertFormFieldIsHidden('title', 'createPostForm')

禁用字段

要断言字段可用,请传递字段名到 assertFormFieldIsEnabled()

use function Pest\Livewire\livewire;

test('title is enabled', function () {
livewire(CreatePost::class)
->assertFormFieldIsEnabled('title');
});

要断言字段禁用,请传递字段名到 assertFormFieldIsDisabled()

use function Pest\Livewire\livewire;

test('title is disabled', function () {
livewire(CreatePost::class)
->assertFormFieldIsDisabled('title');
});

对于 assertFormFieldIsEnabled()assertFormFieldIsDisabled(),你可以传递该字段所属表单的名称作为第二个参数,比如 assertFormFieldIsEnabled('title', 'createPostForm')

Actions

你可以传递 Action 的表单组件名及 Action 名到 callFormComponentAction 中调用 Action:

use function Pest\Livewire\livewire;

it('can send invoices', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callFormComponentAction('customer_id', 'send');

expect($invoice->refresh())
->isSent()->toBeTrue();
});

使用 data 参数,传递数据数组给 Action:

use function Pest\Livewire\livewire;

it('can send invoices', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callFormComponentAction('customer_id', 'send', data: [
'email' => $email = fake()->email(),
])
->assertHasNoFormComponentActionErrors();

expect($invoice->refresh())
->isSent()->toBeTrue()
->recipient_email->toBe($email);
});

如果只需要设置 Action 的数据而不立即调用它,可以使用 setFormComponentActionData():

use function Pest\Livewire\livewire;

it('can send invoices', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->mountFormComponentAction('customer_id', 'send')
->setFormComponentActionData('customer_id', 'send', data: [
'email' => $email = fake()->email(),
])
});

执行

要检测 Action 是否被中止,可以使用 assertFormComponentActionHalted()

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,
])
->callFormComponentAction('customer_id', 'send')
->assertFormComponentActionHalted('customer_id', 'send');
});

错误

assertHasNoFormComponentActionErrors() 用于断言提交 Action 表单没有出现验证错误。

使用 assertHasFormComponentActionErrors() 用于使用数据断言验证错误,类似于 Livewire 中的 assertHasErrors():

use function Pest\Livewire\livewire;

it('can validate invoice recipient email', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callFormComponentAction('customer_id', 'send', data: [
'email' => Str::random(),
])
->assertHasFormComponentActionErrors(['email' => ['email']]);
});

要断言 Action 预装填数据,可以使用 assertFormComponentActionDataSet() 方法:

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,
])
->mountFormComponentAction('customer_id', 'send')
->assertFormComponentActionDataSet([
'email' => $recipientEmail,
])
->callMountedFormComponentAction()
->assertHasNoFormComponentActionErrors();

expect($invoice->refresh())
->isSent()->toBeTrue()
->recipient_email->toBe($recipientEmail);
});

Action state

要断言 Action 存在于或者不在表单中,可以使用 assertFormComponentActionExists()assertFormComponentActionDoesNotExist() 方法:

use function Pest\Livewire\livewire;

it('can send but not unsend invoices', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionExists('customer_id', 'send')
->assertFormComponentActionDoesNotExist('customer_id', 'unsend');
});

要断言 Action 对用户隐藏或可见,可以使用 assertFormComponentActionHidden()assertFormComponentActionVisible() 方法:

use function Pest\Livewire\livewire;

it('can only print customers', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionHidden('customer_id', 'send')
->assertFormComponentActionVisible('customer_id', 'print');
});

要断言 Action 是对用户启用还是禁用,可以使用 assertFormComponentActionEnabled()assertFormComponentActionDisabled() 方法:

use function Pest\Livewire\livewire;

it('can only print a customer for a sent invoice', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionDisabled('customer_id', 'send')
->assertFormComponentActionEnabled('customer_id', 'print');
});

要断言 Action 对某个用户隐藏,可以使用 assertFormComponentActionHidden() 方法:

use function Pest\Livewire\livewire;

it('can not send invoices', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionHidden('customer_id', 'send');
});

按钮外观

要断言 Action 的标签正确,可以使用 assertFormComponentActionHasLabel()assertFormComponentActionDoesNotHaveLabel()

use function Pest\Livewire\livewire;

it('send action has correct label', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionHasLabel('customer_id', 'send', 'Email Invoice')
->assertFormComponentActionDoesNotHaveLabel('customer_id', 'send', 'Send');
});

要断言 Action 按钮的图标正确显示,可以使用 assertFormComponentActionHasIcon()assertFormComponentActionDoesNotHaveIcon()

use function Pest\Livewire\livewire;

it('when enabled the send button has correct icon', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionEnabled('customer_id', 'send')
->assertFormComponentActionHasIcon('customer_id', 'send', 'envelope-open')
->assertFormComponentActionDoesNotHaveIcon('customer_id', 'send', 'envelope');
});

要断言 Action 按钮的颜色正确显示,可以使用 assertFormComponentActionHasColor()assertFormComponentActionDoesNotHaveColor()

use function Pest\Livewire\livewire;

it('actions display proper colors', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionHasColor('customer_id', 'delete', 'danger')
->assertFormComponentActionDoesNotHaveColor('customer_id', 'print', 'danger');
});

URL

要断言 Action 的 URL 正确,可以使用 assertFormComponentActionHasUrl()assertFormComponentActionDoesNotHaveUrl()assertFormComponentActionShouldOpenUrlInNewTab()assertFormComponentActionShouldNotOpenUrlInNewTab()

use function Pest\Livewire\livewire;

it('links to the correct Filament sites', function () {
$invoice = Invoice::factory()->create();

livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionHasUrl('customer_id', 'filament', 'https://filamentphp.com/')
->assertFormComponentActionDoesNotHaveUrl('customer_id', 'filament', 'https://github.com/filamentphp/filament')
->assertFormComponentActionShouldOpenUrlInNewTab('customer_id', 'filament')
->assertFormComponentActionShouldNotOpenUrlInNewTab('customer_id', 'github');
});