Skip to content
全部文档

测试表格

测试表格能否渲染

要确认表格组件能够渲染,请使用 assertSuccessful() Livewire 辅助方法:

php
use function Pest\Livewire\livewire;

it('can render page', function () {
    livewire(ListPosts::class)
        ->assertSuccessful();
});

要测试显示了哪些记录,可使用 assertCanSeeTableRecords()assertCanNotSeeTableRecords()assertCountTableRecords()

php
use function Pest\Livewire\livewire;

it('cannot display trashed posts by default', function () {
    $posts = Post::factory()->count(4)->create();
    $trashedPosts = Post::factory()->trashed()->count(6)->create();

    livewire(PostResource\Pages\ListPosts::class)
        ->assertCanSeeTableRecords($posts)
        ->assertCanNotSeeTableRecords($trashedPosts)
        ->assertCountTableRecords(4);
});
若表格使用分页,`assertCanSeeTableRecords()` 仅检查第一页的记录。要切换页面,请调用 `call('gotoPage', 2)`。
若表格使用了 `deferLoading()`,应在 `assertCanSeeTableRecords()` 之前调用 `loadTable()`。

测试列

要确认某列已渲染,请将列名传给 assertCanRenderTableColumn()

php
use function Pest\Livewire\livewire;

it('can render post titles', function () {
    Post::factory()->count(10)->create();

    livewire(PostResource\Pages\ListPosts::class)
        ->assertCanRenderTableColumn('title');
});

该辅助方法会获取此列的 HTML,并检查它是否出现在表格中。

要测试某列未被渲染,可使用 assertCanNotRenderTableColumn()

php
use function Pest\Livewire\livewire;

it('can not render post comments', function () {
    Post::factory()->count(10)->create()

    livewire(PostResource\Pages\ListPosts::class)
        ->assertCanNotRenderTableColumn('comments');
});

该辅助方法会断言此列的 HTML 默认不会显示在当前表格中。

测试列能否被搜索

要搜索表格,请用搜索词调用 searchTable() 方法。

然后可用 assertCanSeeTableRecords() 检查筛选后的表格记录,并用 assertCanNotSeeTableRecords() 断言某些记录已不在表格中:

php
use function Pest\Livewire\livewire;

it('can search posts by title', function () {
    $posts = Post::factory()->count(10)->create();

    $title = $posts->first()->title;

    livewire(PostResource\Pages\ListPosts::class)
        ->searchTable($title)
        ->assertCanSeeTableRecords($posts->where('title', $title))
        ->assertCanNotSeeTableRecords($posts->where('title', '!=', $title));
});

要搜索单个列,可将搜索数组传给 searchTableColumns()

php
use function Pest\Livewire\livewire;

it('can search posts by title column', function () {
    $posts = Post::factory()->count(10)->create();

    $title = $posts->first()->title;

    livewire(PostResource\Pages\ListPosts::class)
        ->searchTableColumns(['title' => $title])
        ->assertCanSeeTableRecords($posts->where('title', $title))
        ->assertCanNotSeeTableRecords($posts->where('title', '!=', $title));
});

测试列能否被排序

要排序表格记录,可调用 sortTable(),并传入要排序的列名。可在 sortTable() 的第二个参数中使用 'desc' 来反转排序方向。

表格排序后,可使用带 inOrder 参数的 assertCanSeeTableRecords() 确认表格记录按顺序渲染:

php
use function Pest\Livewire\livewire;

it('can sort posts by title', function () {
    Post::factory()->count(10)->create();

    $sortedPostsAsc = Post::query()->orderBy('title')->get();
    $sortedPostsDesc = Post::query()->orderBy('title', 'desc')->get();

    livewire(PostResource\Pages\ListPosts::class)
        ->sortTable('title')
        ->assertCanSeeTableRecords($sortedPostsAsc, inOrder: true)
        ->sortTable('title', 'desc')
        ->assertCanSeeTableRecords($sortedPostsDesc, inOrder: true);
});

INFO

Filament 表格在输出记录前使用 SQL order 语句排序。不同数据库驱动可能使用不同的排序策略,也可能与 PHP 自身的排序策略不同,因此应确保测试记录使用数据库查询的 orderBy() 排序,而不是模型集合上的 sortBy()

测试列的状态

要断言某列对于某条记录具有或不具有某个状态,可使用 assertTableColumnStateSet()assertTableColumnStateNotSet()

php
use function Pest\Livewire\livewire;

it('can get post author names', function () {
    $posts = Post::factory()->count(10)->create();

    $post = $posts->first();

    livewire(PostResource\Pages\ListPosts::class)
        ->assertTableColumnStateSet('author.name', $post->author->name, record: $post)
        ->assertTableColumnStateNotSet('author.name', 'Anonymous', record: $post);
});

要断言某列对于某条记录具有或不具有某个格式化状态,可使用 assertTableColumnFormattedStateSet()assertTableColumnFormattedStateNotSet()

