Expected, actual, and super fast assertion creation

| 3 min read

If you follow this blog[1] you know that one thing I enjoy is improving my workflow inside my IDE. The feeling of productivity of being able to code something in seconds instead of minutes brings me joy and lets me keep my focus on other things. I recently had a new improvements idea for test creation[2].

I think that a great idea to use in tests is to prefix variables with a special role and have a convention for it. My personal preference is to prefix the variable containing the expected result with ‘expected’ and the one containing the value you want to check with ‘actual’.

I decided to create two custom postfix templates that, for some value, create a variable with the wanted prefix and trigger auto-completion to generate the end of the variable name.

The flow goes like this:

  1. Create a value: new Pony(‘Eole’)
  2. Type .ev
  3. Get $expected<cursor> = new Pony(‘Eole’);
  4. Let the autocompletion guide you. Here it will typically suggest something interesting based on the value, like Pony in our example. If you’re dissatisfied with the suggestion, type something else.
  5. Tab ⇥
  6. Done.

See it in action here:
Example of running the ev postfix template

I let you imagine how it works with the av postfix template to get an actual prefixed variable.

It took me a few minutes to get a variable name in camelCase because the auto-completion returns a capitalized name. Thankfully, you can use GroovyScript inside templates, which makes it easy to lower the generated string.

You can avoid the work of recreating those two postfix templates by copying the following snippet in the plugin configuration file.

.ev : Create an expected variable
	ANY -> \$expected$var:capitalize(groovyScript("if(_1) { _1.substring(1) } else { _1 }", phpSuggestVariableName()))$ = $expr$;$END$

.av : Create an actual variable
	ANY -> \$actual$var:capitalize(groovyScript("if(_1) { _1.substring(1) } else { _1 }", phpSuggestVariableName()))$ = $expr$;$END$

But that’s just the first part of the improvement.

Do you speak French and want to stop hating your tests ?

I've created a course to help developers to improve their automated tests.

I share ideas and technics to improve slow, flaky, failing for unexpected reason and hard to understand tests until they become tests we take joy to work with !

But you'll need to understand French...

Now that I had a convenient way to generate my expected and actual value, it unlocked a new idea: let’s generate assertions with the variable already there.

For this, I created a new live template, asseq which adds the code for an equality assertion, $this->assertEquals($expected, $actual); and triggers autocomplete after the two prefilled parameters. Getting an assert equal in a test is now as easy as typing asseq, Tab ⇥, Tab ⇥.

See it here how fast it goes :

Example of running the asseq live template

And here is the live template snippet to add to your configuration if you want to use that trick to.

<template name="asseq" value="$$this->assertEquals($$expected$VAR$, $$actual$VAR2$);" description="" toReformat="true" toShortenFQNames="true">
  <variable name="VAR" expression="complete()" defaultValue="" alwaysStopAt="true" />
  <variable name="VAR2" expression="complete()" defaultValue="" alwaysStopAt="true" />
  <context>
    <option name="PHP Statement" value="true" />
  </context>
</template>

As a bonus, here is the snippet for a second live template that allows you to select what assertion you want because you sometimes need something other than an equality assertion. It does the same thing as the previous one but adds an extra stop and autocomplete step to select the assertion.

<template name="assert" value="$$this->assert$ASSERT$$END$($$expected$VAR$, $$actual$VAR2$);" description="" toReformat="true" toShortenFQNames="true">
  <variable name="VAR" expression="complete()" defaultValue="" alwaysStopAt="true" />
  <variable name="VAR2" expression="complete()" defaultValue="" alwaysStopAt="true" />
  <variable name="ASSERT" expression="complete()" defaultValue="" alwaysStopAt="true" />
  <context>
    <option name="PHP Statement" value="true" />
  </context>
</template>

I hope this blog post will give you other ideas on how to use live templates and postfix templates to improve you workflow and bring more joy to your work life.


  1. You don’t, let’s be honest, no one does 😅 ↩︎

  2. If you followed that blog, you would know that I spend a lot of time speaking about testing. If that’s one of you’re areas of interest, go there. ↩︎