How to use a local MinIO S3 server with Laravel, and automatically configure it for your Laravel Dusk test suite
If you're writing tests for your Laravel application and you need to interact with its storage system, you might have come across the Storage::fake()
method. This method brilliantly fakes an entire filesystem disk, whether a local disk or an external disk like an S3 service. As a result, you don't have to rewrite a single thing in your code. For end-to-end tests with Laravel Dusk, there are helper methods as well. For example, an attach
method easily attaches a file to an input element.
While this covers most of the testing tools you'll ever need, I've found myself in need of interacting and testing with a real, live S3 service. In my case, I implemented S3's multipart upload feature and wanted a complete end-to-end test. I want to ensure that everything, from attaching a file to the input element to handling the multipart upload, is guaranteed to work.
I've stumbled upon MinIO, an open-source storage suite that runs on all major platforms. It's super lightweight and still fully S3-compatible. There's hardly a thing you have to configure to make it sing with Laravel. You need to point the endpoint
and url
configuration key to the MinIO server and set the use_path_style_endpoint
configuration key to true.
AWS_ACCESS_KEY_ID=userAWS_SECRET_ACCESS_KEY=passwordAWS_DEFAULT_REGION=eu-west-1AWS_BUCKET=bucket-nameAWS_URL=https://127.0.0.1:9000AWS_ENDPOINT=https://127.0.0.1:9000AWS_USE_PATH_STYLE_ENDPOINT=true
To make the testing part even more effortless, I've created a little package that automatically starts and configures a MinIO server for each test. It works fantastic on GitHub Actions as well. You can choose to start a new server for each test or use the same server for the entire test suite. You only have to add a trait to your test, and add the bootUsesMinIOServer
method:
<?php namespace Tests\Browser; use Illuminate\Foundation\Testing\DatabaseMigrations;use ProtoneMedia\LaravelMinioTestingTools\UsesMinioServer;use Tests\DuskTestCase; class UploadVideoTest extends DuskTestCase{ use DatabaseMigrations; use UsesMinioServer; protected function setUp(): void { parent::setUp(); $this->bootUsesMinIOServer(); } /** @test */ public function it_can_upload_a_video_using_multipart_upload() { }}
In the README.md of the repository, you'll find how to configure GitHub Actions to use MinIO for your test suite.