Testing our design system components
Avoiding the unforseen consequences of change
We have lots of components in our Pulsar design system, but for this post I’m going to focus on just one. The button.
Buttons are prolific in our software, they do lots of different things and they need to be consistent, recognisable and predictable. Our buttons can have a handful of classes applied which define the colour (primary, success, danger etc), visual variations (small, outlined, naked) and the state (disabled, active) as well as the normal set of interactive states that a button needs to support (hover, active, focus).
We test lots of things about our humble little button, like:
- Is the markup generated by the button helper correct?
- Does the CSS render the button variations correctly?
- Do all of the colour combinations match what we expect?
- Has anything else changed that we weren’t expecting?
Part 1: Testing the markup
Helpers let us provide, for want of a better description, an API for the UI. Instead of using the raw HTML markup for a button in a view, we can call the button helper with a set of options, and the relevant markup will be created for us when the page is viewed in-browser.
will spit out the following HTML:
<button class="btn btn--primary">Foo</button>
I know you’re probably wondering “why is this any better than normal markup” and admittedly, a button is probably the least impressive example I can give (form elements have a good amount of wrapper markup), but we’ll keep it simple with buttons for now.
There’s a few documented options that a button may have. Supply
'type': 'link' and you’ll get
<a href="#" class="btn btn--primary">Foo</a> instead of
<button>, as well as different markup for
submit types too. We need to test all of those to make sure the markup created by our helper is correct, valid and that any other supported options like
disabled are added as correctly formatted attributes.
We have a suite of fixtures, which consist of a
.twig file (the input) and a matching
.html file containing the expected output. The Twig fixtures all run through PHPUnit and their output is matched against the ‘expected’ HTML file. The Pulsar repository has hundreds of fixtures being tested in this way, everything from buttons to more complex components like the primary navigation module.
As an example, if I intentionally add a
newClass class to the helper and run PHPUnit again it will fail any fixtures that weren’t expecting a button with
newClass. If the change is expected, I can verify which components are depending on the button helper and may be affected by the change or, if the change to the helper wasn’t expected, I can fix that instead!
Taking the time to write unit tests for our helper markup helps massively when it comes to refactoring and bug fixing, we can quickly run the test suite to confirm that our changes within Twig have not affected the markup in ways we weren’t expecting.
But wait, there’s more!
So we have this comprehensive fixture suite pulling double-duty, testing our generated markup is correct in both the PHP and JS implementations of Twig. In my next post I’ll show how we use the same fixtures again to test the visual output and let us know if anything changed, right down to the pixel.
Header image from Black Mesa, used under fair use.