Optimizing Your PHPUnit Workflow in Sublime Text

Convincing yourself to skip writing tests is easy when your testing workflow is slow and painful.

Here's some tools and tricks I use to make sure testing doesn't slow me down.

Making your tests easy to write

I've been a big fan of Sublime Text's snippets feature for years.

They make it really easy to generate repetitive boilerplate code, and if you know how to use placeholders and substitutions properly, you can do some pretty magical stuff.

Generating new test classes

Here's a snippet that I use to generate new test case classes:

<snippet>
    <content><![CDATA[
<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ${TM_FILENAME/(\w+)\.php/\1/} extends TestCase
{
    ${0}
}
]]></content>
    <tabTrigger>testcase</tabTrigger>
</snippet>

To use it:

  1. Create a new file (say PaymentGatewayTest.php)
  2. Type testcase
  3. Hit TAB

...and you'll automatically get a new test case with the same name as the file that was created.

Here it is in action:

I spend most of my time working with Laravel, so I include some common imports at the top of each class and make sure to extend Laravel's base TestCase, but you can of course customize this however you need.

Generating new test methods

Here's the snippet I use to create new test methods inside my test classes:

<snippet>
    <content><![CDATA[
/** @test */
function ${1:the_one_where}()
{
    ${0}
}
]]></content>
    <tabTrigger>test</tabTrigger>
    <scope>source.php</scope>
</snippet>

To use it, I just type "test", TAB inside of a test class, and I've got a fresh test method with the proper annotation added, and the method name pre-selected so I can start typing my test name right away:

Both of these snippets save me a ton of time every day, and make it a lot easier to spend the extra time to write tests for a new feature.

Making your tests easy to run

Ever wanted to run just a specific test method? Does this workflow sound familiar?

  1. Highlight the test method name
  2. Copy the method name
  3. Switch to your terminal
  4. Type phpunit --filter=
  5. Paste the method name
  6. Run the command

It didn't take me very long to get sick of this crap, so my pal David Hemphill and I put together a little Sublime Text package called Sublime PHPUnit for ourselves.

Sublime PHPUnit is macOS-only right now, but I'd welcome pull requests for cross-platform support.

Running a single test method

Here's how I run a single test method:

  1. Move my cursor so it's inside the test I want to run
  2. Run the Sublime PHPUnit: Run This Test Method command

I have this bound to option+command+T so I can quickly run the test I'm working on with a single keystroke.

You wouldn't believe how much more often you run a test when it's this easy to run!

Running all of the tests in a file

To run all of the tests inside of a single test class, use this command:

Sublime PHPUnit: Run This File

I have this bound to option+T.

Tying it all together

Here's what my usual testing workflow looks like when I'm adding a new test:

  1. Scaffold out the new test using my "test", TAB snippet
  2. Work on getting that single test to pass, running it on its own with option+command+T
  3. Once that test passes, run the whole file with option+T to make sure I haven't broken any other functionality
  4. Before I commit, run the entire test suite by just running phpunit in the terminal

By only running the tests I'm working with directly instead of the whole test suite, I get extremely fast feedback which makes it easy to run the tests very frequently.

Since it's so easy for me to run just the tests I care about, I'm not constantly punished if my entire test suite takes 10-20 seconds to run.

I've found this makes me less likely to sacrifice high value integration tests in the name of speed, allowing me to get maximum confidence out of my test suite without crippling my workflow.

Trying to wrap your head around testing? Test-Driven Laravel is a course I recently launched that teaches you how to TDD an app from start to finish. Learn more about it here.