Just. Stop. It.
Ok, now that I’ve got that off my chest let’s lead with an example.
In programming there is a practice of writing codified tests for other code that you have written. Another practice is to pontificate about the right and wrong ways to write said code and said tests and there can be many heated debates about right and wrong. Most often than not, my experience of these debates tends to go between the following two types of evidence to support a claim:
- I read about this in a book by someone and therefore it is true
- I tried this out a few times and experiences it first hand and therefore it is true
Unfortunately both of these approaches have drawbacks because it is important to understand the underlying values of the individual making the claim and the basis of those values.
Ultimately values need to be based upon reasonable evidence and fact. A value exists as an expression of something important in achieving a particular goal. This is where things can get slightly muddy because goals can be both objective, subjective and can quite happily conflict with other goals. I think there is probably something to be done regarding whether or not a goal needs to be based on fact or fiction.
I’m digressing. Allow me to try and pull this back on topic.
When writing tests there are a couple of approaches.
Generalise and refactor aggressively
This means split out test methods, test data, test assertions and all the various other test utilities so that they can be shared by lots of other lovely tests. The values which lead to this I’ve found are typically found in the misconception of the DRY principal (Don’t Repeat Yourself) and the desire to do Object Oriented Programming (albeit unknowingly poorly). The problem is that there are lots and lots of books and expertise around misconceived OOP and DRY which means that many people who don’t examine the basis for these principals and try to re-prove and assert them for basic principals tend to blindly follow the statements, behaviours, additional value and various other bits and bobs that the sources of expertise present.
Keep everything contained within the same method
This means that setting up the test data, performing the various operations and running the assertions is all done inline in the test method itself. The values which lead to this I’ve found are to do with ease of reading, ease of debugging and ease of keeping isolated. The major elephant in the room here is that the more code there is then the less readable something is.
So, where do I stand?
My goal is to effectively, efficiently and easily write code that someone else can pick up as quickly as possible and change. The reason for this goal is that the most costly part of software development is the time it takes for a developer to pick up code. A contract developer for example spending a week on a piece of code is the same as blowing at least £2k out of the window plus any lost revenue from the additional time taken to get the fix/feature out of the door. The cost of Infrastructure today is so cheap that it is literally pennies in comparison to the cost of developer time.
I stand on the side of keep everything contained within the same method. My reasons for this are that there is no misdirection or generalisation that can frustrate the developer. If the test is sufficiently complex then a better solution would be to have a single test per test class and break the test method into meaningful methods so that it is easier to read, but in this situation under no circumstances should that test class be expected to perform additional tests as this will make it way to easy to attempt to share these extracted methods and really start fucking things up.
As a final piece to this, is copy paste really so bad? Seriously, what is wrong with it? Why are we so lazy that we will happily handicap future development in the name of not typing Ctrl+c, Ctrl+v?
If you have a different viewpoint to this then please feel free to provide comprehensive reasoning. If you find there are gaps in my reasoning then please feel free to expose them so that I can attempt to fill them in or change my view based on new evidence.