What can we learn by refactoring without touching our unit tests? A converts’ explanation of outside-in testing.August 26, 2015 @ 8:13 pm Posted to .Net, Mocking, Testing, Unit Testing by Antony Koch
Everywhere I’ve worked develops ‘features’. No great revelation there. However a feature is often, or at least ought to be, quite a small piece of functionality. A stripe of business value carved out of a larger solution. This stripe can be tested and released within a sprint while adding value to the business.
A lot of features can be expressed using a ‘happy path’: that is to say that there tends to be very few ways in which this feature can be executed without any exceptions thrown or any downstream entities not being found.
A typical scenario expressed in Gherkin takes the following form:
Given a context When an action is perform Then there is an outcome
Expanding upon this with a more real world set of scenarios:
Given an Amazon Prime customer When the customer searches for goods Then a Prime delivery option should be displayed Given a non Amazon Prime customer When the customer searches for goods Then no prime delivery option should be displayed
Simple enough, right? Those 6 lines of text define everything we’re about to code up.
So of the time spent coding up, how much of it, in a TDD setting, is spent on unit tests? 50%? 75%? 75% of your time spent writing code that no user will touch.
Now let’s say the next feature comes along and we learn that our initial solution requires some refactoring. Where we once had one query and no commands we may now need nested queries and a single command along with, say, an extra integration point with a cloud service.
How much time do you need to spend rewriting those unit tests? Do you reconsider whether or not to refactor because of the burden of rewriting those tests? I know I have.
Now imaging you had no unit tests. Only acceptance, or black box, tests. Same web page. Same prime indicator. Same test. How much time do you spend writing tests when you refactor your underlying solution?
If you’ve got it right?
100% of your time writing production code. That’s what it’s supposed to be about, right? A bright idea hits you half way through your refactor. Your tests are still green. What’s the cost of experimenting?
You can commit what you have now – it’s working – and start tinkering. Your creativity starts to flow. Your repertoire of of enterprise patterns can come to the fore. Your factory factory loses its purpose: you don’t need interfaces just so you can mock, just so you can abstract.
This may seem somewhat preach, but I feel like this is the right way to do things.
More blog posts are to follow.