UI Engineers that don't write a lot of automated tests often find that deciding 'what' to test is their biggest challenge.
They normally encounter a couple of issues when deciding the best approach to take;
But these problems are not really caused by testing.
They are caused by programming itself.
Programming is an activity that carries a lot of uncertainty. We don’t really know what we need to begin, much of our time is spent learning about the tools we are using, and the system we are building is not completely understood.
In order to decide ‘what to test’ we need to try and remove uncertainty. We should do this by focussing on what matters.
And ‘what matters’ when we want to test an app is the ‘specification’. The specification is simply the piece by piece account of what the software should do from the perspective of the user!
Now, this is probably nothing new to you.
Most UI engineers know….
They have an array of tools available to help focus on the specification like end-2-end tests with Cypress, Selenium browser scripts, the React Testing Library and other tools like Protractor etc…
But let’s face it; most tools are incredibly heavy weight. They have to use complex file structures, difficult to remember configs, extremely slow IO processes and they struggle to be easily set up in CI servers. Added to this these tools also take their toll on our productivity because they are difficult to learn!
But… contrary to complex integration testing tools is the humble unit test tool like Jest or Karma – it’s simple, it’s fast, and it's easy to understand.
But the problem of not knowing ‘what’ to test is amplified by the humble unit test because they infer no knowledge of specification; they just exist at the micro level. And even when we know which ones to write they can often just become a long list of tests that no one understands apart from the original creator.
Wouldn’t it be nice to be able to use a simple unit test library whilst being able to focus on the specification of the system like we do when we use integration tools?
That way we would have what we need; ‘tests as specifications’ but without all the heavy weight tooling. You might say this helps us comply with the Pareto principle (where 80% of the benefit comes from 20% of the effort).
Well you CAN do this…and it’s actually not that hard. Let me explain...
What you do is decide to ‘focus on what matters’, because most UI engineers and testers do not realise that testing is not really about testing. Testing is actually about something else far more important.
It’s about 'thinking'!
When we develop a UI app, instead of focussing on tools which are about how frameworks work, we should focus on setting the code up in a way that mimics how we think. Setting up code about how we think has a special name – it’s called ‘architecture’.
And this is the critical thing that most UI engineers forget when they test an app. A UI engineer should be focussed not on the tools, but instead having a good UI architecture. Specifically; having a testable UI architecture!
In our course Ultra-Fast Testing and TDD we teach engineers how to go about creating a testable architecture by visualising everything inside a black box.
This black box is a mental model we use to solve the problem of ‘deciding what to test’.
What we say is that instead of relying on heavy integration tools. We are going to focus on creating a boundary around our code by keeping a very clear distinction between the code that serves the ‘UI framework’ and the code that serves the ‘Specification’. We can also call this an 'outside in' approach.
When students begin doing this; I see something magical happen. I see them begin to describe and test the system in unit tests but... from the perspective of a user.
So, because they are doing this architecturally their tests are much much simpler to read, why?
Because they achieve testing focus without ‘overhead’. The focus of specification inside each test without the complexity of having to drive tools or read HTML is something to marvel at because...
This helps them write better and more effective code and tests because they are working smart!
So, in conclusion I really recommend testing using the approach of simplifying your toolset and focussing on UI architecture before dropping in complex integration tools.
Using the black box and considering a UI architecture that lends itself to an ‘outside in’ approach to UI architecture is paramount if you want to keep your life simple and write code and tests which scales. In summary…
Hope you enjoyed this article.