Custom Development

Unit Testing Your UI

Gabriel Obregon

I’m a huge fan of unit testing front end code no matter what platform I’m coding in. The rule about being smart about what you test is even more important with UI code. Uncle Bob said, “having dirty tests is equivalent to, if not worse than, having no tests.”

While Uncle Bob was talking about poor code in the tests, I believe it also applies to testing the right things. It is very easy to test the wrong things or things that don’t really matter. It’s a bad idea to test something that is a certain color or width (of course there could be cases where this needs to be tested). If your code is adding a class selector to an element, then you should definitely test that the class is being added, and that it’s being added at the right time.

Unit testing will improve your UI code architecture and without it, people will tend to lump a lot of code in the View Controller. I will usually catch myself doing that in iOS View Controllers or in my Backbone Views. If there are unit tests in place then just move it to another class and use the tests to make sure everything is working. This is something that has always been done in the back end, so why not in the front end?

There are three ways to unit test, explained beautifully in this video:

  • Return Value Verification. You call a method and make sure the correct value was returned.
  • State Verification, an action or method is called and you verify that the state has changed as expected.
  • Behavior Verification, an action or method is called and you verify that it calls the correct subsequent method.

I find myself using Behavior Verification the most when testing my UI, and with good reason, the UI is supposed to trigger something.

Unit testing your UI can be tricky though. Most tests will be Behavior Verification so you will have to be well acquainted with mocks, stubs, and spies from your chosen testing framework. That being said, like with all unit testing, if there are too many mocks in a test suite then it’s time to do some refactoring.

Let’s talk about a simple example for testing UI, events. There’s a very high probability that you will have events in your UI code, especially with JavaScript. This is something that I always make sure I test. Events are identified by strings, which can be tricky to debug. I always write tests to ensure that I’m subscribing to the right event, that I’m unsubscribing when the object is being destroyed, and that the right methods are being called when the event is fired.

AngularJS might be my favorite for testing events because when you subscribe to an event it returns a deregistration function for the listener. All you have to do is spy on that returned function when the scope is being destroyed. Memory leaks with zombie event receivers are never good. Tip: when the scope is destroyed, AngularJS automatically takes care of removing objects that are $watch-ed so you don’t have to worry about those.

While reading Testable JavaScript (highly recommended) there was a quote that stood out for me and was quickly highlighted. “If it is not testable, maintainable, and understandable, it is trash.” While that sounds harsh, I have to agree with it. As consultants we have to write code that is maintainable. We are not going to be on that project forever, so it will be up to someone else to maintain it. Tests help others understand what is going on in our code, they also help us write more readable concise code. Finally and the most obvious one, tests will alert someone if they broke something. UI code is no different and should be treated as a first class citizen when it comes to writing tests. Fortunately, there are more than enough tools to aid us in this. It doesn’t matter if you choose a TDD or a BDD framework, what matters is that there are good tests.

I hope this post was helpful and gave you a few pointers. How do you test your UI? Let me know if I left anything out!

Gabriel Obregon

Summa Alumni