php
use function Pest\Livewire\livewire;

it('can get post author names', function () {
    $post = Post::factory(['name' => 'John Smith'])->create();

    livewire(PostResource\Pages\ListPosts::class)
        ->assertTableColumnFormattedStateSet('author.name', 'Smith, John', record: $post)
        ->assertTableColumnFormattedStateNotSet('author.name', $post->author->name, record: $post);
});

测试列是否存在

要确认某列存在,可使用 assertTableColumnExists() 方法:

php
use function Pest\Livewire\livewire;

it('has an author column', function () {
    livewire(PostResource\Pages\ListPosts::class)
        ->assertTableColumnExists('author');
});

你可以额外传入一个函数,断言该列通过给定的「真值测试」。这适用于断言列具有特定配置。也可以将记录作为第三个参数传入,这在检查依赖于正在渲染的表格行时很有用:

php
use function Pest\Livewire\livewire;
use Filament\Tables\Columns\TextColumn;

it('has an author column', function () {
    $post = Post::factory()->create();
    
    livewire(PostResource\Pages\ListPosts::class)
        ->assertTableColumnExists('author', function (TextColumn $column): bool {
            return $column->getDescriptionBelow() === $post->subtitle;
        }, $post);
});

测试列的可见性

要确认特定用户能否看到某列,可使用 assertTableColumnVisible()assertTableColumnHidden() 方法:

php
use function Pest\Livewire\livewire;

it('shows the correct columns', function () {
    livewire(PostResource\Pages\ListPosts::class)
        ->assertTableColumnVisible('created_at')
        ->assertTableColumnHidden('author');
});

测试列的描述

要确认某列在上方或下方具有正确的描述,可使用 assertTableColumnHasDescription()assertTableColumnDoesNotHaveDescription() 方法:

php
use function Pest\Livewire\livewire;

it('has the correct descriptions above and below author', function () {
    $post = Post::factory()->create();

    livewire(PostsTable::class)
        ->assertTableColumnHasDescription('author', 'Author! ↓↓↓', $post, 'above')
        ->assertTableColumnHasDescription('author', 'Author! ↑↑↑', $post)
        ->assertTableColumnDoesNotHaveDescription('author', 'Author! ↑↑↑', $post, 'above')
        ->assertTableColumnDoesNotHaveDescription('author', 'Author! ↓↓↓', $post);
});

测试列的额外属性

要确认某列具有正确的额外属性,可使用 assertTableColumnHasExtraAttributes()assertTableColumnDoesNotHaveExtraAttributes() 方法:

php
use function Pest\Livewire\livewire;

it('displays author in red', function () {
    $post = Post::factory()->create();

    livewire(PostsTable::class)
        ->assertTableColumnHasExtraAttributes('author', ['class' => 'text-danger-500'], $post)
        ->assertTableColumnDoesNotHaveExtraAttributes('author', ['class' => 'text-primary-500'], $post);
});

测试 SelectColumn 中的选项

若有 select 列,可用 assertTableSelectColumnHasOptions()assertTableSelectColumnDoesNotHaveOptions() 确认它具有正确的选项:

php
use function Pest\Livewire\livewire;

it('has the correct statuses', function () {
    $post = Post::factory()->create();

    livewire(PostsTable::class)
        ->assertTableSelectColumnHasOptions('status', ['unpublished' => 'Unpublished', 'published' => 'Published'], $post)
        ->assertTableSelectColumnDoesNotHaveOptions('status', ['archived' => 'Archived'], $post);
});

测试筛选器

要筛选表格记录,可使用 filterTable() 方法,配合 assertCanSeeTableRecords()assertCanNotSeeTableRecords()

php
use function Pest\Livewire\livewire;

it('can filter posts by `is_published`', function () {
    $posts = Post::factory()->count(10)->create();

    livewire(PostResource\Pages\ListPosts::class)
        ->assertCanSeeTableRecords($posts)
        ->filterTable('is_published')
        ->assertCanSeeTableRecords($posts->where('is_published', true))
        ->assertCanNotSeeTableRecords($posts->where('is_published', false));
});

对于简单筛选器,这只会启用该筛选器。

若要设置 SelectFilterTernaryFilter 的值,请将值作为第二个参数传入:

php
use function Pest\Livewire\livewire;

it('can filter posts by `author_id`', function () {
    $posts = Post::factory()->count(10)->create();

    $authorId = $posts->first()->author_id;

    livewire(PostResource\Pages\ListPosts::class)
        ->assertCanSeeTableRecords($posts)
        ->filterTable('author_id', $authorId)
        ->assertCanSeeTableRecords($posts->where('author_id', $authorId))
        ->assertCanNotSeeTableRecords($posts->where('author_id', '!=', $authorId));
});

在测试中重置筛选器

要将所有筛选器重置为原始状态,请调用 resetTableFilters()

php
use function Pest\Livewire\livewire;

