BTW, I meant to say that I totally agree with this article, Roy, and on the Twitter convo that birthed this post.
Thank you again, Roy, for a very well-thought-out post. I really hope that we can achieve what you map out here. This coupling has bothered me for some time now, though I've been more narrowly focused on TDD as a stand-in for the SOLID-coupled camp. Unfortunately, most sources you find when searching for information on "unit testing" are (right now) going to be those with this tight coupling. Changing that will be... difficult...
"...just get people to start testing today and learn SOLID later..."
That sounds like you want to sale me something :) and that magical "just" keyword is not just (he-he) a coincedence.
I agree with the idea of the post, but there is an unfortunate and very real problem with it. Unit testing poorly written/designed code is really tough. I almost gave up on the idea years ago because it was so hard to write tests for my poorly designed applications. I've spent the last couple of years learning about better design practices and now I find TDD much easier.
Overall I like the idea, I just think its going to be hard to teach
if someone is so poor as a developer that they canning understand an apply SOLID (5 simple rules which should take no competent developer more than a couple of weeks to grasp) ... Why do you think they ate competent enough to write even a simple unit test?
As an example ... Our current project has a class for ProductCode ... It requires no mocking to test, requires no application of SOLID to write or test, and has 70 odd unit tests around it ... To write those tests well took far more experience and time than would ever be required to learn and applly SOLID
I think the part that may be the issue here is that good design patterns are trivial to learn ... Applying them well is harder but still not rocket science ... TDD in any meaningful way is considerably harder than both long before you get to mocking or SOLID
You argue that TDD could be better of alone with out SOLID, and people could learn SOLID later.
But since SOLID is the pre-request of good TDD, why would you want to turn this up side down?
To make $$$?
I would much rather people started learning SOLID and did no TDD.
So its SOLID then TDD, not TDD(with out the design aspect) and then SOLID.
Ultimately, on the purely theoretical side, I agree that TDD and SOLID design have no reason to be coupled. If they assist each other, that's awesome, but there's no need to make one a prerequisite for the other.
However, looking at the bigger picture, there are other factors to consider. To me, it seems that software engineering is in some sort of trouble, mainly because a lot of those who work in the field are insufficiently educated and unskilled in their craft, thus dragging the entire industry down.
The high demand for software, and the "programming is easy for anyone" approach cultivated by many for the past couple of decades, have made people believe they can practice software engineering without being proficient in it, and have contributed to software engineering becoming an industry filled with mediocre workers and mediocre quality products.
Making TDD easier on the programmer who doesn't employ SOLID will cause greater integration of TDD principles in the industry, but at the same time it will legitimize building software that is badly designed, as long as it's tested.
The current coupling of TDD and SOLID presents a sort of healthy ultimatum to the uneducated programmer: either learn how to design well and gain the ability to test your code, or stay uneducated. Simply put: if you want to be any good, you have to learn how to practice your craft well.
This choice might leave some in the warm embrace of amateurism, true; but it will cause others, who wish to become better at what they do, learn how to design software well AND test it.
With TDD simplified and the barrier for entry lowered, a middle class will be created: that of programmers who know how to test their code, but don't know how to design it. Some will go on to learn SOLID, but many, I fear, will be comfortable staying at that level - which would be a loss for the industry as I see it.
Simplifying TDD creates a sort of "magic bullet" that gleams at the uneducated programmer, hinting: "there's no need to know how to do things right". I feel that in the current state of the industry, this is not a good idea.
I hold good design as more valuable than test coverage (this might be the only point where we differ, and the heart of this comment). I'd rather "win over" those who would take on SOLID for the sake of TDD, than "give up" those who would forsake SOLID because they have a simplified way to do TDD.
I think most of the people that are arguing for SOLID first (and foremost) and then everything else are missing one important point; not all us poor developer soles are computer science (or the related) graduates.
The industry is thriving with professionals that were lured into the field by the unresistible attraction of long hours in-front of the keyboard to bring to life something you designed (sorry Roy, beat you to the world’s worst analogy)
Didn’t the success of Ruby and similar dynamic languages teach the industry that its not all about UML, factorings, SOLID and all the OOD jargon that though serves great interview show-off does not impress management when they talk about delivery and care less about maintainability, QA, CI, …etc.
Of-course developers should care and that’s why Agile and TDD is causing a lot of stir and curiosity but speaking out of experience the charge of entrance is too high that most just stay watching from the fences.
I am all about tools and frameworks that make all this attainable for us mere mortals and I am sure that most would pick-up SOLID and OOD as an evolution to already attained understandings and skills.
"It allows developers in a non-agile environment to do little,incremental steps on the road to a better way of working, without needing to chow down the whole meal in one big bite."
This is not simply 'hitting the nail' on the head; this is *sledgehammering the railroad spike* on the head. Excellent post, Roy. It seems that people don't understand that you don't want the software engineering discipline to become diluted by dimwits - on the contrary, you want lead people down the right path, and you're tossing around some great ideas about how to do it.
It's really a question of how to be Agile about "how to be Agile".
It's about how to capitalize on the TDD benefits incrementally, as opposed to some sort of "waterfall"-like training program that is supposed to change the mindset of every team member in one big leap without any stepping stones in between.
I think you are right, Roy. Personally, I think the code smell driven training is the best. It was the approach by Bob Martin in his book. If you have a certain smell, chances are that you are violating a principle.
Smell type A usually is the symptom of violation A or C. A and C have each an associated list of patterns that may be investigated.
That's what did it for me. Do TDD and investigate smells. Smells in the tests and smells in the codebase.
What's a unit test anyway?
Is it any class that happens to have a TestFixture attribute on it?
What value would that provide?
Wow, Udi is now trolling. What's next? JDN commenting in full agreement? :-)
you should just stop talking. yer posts are freaking irritating and for the noobs.
I think it's a bit strange that you recommend to buy your book. Because it's not even finished and have been in the working for a long time now. and because there are several things in the book that contradict what you are saying here on your blog. Here are some quotes:
"there are always those who
feel that opening up the design to be more testable is a bad thing because it hurts the “object Oriented” principles
the design is based on. I can wholeheartedly say to those people now “Don’t be silly”." page 53
About Typemock "Some people claim that can even be too powerful (I’m one of them)" page 84
Karsten: indeed, when I started writing this book, about two(!) years ago, I had different opinions on Typemock and testability (or rather, less dilemmas about these issues).
These comments were changes to reflect my current thinking in the latest book cycle.
the good news is the book is just about done now.
regarding the comment on page 53 - I still hold that SOLID is a good way to design (on top of OOP) so "Don't be silly" still holds.
Also, suggesting my book was a bit of a tongue in cheek since it was in the middle of me saying how people can profit off the situation.
There. I explained the joke. It's dead. happy?
Udi: What the hell are you talking about..?
>Karsten: indeed, when I started writing this book, about two(!) years ago..
I fully understand that you have changed your mind.
>the good news is the book is just about done now.
That's great, I'm excited to read it and also excited to see if you will change your examples to use Typemock instead of Rhinomocks :-) Now don't get me wrong, I think the book (what I've read in it) is good.
>There. I explained the joke. It's dead. happy?
Hmm what was the joke again. Do you recommand designing for testability?
Actually I am still using Rhino in my book because Typemock Is still a commercial product.
Ok. I think I am beginning to see what you are saying Roy. What I am not sure now is why has this post triggered the discussion of doing TDD without the SOLID principles?
I see this post as you saying to the average developer..
'keep developing in your comfort zone., let me show you how to write good tests on top of your code., so you can have good maintainable tests to start with'
I think this is achievable. But to write tests first and then code that makes the test pass without any SOLID principles is.. P.A.I.N.F.U.L
I agree and I've been telling people this for quite some time now.
Getting your code under test is valuable in its own right. Why wait until you can convince a whole team of people to radically change how they work to apply TDD processes?
The grassroots effort should proceed from conscientious application of SOLID principles, refactoring and Plain Old Unit Testing.
In other words, business as usual... but a little smarter and a little better. Not a sea change but a progression.