Test-driven: Or, how I saw the light
testing .net c# development tdd test-driven climbdown
T minus 1 month.
In my current project I'm working with a rare-breed programmer. An SDET, a Software Development Engineer in Test. These guys are accomplished programmers but focus on software quality.
"Hey, I write quality software", I say, "It works, doesn't it?".
T minus 4 years.
Working in a software team for a financial shop. The Head of Software keeps talking about Agile software development, Test-driven development, Continuous Integration etc. Sounds like a plan. Try it. Nice idea, can't see how it works. "I always test my code". I say. I do. Console application which wraps the component, fire in data, breakpoint it, verify outputs. Sorted. Job done.
T minus 3 years 11 months.
Cajoled into writing "Unit Tests". Great, double the amount of code to write, same amount of time = less functionality. Features creep, pressures mount, tests get disabled. Code rot. "I write quality software, it works doesn't it?".
T minus 3 years 9 months.
Epic megafuckton of a bomb drops. Trying to debug, fix, unravel. Breakpoints are my friend. "it works on my machine". Late nights. Slipped deadlines. Break original functionality. QA test team get blame. "Test should have spotted this, it's a basic bloody error!".
T minus 6 weeks.
A leopard doesn't need to change its spots. "I've been coding in OOP systems for years, I know the best practices!"
T minus 7 years.
Massive refactor of game engine. Deeply nested inheritance trees. Ugly! Decide to favour composition.
T minus 5 years.
Massive refactor of game engine. Too many hidden dependencies. This OO-lark is a pain!
T minus 3 weeks.
"We need to ensure high code quality on this, try looking at test driven development or something".
"No, that doesn't work. Tried it, takes too much time and gets in the way".
T minus 2 weeks.
Dependency Injection. Heard of it. Tried it in the past, found it to be useful in some situations. I'll learn that later. No rush.
T minus 7 days.
"This code you've written needs a real Cloud Service deployment!".
"Use dev fabric, it's what it's there for! I've written a load of tests to verify it works!"
"But you still need a hard external dependency!"
T minus 4 days.
Trying to test code which relies on something I have no control over. "I know this can happen, but I have no idea when or what causes it. It's part of Azure, how do I sort this?".
T minus 3 days.
"I need to learn this stuff". Spends long weekend reading, on YouTube and more, practicing, practicing, practicing.
The way I write code now is fundamentally different to how I wrote code 7 years ago, 7 months ago, even 7 days ago. I always prided myself on being a half decent software engineer, but ultimately I will confess - the majority of the code I've ever written in my lifetime has been very hard to isolate and test. I've followed best practices as much as possible, but have almost always ended up with hidden dependencies, internal state that's hard to affect or even worse, hard external dependencies.
Having embraced concepts like Dependency Injection, Continuous Integration, Mocking/Faking and Test-driven Development I finally feel like I've added security and confidence around the things I code.
I've tried all this in the past, even blogged about how I didn't get on with it. It's a tough sell. It adds time to development, perhaps even doubles it, but it's worth it.
Using DI and mocks, I can abstract away hard dependencies on external services or libraries and replace them with fakes. I can cause those obscure exceptions and make sure my code handles it. I don't have to wait for a blue moon, I don't have to slay 15 virgin princesses and hope that quantum mechanics favours my outcome today. I can fake the whole thing and force it. I have full control over the environment my code works in. It's like being a god of bits.
What's more, it has fundamentally changed the way I code. It sounds odd, but everything I code now I see the coupling, I see how state migrates between related components. I've done this stuff before, after all it's "good engineering practice", but lets face it - I must have gotten it wrong. Doesn't matter if the odd one slips in there does it?
I realise that to many of you this may be a "well duh". But to me it's a huge swing. A swing in attitude, mindset, approach and style. it's a paradigm shift that required a "click" to happen. I knew all this stuff before, but now I live it. I find it hard to see how I can go back to my old ways.