Quickly Generating Tests Files For Your Laravel Application
Published 06/11/2021 | Last updated 17/12/2021 | 986 viewsKeep your test directory in sync with your application structure and keep your test suite organised
One of the biggest challenges when writing tests is maintaining a readable suite over time. When I first started writing tests, I would place everything in the root of the tests
directory. As you can imagine, once your test suite begins to grow, this can quickly get messy.
I've tried a lot of different methods for organising tests over the years, but the more tests I write, the more I realise that I want my test suite structure to match the structure of my application. For example, if I have a UserController
in the app/Http/Controllers/Admin/UserController.php
file, I want a feature test at tests/Feature/Http/Controllers/Admin/UserControllerTest.php
.
The issue is that it's super annoying to have to keep these folders in sync. Typing out these long namespaces twice (once for the controller and once for the test) each time I create a new class is super frustrating. In code, anything that is super frustrating usually needs a better implementation.
So, as of Laravel 8.65, you can now add the --pest
or --test
option to various php artisan make
commands. When you do, you'll get a matching test for that generated class. Here's an example:
In this example, two files have been generated:
- app/Http/Controllers/Admin/UserController.php
- tests/Feature/Http/Controllers/Admin/UserControllerTest.php
Nice, hey? It's less work for the developer, which makes it more likely that we'll actually create the tests in the first place. Afterall, it's now just 4 letters away. Here are the Artisan commands you can use it on currently:
- php artisan make:command
- php artisan make:job
- php artisan make:listener
- php artisan make:mail
- php artisan make:model
- php artisan make:notification
- php artisan make:controller
- php artisan make:middleware
Adding matching tests for your own artisan commands
If you're a Laravel package developer, or even if you have a large Laravel application, you may have a few of your own custom make
Artisan commands. You'll be happy to know that it's insanely simple to add this functionality to those commands. There are two requirements: your command extends the Illuminate\Console\GeneratorCommand
class and you use the Illuminate\Console\Concerns\CreatesMatchingTest
. Here's an example:
<?php namespace Illuminate\Foundation\Console; use Illuminate\Console\Concerns\CreatesMatchingTest;use Illuminate\Console\GeneratorCommand; class MyCustomMakeCommand extends GeneratorCommand{ use CreatesMatchingTest;
That's it! Simply by adding the new CreatesMatchingTest
trait, your custom Artisan command now has a --pest
and --test
option that will allow other developers to easily add matching tests when using your command.
Wrapping up
I'm a big believer in convention over customisation. Sticking to a single paradigm is essential for a maintainable test suite, and the new --pest
and --test
options help enable that with no extra effort.
I hope you like this addition to the framework as much as I do. Keep writing those tests!
Regards, Luke