it('can reset table filters', function () {
    $posts = Post::factory()->count(10)->create();

    livewire(PostResource\Pages\ListPosts::class)
        ->resetTableFilters();
});

在测试中移除筛选器

要移除单个筛选器,可使用 removeTableFilter()

php
use function Pest\Livewire\livewire;

it('filters list by published', function () {
    $posts = Post::factory()->count(10)->create();

    $unpublishedPosts = $posts->where('is_published', false)->get();

    livewire(PostsTable::class)
        ->filterTable('is_published')
        ->assertCanNotSeeTableRecords($unpublishedPosts)
        ->removeTableFilter('is_published')
        ->assertCanSeeTableRecords($posts);
});

要移除所有筛选器,可使用 removeTableFilters()

php
use function Pest\Livewire\livewire;

it('can remove all table filters', function () {
    $posts = Post::factory()->count(10)->forAuthor()->create();

    $unpublishedPosts = $posts
        ->where('is_published', false)
        ->where('author_id', $posts->first()->author->getKey());

    livewire(PostsTable::class)
        ->filterTable('is_published')
        ->filterTable('author', $author)
        ->assertCanNotSeeTableRecords($unpublishedPosts)
        ->removeTableFilters()
        ->assertCanSeeTableRecords($posts);
});

测试筛选器的可见性

要确认特定用户能否看到某个筛选器,可使用 assertTableFilterVisible()assertTableFilterHidden() 方法:

php
use function Pest\Livewire\livewire;

it('shows the correct filters', function () {
    livewire(PostsTable::class)
        ->assertTableFilterVisible('created_at')
        ->assertTableFilterHidden('author');
});

测试筛选器是否存在

要确认某个筛选器存在,可使用 assertTableFilterExists() 方法:

php
use function Pest\Livewire\livewire;

it('has an author filter', function () {
    livewire(PostResource\Pages\ListPosts::class)
        ->assertTableFilterExists('author');
});

你可以额外传入一个函数,断言该筛选器通过给定的「真值测试」。这适用于断言筛选器具有特定配置:

php
use function Pest\Livewire\livewire;
use Filament\Tables\Filters\SelectFilter;

it('has an author filter', function () {
    livewire(PostResource\Pages\ListPosts::class)
        ->assertTableFilterExists('author', function (SelectFilter $column): bool {
            return $column->getLabel() === 'Select author';
        });
});

测试汇总

要测试汇总计算是否正常,可使用 assertTableColumnSummarySet() 方法:

php
use function Pest\Livewire\livewire;

it('can average values in a column', function () {
    $posts = Post::factory()->count(10)->create();

    livewire(PostResource\Pages\ListPosts::class)
        ->assertCanSeeTableRecords($posts)
        ->assertTableColumnSummarySet('rating', 'average', $posts->avg('rating'));
});

第一个参数是列名,第二个是汇总器 ID,第三个是期望值。

注意,期望值与实际值会被规范化,因此 123.12 被视为与 "123.12" 相同,['Fred', 'Jim'] 被视为与 ['Jim', 'Fred'] 相同。

可通过将 ID 传给 make() 方法来设置汇总器 ID:

php
use Filament\Tables\Columns\Summarizers\Average;
use Filament\Tables\Columns\TextColumn;

TextColumn::make('rating')
    ->summarize(Average::make('average'))

该 ID 在该列的汇总器之间应唯一。

仅测试一个分页页上的汇总

若只计算一个分页页的平均值,请使用 isCurrentPaginationPageOnly 参数:

php
use function Pest\Livewire\livewire;

it('can average values in a column', function () {
    $posts = Post::factory()->count(20)->create();

    livewire(PostResource\Pages\ListPosts::class)
        ->assertCanSeeTableRecords($posts->take(10))
        ->assertTableColumnSummarySet('rating', 'average', $posts->take(10)->avg('rating'), isCurrentPaginationPageOnly: true);
});

测试范围汇总器

要测试范围,请将最小值和最大值传入元组风格的 [$minimum, $maximum] 数组:

php
use function Pest\Livewire\livewire;

it('can average values in a column', function () {
    $posts = Post::factory()->count(10)->create();

    livewire(PostResource\Pages\ListPosts::class)
        ->assertCanSeeTableRecords($posts)
        ->assertTableColumnSummarySet('rating', 'range', [$posts->min('rating'), $posts->max('rating')]);
});

测试可切换列

默认情况下,只有表格中默认开启的列会被渲染并可供测试。可使用 toggleAllTableColumns() 开启表格中的所有列:

php
use function Pest\Livewire\livewire;

it('can toggle all columns', function () {
    livewire(PostResource\Pages\ListPosts::class)
        ->toggleAllTableColumns();
});

也可以使用 toggleAllTableColumns(false) 关闭所有列:

php
use function Pest\Livewire\livewire;

it('can toggle all columns off', function () {
    livewire(PostResource\Pages\ListPosts::class)
        ->toggleAllTableColumns(false);
});