Testing Filament with Pest: Resources &amp; Actions | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Testing Filament Resources, Actions, and Form Assertions with Pest        On this page       1. [  Why Filament Tests Are Worth the Effort ](#why-filament-tests-are-worth-the-effort)
2. [  Project Setup ](#project-setup)
3. [  Testing a Resource List Page ](#testing-a-resource-list-page)
4. [  Asserting Table Actions ](#asserting-table-actions)
5. [  Form Field Assertions on Create/Edit Pages ](#form-field-assertions-on-createedit-pages)
6. [  Testing Authorization Inside Filament ](#testing-authorization-inside-filament)
7. [  Infolist Assertions (Filament v4) ](#infolist-assertions-filament-v4)
8. [  Key Takeaways ](#key-takeaways)

  ![Testing Filament Resources, Actions, and Form Assertions with Pest](https://cdn.msaied.com/364/46ec081a3f3b2ebe86d1f88b0d016b4c.png)

  #filament   #pest   #testing   #laravel  

 Testing Filament Resources, Actions, and Form Assertions with Pest 
====================================================================

     4 Jul 2026      3 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

1. [  01   Why Filament Tests Are Worth the Effort  ](#why-filament-tests-are-worth-the-effort)
2. [  02   Project Setup  ](#project-setup)
3. [  03   Testing a Resource List Page  ](#testing-a-resource-list-page)
4. [  04   Asserting Table Actions  ](#asserting-table-actions)
5. [  05   Form Field Assertions on Create/Edit Pages  ](#form-field-assertions-on-createedit-pages)
6. [  06   Testing Authorization Inside Filament  ](#testing-authorization-inside-filament)
7. [  07   Infolist Assertions (Filament v4)  ](#infolist-assertions-filament-v4)
8. [  08   Key Takeaways  ](#key-takeaways)

 Why Filament Tests Are Worth the Effort
---------------------------------------

Filament panels generate a lot of implicit behaviour — authorization checks, form validation, table bulk actions, and page redirects — all wired together through Livewire. Skipping tests means every refactor is a gamble. The good news: Filament ships with first-class Pest/PHPUnit helpers that let you drive the entire panel through HTTP and Livewire assertions, no Dusk required.

Project Setup
-------------

Install the testing helpers if you haven't already:

```bash
composer require --dev pestphp/pest pestphp/pest-plugin-laravel

```

Filament's test helpers live in `Filament\Testing` and are available on the `livewire()` helper once the panel is booted. Add a base `TestCase` that boots your panel:

```php
// tests/TestCase.php
protected function setUp(): void
{
    parent::setUp();
    $this->actingAs(User::factory()->admin()->create());
}

```

Testing a Resource List Page
----------------------------

The simplest assertion confirms the page renders and shows records:

```php
use App\Filament\Resources\OrderResource;
use App\Models\Order;
use function Pest\Laravel\get;

it('renders the order list page', function () {
    Order::factory()->count(3)->create();

    livewire(OrderResource\Pages\ListOrders::class)
        ->assertCanSeeTableRecords(Order::all());
});

```

`assertCanSeeTableRecords` checks that the Livewire component's table query returns those models — it does **not** assert rendered HTML, so it stays fast.

Asserting Table Actions
-----------------------

Table row actions and bulk actions each have dedicated helpers:

```php
it('marks an order as shipped via table action', function () {
    $order = Order::factory()->pending()->create();

    livewire(OrderResource\Pages\ListOrders::class)
        ->callTableAction('mark_shipped', $order)
        ->assertHasNoTableActionErrors();

    expect($order->fresh()->status)->toBe('shipped');
});

it('bulk-deletes selected orders', function () {
    $orders = Order::factory()->count(5)->create();

    livewire(OrderResource\Pages\ListOrders::class)
        ->callTableBulkAction('delete', $orders)
        ->assertHasNoTableActionErrors();

    expect(Order::count())->toBe(0);
});

```

`callTableAction` accepts the action name (the string you pass to `Action::make()`) and the target record. If the action opens a modal form, pass data as the third argument.

Form Field Assertions on Create/Edit Pages
------------------------------------------

```php
it('creates an order with valid data', function () {
    livewire(OrderResource\Pages\CreateOrder::class)
        ->fillForm([
            'customer_id' => Customer::factory()->create()->id,
            'total'       => 199.99,
            'status'      => 'pending',
        ])
        ->call('create')
        ->assertHasNoFormErrors();

    expect(Order::count())->toBe(1);
});

it('fails validation when total is negative', function () {
    livewire(OrderResource\Pages\CreateOrder::class)
        ->fillForm(['total' => -10])
        ->call('create')
        ->assertHasFormErrors(['total' => 'min']);
});

```

`assertHasFormErrors` accepts either a plain field name or a `field => rule` pair, matching Laravel's validation key format.

Testing Authorization Inside Filament
-------------------------------------

Filament respects `canCreate`, `canEdit`, and `canDelete` policy methods. Test them explicitly:

```php
it('hides the create button for viewers', function () {
    $this->actingAs(User::factory()->viewer()->create());

    livewire(OrderResource\Pages\ListOrders::class)
        ->assertActionHidden('create');
});

```

This prevents silent authorization regressions when policies change.

Infolist Assertions (Filament v4)
---------------------------------

Filament v4 infolists are also testable:

```php
it('displays the order total in the infolist', function () {
    $order = Order::factory()->create(['total' => 250.00]);

    livewire(OrderResource\Pages\ViewOrder::class, ['record' => $order->id])
        ->assertInfolists()
        ->assertInfolists(['total' => '$250.00']);
});

```

Key Takeaways
-------------

- Use `livewire(PageClass::class)` — never raw HTTP — for Filament page tests.
- `assertCanSeeTableRecords` checks query results, not DOM; it's fast and reliable.
- Pass action data as the third argument to `callTableAction` for modal-driven actions.
- `assertHasFormErrors(['field' => 'rule'])` catches specific validation failures cleanly.
- Always test authorization explicitly; policy regressions are silent without it.
- Filament v4 infolist helpers follow the same pattern as form helpers.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Ftesting-filament-resources-actions-and-form-assertions-with-pest-2&text=Testing+Filament+Resources%2C+Actions%2C+and+Form+Assertions+with+Pest) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Ftesting-filament-resources-actions-and-form-assertions-with-pest-2) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Do Filament Pest tests require Laravel Dusk or a real browser?        No. Filament's test helpers drive the Livewire components directly over HTTP, so tests run in-process and are much faster than browser-based tests. 

      Q02  How do I test a table action that opens a modal form?        Pass the form data as the third argument to `callTableAction('action_name', $record, ['field' =&gt; 'value'])`. Then assert with `assertHasNoTableActionErrors()` or check the database state. 

      Q03  Are these helpers compatible with both Filament v3 and v4?        Most helpers — `callTableAction`, `fillForm`, `assertHasFormErrors` — work in both versions. Filament v4 adds infolist-specific assertions; check the version's changelog for any renamed methods. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![Object Storage Migrations with Laravel's Read-Through Filesystem](https://cdn.msaied.com/565/f830d15d4a1287d381fa05e631ea2aba.png) Laravel 13 Object Storage S3 

### Object Storage Migrations with Laravel's Read-Through Filesystem

Laravel 13 introduces a read-through filesystem driver that lets you migrate from S3 to R2 without downtime. N...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 18 Aug 2026     4 min read  

  Read    

 ](https://msaied.com/articles/object-storage-migrations-with-laravels-read-through-filesystem) [ ![Livewire v4.4.1 Released: Bug Fixes, Alpine 3.16.2, and Laravel 13 Compatibility](https://cdn.msaied.com/564/c64b65959ad8ade491c78f3482f22996.png) Livewire Laravel Alpine.js 

### Livewire v4.4.1 Released: Bug Fixes, Alpine 3.16.2, and Laravel 13 Compatibility

Livewire v4.4.1 ships 16 fixes and improvements including Alpine.js bumped to 3.16.2, cached computed property...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 18 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/livewire-v441-released-bug-fixes-alpine-3162-and-laravel-13-compatibility) [ ![MySQL EXPLAIN and Query Profiling in Laravel: Finding Slow Queries Before They Hit Production](https://cdn.msaied.com/563/f2d4a7fb0ab45706cf9330746f7b2588.png) laravel mysql performance 

### MySQL EXPLAIN and Query Profiling in Laravel: Finding Slow Queries Before They Hit Production

Learn how to read MySQL EXPLAIN output, use query profiling tools, and integrate them into a Laravel workflow...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 18 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/mysql-explain-and-query-profiling-in-laravel-finding-slow-queries-before-they-hit-production) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
