How to Separate (and Skip) Laravel Jetstream's Tests
!Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.
I normally use Laravel Breeze to build my projects, but recently I started a new project that needed team support, so I figured I'd finally use Jetstream on a real project, instead of just for fun.
There's a lot I really like about Jetstream, but one thing that bothers me—I know, it's not super reasonable, but whatever—is that it publishes so many tests out of the box. I want them to run in CI, so I can be confident the things they're testing are still covered, but I'd rather skip them locally.
But... how?
PHPUnit Testsuites
PHPUnit allows you to define one or more testsuites
, each of which point to one or more files, and which can be given a name.
In Laravel, here's the default configuration (from phpunit.xml
) (with extraneous information removed):
<?xml>
<phpunit>
<testsuites>
<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory>tests/Feature</directory>
</testsuite>
</testsuites>
So, we're loading two sets of tests, each of which gets a nickname.
Since I want to treat the Jetstream tests as separate from the others, I realized the best way to accomplish this is to move them out of the tests/Feature
folder and into their own folder, and their own testsuite. So, I moved all of the default Jetstream tests from the tests/Feature
directory into a new folder tests/Jetstream
instead, and added a new testsuite attached to that folder:
<?xml>
<phpunit>
<testsuites>
<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory>tests/Feature</directory>
</testsuite>
<testsuite name="Jetstream">
<directory>tests/Jetstream</directory>
</testsuite>
</testsuites>
Note: If you're using Pest tests, you can move these files and they'll just be good to go. If you're using PHPUnit tests, you'll also have to modify the files to update their namespaces from
Tests\Feature
toTests\Jetstream
.
Now, we can control when our Jetstream tests are and aren't running.
If we want to run just one testsuite, we can pass that suite's name to the --testsuite
flag:
php artisan test --testsuite Unit
We can also choose to exclude a test suite:
php artisan test --exclude-testsuite Jetstream
However, what I want is to define that that test suite should be ignored by default; that's not something we can do from the command line.
PHPUnit's defaultTestSuite
Tighten's Keith Damiani pointed me in the direction of the defaultTestSuite
configuration in PHPUnit. It allows to you define which test suites run when you don't pass the --testsuite
or --exclude-testsuite
parameters.
Now that we have our Jetstream
testsuite separated, we can exclude it by default, by setting the defaultTestSuite
property on the base <phpunit>
declaration in phpunit.xml
:
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
defaultTestSuite="Unit,Feature"
>
Loading test suites in Pest
If your app is using Pest, there's a line in tests/Pest.php
that loads the tests in tests/Feature
with RefreshDatabase
as a trait:
uses(TestCase::class, RefreshDatabase::class)->in('Feature');
Since the Jetstream
tests expect a database, you'll want to duplicate that line for the Jetstream tests, and end up with the following:
uses(TestCase::class, RefreshDatabase::class)->in('Feature');
uses(TestCase::class, RefreshDatabase::class)->in('Jetstream');
Wrapping it all together
Here are my steps, simplified:
- Move all the Jetstream tests from
tests/Feature
folder into a newtests/Jetstream
folder. - Add a new
testsuite
for that folder inphpunit.xml
:
<xml>
<phpunit>
<testsuites>
<!-- ... -->
<testsuite name="Jetstream">
<directory>tests/Jetstream</directory>
</testsuite>
</testsuites>
- Update
Pest.php
to load that folder separately:
uses(TestCase::class, RefreshDatabase::class)->in('Feature');
uses(TestCase::class, RefreshDatabase::class)->in('Jetstream');
- Update
phpunit.xml
to run onlyUnit
andFeature
testsuites by default:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
defaultTestSuite="Unit,Feature"
>
That's it!
Now, when I run php artisan test
, it excludes the Jetstream testsuite by default; but if I want to run those tests myself in CI, I still can, with php artisan test --testsuite Jetstream
.
Comments? I'm @stauffermatt on Twitter
Tags: jetstream • phpunit • pest