It’s been a year and a day since my last post. Plenty has been going on in the last 12 months. I finally took the dive into mobile that I’d been putting off until the tools improved, with a rebuild at Which? in London.
Which? made some bold technology decisions to break with their legacy codebase. Previously using Java in the web app and API layers of the stack, they kept it for the API and adopted Ruby on Rails for the web application.
I’d heard great things about how fast you could build stuff with Rails. I didn’t come to front end development via a server side language so a framework like Rails, that gives an easier introduction to that layer, has great appeal. Without a doubt it’s enabling and makes you a better all-round developer.
Another big thing that learning Ruby has given me is the ability to write automated UI tests with Cucumber. I had heard about CucumberJS early last year but it looked a bit in-progress. Cucumber with Ruby looked more complete with better docs and plugins.
Regarding BDD and the practise of describing features using Given.. When.. Then syntax, that are readable by the business – I’d heard experienced consultants saying things like
“Feature files are a nice idea but I’ve never actually seen them used by a business in real-life”
I don’t buy that view – at Which? the features have been described by a business analyst in Jira then handed over to us to automate. We might make some minor tweaks in language not meaning, to make it possible to automate them.
The company, developers and QA then have a clear contract for what we’re building, and even better, we can code directly against it. When we fulfil the contract, the tests turn green.
BDD is of course an investment – in mocking up the data, working out robust ways to test the code, trying to make the tests run as fast as possible, and dealing with occasional (and sometimes inexplicable) fragile tests that work one minute then fail the next.
Finding a balance between unit and UI tests
You burn through a lot more unit tests because they’re more tightly tied to the implementation, which in any decently maintained codebase should be evolving constantly as it’s refactored. Parts of your code inevitably get thrown away, implementations change and the unit tests frequently turn red until you turn them green again or remove the redundant ones. The closer the tests are to the metal, the more ephemeral they are.
On the other hand, a UI test, once turned green should only turn red infrequently – if there’s a breakage in the interface, or if a refactor is significant enough to require the parts of the step definitions that touch the implementation, to need updating.
Again, am I saying don’t write unit tests? Absolutely not. They can guide the design of lower-level logic and help find flaws in it. And they can instantly expose regressions as you refactor.
I’m just questioning some commonly received wisdom that you should have orders of magnitude more unit tests than UI tests. All tests are an investment – the time spent writing and maintaining them gets paid back in fewer regressions and production bugs.
I’m totally sold on the BDD way of working now. You won’t always find it happens in a project – I’ve come across the odd very capable front end developer who didn’t see it as part of their role to write UI tests. Although it was in a technology stack that didn’t make it easy to write UI tests (hello Java).
Some QAs get nervous about developers doing it, but they shouldn’t. If the devs write UI tests for the web app that mock out services like authentication and APIs, then it frees up the QAs to write those true end-to-end tests using real copies of the services.
Writing tests and seeing them run green gives calm to the developer. You don’t get that sick feeling in the run-up to a release that you might have caused regressions with your last commit, but aren’t sure where. The better your tests, the more secure you feel. If you haven’t, try it!