How designers can use unit testing to build resilient and happy design systems
Adapting a method from programming for product design
Design systems! Atomic design! Pattern libraries! Over the last two-ish years, these concepts have picked up speed in the design community. Some of us at Vox Product even attended a conference last month about design systems and living styleguides.
Design systems help us determine what “lego pieces” make up our larger product, whether that’s a button or heading styles. Creating a design pattern library helps us document these lego pieces, so that teammates and other humans can easily understand what they are, why they are, and how to use them.
Only recently have I begun to fully embrace design systems because I’ve actively seen the advantages they provide. On the flip side, I’ve seen the world of pain in which you can find yourself if you don’t embrace design systems. Seriously, try refactoring CSS in an old codebase — for the third time — and finding six different variations of one button. 😱 No thank you.
But what goes into the process of actually integrating a new design pattern into a design system? How does a small, lego piece piece of a design, like a “primary action button” find itself on the “Buttons” page of a design pattern library?
Let’s imagine that you’ve already gone through the step of realizing that a design pattern is needed for a particular use case. In the case of our button, we’ve come to realize that we use buttons everywhere in our application, but we need a differently styled button that will draw the user’s attention, called the “primary action button.” Great! But what happens after that decision is made?
Well, you could just design it, code it, and put it there. But lately, my team and I have been treating the placement of new patterns into the pattern library with great scrutiny. We follow a “unit testing” process for each design pattern we introduce.
Unit testing: stolen from programming, adapted for design
Unit testing in programming is a process in which “the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation.” The point of unit testing is to make sure a small, atomic unit of software can be healthily integrated into a larger software ecosystem without breaking everything, either now or in the future.
With the rise of design systems, it makes sense to apply this method of unit testing not only to code, but to design as well. Before integrating a unit of design into a holistic design system, we must scrutinize it from every angle so that it doesn’t upset the ecosystem.
Our unit testing process at Vox Product
Okay, I’ll fess up. “Unit testing in design” in practice is really just another fancy name for a design review. On our team, unit testing occurs as a collaborative exercise, much like a traditional design review. We gather ’round, take a look at the patterns our teammates have built, then we review and have a discussion around what’s being presented. Our team is made up of Front-End Designers, so the presentation of the patterns is done in either a Sketch file or code.
On our team, all design patterns are tested for:
- Uniqueness: Is this design pattern necessary, or can we use an already-built pattern instead? What new thing does this pattern offer us?
- Reusability: Is this design pattern abstracted enough to be reused elsewhere in the application? (Whether it’s the code that’s abstracted, or the general concept of the component itself.)
- Statefulness and Interactivity: Have we covered all bases regarding state with this component? We use this checklist.
- Clarity (in language, motion, and code): If code is presented, is it clear? Does it follow our code styleguide? (We use BEM, mixed with utility/helper classes.) If copy is present, is the language clear and friendly, or is there ambiguous terminology present? (Ideally, you’d have a UI copy styleguide to check against.) If animation is present, is the transition clear and does it make sense, or is it superfluous and confusing? Can you conduct user testing to find answers to these questions?
- Responsiveness: Depends on the product, but most products should be small screen friendly. Does your design pattern scale gracefully?
- Accessibility: If code is presented, does it follow accessibility guidelines? If colors are used, does the pattern pass color contrast tests?
These six categories are roughly what a design review of design patterns focuses on. This type of review would not be suitable for design reviewing a product’s design more holistically. Hopefully by the time you’re actually building out design patterns, you’ve already completed an earlier layout/UX/flow/information architecture stage. There is a separate list of questions you should be asking at that stage, which I won’t go into here.
Unit testing builds resilient systems that can be reused and shared
Our company is maturing, and so are our platforms. This means more people are joining the team, touching the platforms, and launching new ones, whether public-facing or internal.
By creating reusable components that have been thoroughly tested, you can begin to share these components across products and platforms. My team at Vox Product, Revenue Platforms, has two major platforms that we currently support and actively develop upon. These two platforms each have their own design pattern libraries, but many of the patterns (if not most!) are shared between the two platforms. This type of sharing allows for more rapid prototyping and development, a shared language and understanding between two teams, and overall promotes a collaborative culture of design and code. Because one of the most challenging parts of creating a sustainable design system across a large organization is getting other teammates to use it, establishing a collaborative process up to the moment of integration can make it easier. When people collaborate on something, their buy-in is increased.
It’s important to not reinvent the wheel each time we need to add something to a product or platform. It’s also important that something you’ve added won’t break the system because it’s half-baked or confusing. That’s why you should invest time to thoroughly vet a design pattern before adding it to your system. The most important item on our unit test checklist is arguably: Are we reusing our existing components and patterns? Building a resilient and happy design system might not necessarily mean growing it, but polishing and fortifying it instead.
Thanks & Acknowledgements:
Thanks to my teammates Sanette Tanaka and Mandy Brown for their review and feedback.
The idea of unit testing for design has been brewing in my head for a while, and last month Donna Chan and Isaak Hayes from AppDirect mentioned it very briefly during their presentation at Clarity Conf, so thanks Donna and Isaak for giving me the nudge I needed to write this.
This post originally appeared on Vox Product’s blog.