My Version of "TDD is About Design, Not About Testing"
Before you move on, stop and tell yourself that this time, you will be open to learning about it even if you don't plan on applying it. That you won't make assumptions about it without truly understanding it at a high level.
Read more about it for the benefit of your team, colleagues, and the business so that you can understand both sides (Test Driven Design devs vs. Test After devs or Test No Devs). The difference is important to understand. If you are a Project Manager, VP, or CTO, you need to understand it at a high level.
It's not going away. And it's done on a per developer basis, based on individual choice.
The fact that tests are checked in should not surprise or worry you. You don't have a right to tell test first devs not to write tests. We start with tests, but for reasons you may not be aware of. And this is exactly why you should be reading this blog post.
What one should worry more about is not that we write tests, but that the codebase that continues to become a huge mess, slowing everyone down...or the developers who are wasting time manually debugging for hours or finding more bugs than any team should. We know this happens a lot.
And to those who preach "test later", don't deny it. To those who think they are going to come back to add tests later, you know it never happens. And that's a failed strategy in the first place, I don't care what kind of deadlines you have.
There exists entire teams who practice discipline TDD daily.
TDD adoption is rising and that's great. Sometimes teams do not TDD, and that's fine too!. Some teams have a mix of developers, some TDD some do not, and that's also fine. But know that developers who practice it and have become accustomed to it aren't going to stop doing it, and they do it daily all day long.
oh I know what TDD is...
Are you sure? You need to be sure. I've heard so many tell me this and it's evident that don't have a clue. It may not be what you think it is. There's more than just a subtle meaning behind it.
TDD is Not
- a theory. It never was a theory
- a "sometimes" to those who practice it daily
- about tacking on tests, whether or not to have tests, or when to have tests
- only about code coverage or a "nice to have" or something you dictate with a % to determine whether to write them
- a subtle or casual concept
It Was Proven to Work in 1996 and Continues to Work for Many More Today:
Kent Beck, Martin Fowler, Ron Jeffries, and others at Chrysler invented techniques which became known as Extreme Programming in order to help turn around a project during the time they were brought in to Chrsyler to build a new payroll system system.
We've learned since then that Extreme Programming is not extreme at all, and most of its practices are still spreading strong today. One of those is TDD.
Misunderstandings of TDD Causes Developer Angst
Unfortunately many devs, Project Managers, VPs, etc. don't look it up and invest some time reading about. To make matters worse its very name causes a lot of misinterpretation, misunderstandings, and communication friction between those who practice and rely on it and those who do not.
"no tests this time rule"
It's important that Project Managers, developers, and the business understand what TDD is before casually slapping down the no tests rule as a flat mandate across an entire team, which is not acceptable.
Yes I said it, it's not acceptable to mandate it for every developer on a team. If some developers choose not to write tests, that's their prerogative. If some want to write console.logs all over the place and waste time debugging like that, that's their prerogative. Likewise if others practice TDD, that's what they do. Likewise mandating TDD to every developer on a team is not ok either. Point is, we all "get stuff done" using a mix of techniques and tools. TDD is one of them.
When a developer is told to drop tests because someone else feels they're only a "feature"...whoever is mandating this to a team is operating in a vacuum and is uninformed.
They do not understand that to a developer practicing TDD, it's not even remotely about tacking on tests. It's not a choice. It's about much more as you'll find below for that developer.
They do not realize TDD is now mainstream, and a lot of devs who now rely on it.
It becomes so natural to code this way for a test driven developer, that the thought being told not to write tests simply does not jive. That's not meant to be rude, or uncooperative. It's that to us it's an indispensable tool that we're not willing to forgo, because it's fundamentally how we code the implementation quite literally.
TDD'ers don't think about testing the same way, and more importantly we don't think about the process of designing code the same way. And that should be OK.
It should be ok that some developers on a given team TDD and some don't. It should not matter. And we should be able to do it without fear of retribution or fear that we're not moving at light speed, because developer B over there is. We move at a decent speed but we're not developers who treat our profession as pure numbers by knocking out as many out of the park as we can in a day. If you view the profession like this, based on only velocity per developer, that's going to backfire on you. And you're going to burn out your developers.
Developers should be able to work at a sustainable pace.
This is a profession, not a sweat shop
It's Not About Testing, It's Test Driven Design
It's an indispensable design tool for a lot of developers. It's a lifestyle. I'm sure you've heard this before. And you're going to hear it many times over.
Those who practice it as a discipline feel it would've been better off if it were originally called Test Driven Design which describes it accurately & clearly. It's important for newbies to the term to be aware of this.
We Practice it Daily, not "sometimes" or "casually" or "when we're told we can"
Understand that for those who practice it, which are many these days that
it's the core of how we code on a daily basis:
- it's how we run the code, how we work:
- we write tests to implement & run the code! Simple as that. Fast, easy
- we don't start with "ok lets open up the browser" every time
- we don't think "hey, lets immediately just add console.log lines all over in our code to see if it works" (guess what, that takes time! That's painful. We don't do that. If that works for you, do what you will...we'll respect that as long as you respect that we do it differently)
- instead we run all our tests
- We do this every few minutes, it's part of our flow. So while you are writing console.logs all the time, and opening the browser every few minutes. We run tests, constantly, all the time. Writing or running tests later does not fit the way we code
- To experienced TDD'ists, what slows us down is not writing tests, it's existing messy codebase (rabbit holes), or challenging code that any developer would be slowed by
- pressure to deliver doesn't dictate whether we use it or not
- Unlike test after, we rarely debug; TDD a huge time saver. It's an entirely different experience that you won't understand until you actually do it
- it's how we guide our design as we code a feature
- it's how we determine "done" as we code a feature
- it's how we can pivot fast to new code changes
- it's how we prove the code "works" per the requirements
- its a very quick cycle and gives us a faster, more frequent feedback loop
- it's how we know when we f'd something up during the many code changes we make during a given day
- it's how we know when our code is getting too coupled or that the design stinks. We find this out little by little, AS we are coding fast cycles (not later)
- it forces us to keep lean as we go because we only write enough code to make tests pass/finish a feature
- It's YAGNI all the time
- We don't end up with perfect code, that's not the goal. But and this is a big but: we sure do get pressure to keep it simple all the time as we iterate through the quick TDD cycles. Because our tests will let us know when we aren't keeping things simple. Again, until you have experienced this, you will not understand this
That's what TDD gives a developer who practices it daily, all the time.. Now you know why we don't just "drop it".
- High code coverage
- documents system
Blue step in the TDD cycle => DESIGN
While we do some level of design in all steps in the TDD cycle, the blue step in TDD is by far the most important. And to those who ignorantly claim TDD causes bad design, it's time to read and try TDD before you make such claims.
Red and green in the cycle are about getting code implemented/working fast as possible. Not "perfect". It can even be terrible code. We only care about getting something working that provides value ASAP
It's in the blue step though that we really start using our God given brains and years of experience to design & improve incrementally by applying the following:
- Clean Code practices (self-describing code over code comments, etc.)
We are free to design how we wish.
- does not design for us
- does not cause bad design
It's just that TDD will tell us when that design we've gone with starts to suck because the next test will be harder to code if the design is coupled or has too many dependencies. It tells us when our code stinks. We rely on that feedback often; it helps us along the way, subtly hinting to you when your code needs to be decoupled as you go.
We don't rely on promises to come back to perform big refactorings later; we see that as a failed strategy. When Project Managers promise to add stories to come back later, it does not make sense to us to do that because we do that continuously all the time in small cycles.
It does not slow us down once we get comfortable doing it.
What slows us down is bad code, messy, coupled systems, especially when new to a big codebase.
It takes a bit of time to setup your testing infrastructure if not already setup properly, and a bit of time to get to know the codebase (if not completely greenfield) before a ton of tests start to magically "appear" on top of a codebase not already covered by tests.
Anyone can write tests, but writing good tests comes with experience and critical to be able to benefit from it.
Taking a weekend or a few days to look at a legacy codebase for the first time, before deciding what kind and where to write the first tests should not be a surprise.
Taking a week to setup the infrastructure, should not be a surprise. Weird things happen during setup depending on the language, tools, etc. that a client or team is already using. But..once it's setup, things will start flow.. It's called Sprint 0. And Sprint 0 may not just be one week, it may be two. Just ask the teams on WeDoTDD.com if this is the case with their clients or their team. They will most likely tell you the same.
They Keep Preaching About It !!
There's a reason some think we're over passionate about it.
We know, we know...we're passionate about it because we rely on it...and we can't change that fact. It's a discipline, a tool, a lifestyle that once you get hooked on and get good at it, you never look back or are willing to look back.
Doctors have disciplines they found to work for themselves over time. Would they drop them just because of pressure? No. Software is no different and should not be treated any different. There are and will be disciplines we choose individually to adhere to or not (TDD, DRY, YAGNI, SOLID, Patterns, Clean Code, whatever else comes).
Remember this: We're not saying you have to apply it, but that we already do. and... hey BTW you might like it to. If we are saying you must (mandate), then that's a problem. If we're saying you should, we just wanted to share about the experience we have had with it.
We're sorry, we try not to talk about it too much. Sometimes we do need to shut up about it. If you want to stop hearing about it, just nudge us a bit (but be nice!). And forgive us our daily sins.. No harm done.
It's a personal choice whether to use the technique. We don't and won't ask permission to practice it
We aren't expected to stop using it via a mandate. We understand that others on a team may not be ready to write tests and may not be writing tests, or even wish to use this technique. And we're fine with that. Everyone is at a different place. On the flip side, it's how we code; be fine with that too.
In the end its a tool for the developer, with secondary side effects that naturally benefit the team and business as a result.
When we tell you we write tests all the time, understand who you are hiring, and understand that's a discipline we won't budge on.
It's Still About Team, About Everyone on the Team
I know I said We a lot in here. But we all know that all developers are ultimately a team. We're one. We may use different techniques to get there individually but that we are aligned with the same goal: To deliver working software.
We're All About the Craft of Software...Together
We're here to help each other, and understand differences in both skillset, preference, tolerance, to be inclusive, and to allow autonomy amongst the team but that Individual tools / practices to get there may differ.