Discussion on "TDD does not lead to good design in itself"

362 views
Skip to first unread message

Eric G

unread,
May 16, 2015, 8:14:11 PM5/16/15
to growing-object-o...@googlegroups.com
I don't think this recent discussion initiated by Sandro Mancuso has been raised on this list, I would be interested to hear what people think of it.

Sandro Mancuso: Does TDD really lead to good design?

Google Hangout discussion between Sandro Mancuso and JB Rainsberger :

JB Rainsberger: TDD is Not Magic

I am especially interested in the second part of the Google Hangout, where Sandro raised a question which for me is a fundamental one (starting around :45 mins): to paraphrase, he said that while there are clearly benefits of TDD to micro-level design decisions, TDD does not so obviously help with decisions at a bigger scale, especially when it involves several teams working on different parts of a problem. Even though clearly it is not just micro-level designs that need to evolve to maintain agility. Instead, "we have a whiteboard". He then gives an example from a current actual project.

In my understanding, GOOS is really trying to make the case that the techniques of outside-in development it outlines do address a larger scale of design decisions that are normally considered by TDD (I think it one of Nat and Steve's talks they characterized it as the mysterious "middle" levels of system design). But not in a idealistic, hand-wavy way, as if shifting from a system that can only be tested from the outside to a hexagonal architecture is some inevitable byproduct of a red-green-refactor workflow. I think the magical literature of TDD encourages us to see it this way, and we have expectations around the story going this way, and are frustrated when it doesn't. 

But the refreshing thing about GOOS, to me, is that it addresses making decisions based on the concrete (social and infrastructural) constraints in which the particular development project is situated, and furthermore encourages having your testing strategy be designed around giving you as quick feedback as possible before committing to a particular (infrastructure or UI) decision -- in essence, to really be able to make informed decisions about trade-offs. This goes well beyond most conceptions of TDD of course. To my knowledge, no one has articulated this as well as Nat and Steve.  At the same time, I think Sandro's question is still very relevant and one we could all benefit from reflecting on based on our own real projects. The techniques we need are barely ever mentioned much less developed, IMO.

Eric

philip schwarz

unread,
May 17, 2015, 5:27:15 PM5/17/15
to growing-object-o...@googlegroups.com

I don't understand why in his blog post Sandro says the following:

"4 Rules of Simple Design are NOT part of TDD and I’m purely discussing TDD here. 4 Rules of Simple Design is normally the design guidelines that many experienced TDD practitioners use (including myself, among other techniques) during the refactoring phase."

A couple of days earlier, I tried correcting him in the following twitter exchange (the two extracts are from the 1st edition of 'XP explained'):

@sandromancuso @RonJeffries just to make sure I understand your point: do you consider the 4Rules PART of TDD?

@sandromancuso @RonJeffries I'm asking because I understand them as one of the many great recommendations from XP. Something you combine with TDD.

@sandromancuso @RonJeffries and I'll believe in whatever you say, since you were at the core of it. ;)

@RonJeffries @sandromancuso no they are the rules of simple design and nearly any design difficulty shows up as a problem with one or more of them

@sandromancuso @RonJeffries OK. I agree with that. Just wanted to make sure they are not part of TDD but definitely important during refactor.

@philip_schwarz .@sandromancuso @RonJeffries The design strategy advocated by XP is TDD: 1/4  


@philip_schwarz @sandromancuso @RonJeffries The link between TDD and 4RSD is step four: "If you ever see the chance to make the design simpler, do it." 2/4

@philip_schwarz @sandromancuso @RonJeffries XP defines the 'best' design as the 'simplest' design that runs all the test cases 3/4

@philip_schwarz @sandromancuso @RonJeffries XP defines 'simplest' as the following four constraints, in priority order: 4/4 

Sandro didn't respond. What is also strange is that Ron Jeffries (who is an XP authority) replied to Sandro's question with a 'no'.

Philip

Raoul Duke

unread,
May 17, 2015, 11:08:16 PM5/17/15
to growing-object-o...@googlegroups.com
please somebody tell me how any single thing can be claimed to lead to good design in all or even most cases. ugh.

i guess there's, "well using X, at least we have *some* results vs. just some idiot's random mental hap-hazard mess of code."

but GOOD DESIGN is actually NUANCED DESIGN.

i should think.

Steve Freeeman

unread,
May 20, 2015, 8:20:59 AM5/20/15
to growing-object-o...@googlegroups.com
To me TDD is about using the process of figuring out whether something is working to help me think about the design. The standard question is, “if this worked, how would I know?” and then listen to what that tells you. There’s also another level about “if this worked, how would I know it’s useful?”, which should trigger questions about the purpose of the development. Perhaps this all collapses to a more general question which is, “How do I know I’m doing the right thing?"

Most people interpret TDD as being about testing classes, but that’s more a feature of how it’s taught than the underlying concept--and then we get into pointless arguments about frameworks.

We have some material about using system tests to guide production support, but haven’t written it up properly yet.

S

Tim Wood

unread,
May 24, 2015, 6:06:24 PM5/24/15
to growing-object-o...@googlegroups.com
The way I experienced TDD was that the tests are one useful source of
feedback on the design quality. They don't directly tell me too much
about what the design should be: but if I can easily write easy to
understand tests that capture meaningful aspects of the program
behaviour then I am encouraged that my design might be OK; if the
tests are hard to write or hard to understand, or don't seem to be
testing any cohesive concept, then I am suspicious that there might be
some significant problem with my design.

The reason I think that the feedback from the tests is relevant, is
that each test is a kind of simplified prototype client for the code
being tested. If it is hard to write a clean test, then I suspect (and
have experienced) that it will be at least as hard to write and
understand/maintain the real client code (i.e. it will be hard to
compose the component being tested with any further component).

As far as the TDD discipline itself, it seems to me that what it helps
me do is decompose the things I need to think about during development
into different phases, helping reduce the cognitive load compared to
trying to think about them all at the same time. I can then iterate on
this, allowing what I learn in each phase to feed into what I do in
the others.
1) what is the software going to do (specification)
2) how will I tell if does it (verification/testing)
3) how will it do it / what is the algorithm (implementation)
4) how should the code look (style/comprehensibility)

My experience has been that it can also be useful to apply the idea of
tests giving design feedback, and to some extent the TDD workflow,
with different amounts of granularity when working on the large scale
design of systems. Even when designing distributed systems with many
components I find it helpful to ask myself at the outset: what
properties the system should have; and how I will verify that it does
indeed have those properties when implemented. And I still get the
same feeling of feedback, if the way the system is decomposed (or
interacts with the world) makes it hard to verify what it is doing,
then I suspect that it will also be difficult for at least some of its
users to install/interact/diagnose/reuse/understand/etc.
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriente...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Uberto

unread,
Jun 1, 2015, 1:50:53 PM6/1/15
to growing-object-o...@googlegroups.com
I think it all depends on how you define "lead" and "TDD".
If tdd means "distilling good design using tests" then the answer is easy.



Uberto 

Sent from my iPhone

On 17 May 2015, at 01:14, Eric G <eric...@gmail.com> wrote:

--

Chris Kelly

unread,
Jun 1, 2015, 1:57:27 PM6/1/15
to Uberto, growing-object-o...@googlegroups.com
I agree but I think you need to have core, traditional engineering values.  

i.e. know about design patterns, refactoring, SOLID principles, honing your code smelling skills

because if you don’t then the design part of TDD goes out of the window. You don’t know how to recognise a bad design from a good one. 

The refactoring phase which IMHO is the most important frequently gets dispensed with after the green bar. 

-- 
Chris 

Uberto Barbini

unread,
Jun 1, 2015, 5:02:58 PM6/1/15
to Chris Kelly, growing-object-o...@googlegroups.com
To be honest, I saw a couple of times teams where using TDD almost
fanatically ended to terrible design decisions.

In both cases I think the real problem was a lack of
Architecture/Grand Design/Metaphor context and a lot of pressure to
deliver something quickly.
I don't know if a general thing, after all I saw tens of teams with
shitty design and no tests, but the feeling is that concentrating too
much on TDD can lead to simple classes in a overcomplicated general
design. Tree/Forest problem maybe?

Uberto

Matteo Vaccari

unread,
Jun 2, 2015, 9:45:58 AM6/2/15
to growing-object-o...@googlegroups.com, Chris Kelly

I can't speak for the teams that you saw, but when this happened to us (we produced crappy code even though we thought we were doing TDD well), I think it was because we didn't observe the situation with our eyes and ears and noses open enough :)  

My thought was something like "we write tests! we write code in small increments! we rock!!!" but we didn't see, or pretended not to see, that the code was not good enough.  Thinking that the code was not good enough would have required admitting that we didn't know enough and/or we doing a good enough job.  (By "not good enough" I mean "enough to make the project a success".)  We weren't ready for admitting that.  I think I thought "keep doing TDD, it will be all right in the end".

So... TDD gives you feedback about your design.  (So does the customer!  Alas, always too late.)  If I'm not ready to accept the feedback, TDD cannot guarantee anything.

Matteo


Evgeni Dzhelyov

unread,
Jun 2, 2015, 12:36:52 PM6/2/15
to growing-object-o...@googlegroups.com
Matteo, thanks for sharing that!

It really shows that TDD is just a technique and real world projects are complicated thing - that requires a lot of organization, communication, discipline and knowledge (both technical and on human level) and a technique like TDD is just a tiny piece in the puzzle.

And I think that until we start to discuss the complexity in projects on much more architectural level, instead of over relying that a given technique will save us, nothing will change in general in the industry.

I think the *bad* results coming from people striving for one tool, one technique, one framework is basically the result of the materialistic consumer world that dominates the current world. That doesn't mean that we should stop re-defining and sharing the knowledge, but what happens in IT is just a small reflection of what is happening in the world on a much bigger scale.

Gian Carlo Pace

unread,
Jun 2, 2015, 12:59:22 PM6/2/15
to growing-object-o...@googlegroups.com
I don’t think that TDD as a practice can do anything. I think that if someone uses TDD to listen to the code feedback and continuously think about the design it can be a good way to never forget about the design itself and always enhance it. 

In my experience I use TDD to expose problems and smells in designing code (bad decoupling, missing abstractions) but it doesn’t show me the "right  design" that only experience and designing skill can try to discover. 

So I think I mostly agree with Sandro Mancuso. 

Ciao!
— 
gk 

Uberto Barbini

unread,
Jun 2, 2015, 2:16:48 PM6/2/15
to growing-object-o...@googlegroups.com

Matteo, what do you think was not enough in your code and where the tdd process let you down?

What I saw was a lack of architecture. Meaning that classes were good enough in themselves but didn't work very well together for the actual userstories. In one of the teams, I tried to point this out writing scenario tests, just to show how much wiring and duct taping was needed to make things work.

Thinking about it, there was also a lot of "unrequested flexibility", so probably  Yagni was also forgotten.

Do you think it was something similar to what happened to your team?

Uberto

Matteo Vaccari

unread,
Jun 3, 2015, 2:52:50 AM6/3/15
to growing-object-o...@googlegroups.com
On Tue, Jun 2, 2015 at 8:16 PM, Uberto Barbini <ube...@ubiland.net> wrote:

Matteo, what do you think was not enough in your code 

In the particular project I have in mind, (a) we did not insulate ourself well enough from the huge ball of mud of the rest of the system and (b) our code was a small ball of mud: no useful abstractions, everything coded procedurally and explicitly.

and where the tdd process let you down?

I think we lacked a sense of the difference between DTSTTCPW and "get it done quickly no matter how".  The difference between "simple" and "easy" (see Hickey). The fact that "Simple" is not the first thing you get to implement, but something you arrive at with trial and error and continuous refactoring.

So nothing new, you see?  We just did not do the "refactoring" part well.  Except that it was not obvious to us that we didn't.  The tragic thing that trips many "agile" teams, is that when you don't pay enough attention to your outcomes, for this same reason you will not notice that you don't.  Not until the customer complains.

Matteo

Evgeni Dzhelyov

unread,
Jun 3, 2015, 5:05:13 AM6/3/15
to growing-object-o...@googlegroups.com
Hi Matteo,

Can you say that in your particular project you didn't have the knowledge and experience to avoid the problems you described?

If that's the case, what is your answer to obtaining the required knowledge and experience. What sources of information you seek, how you gain that experience?

My answer to that question is that, I started to read and think about software architecture, software as a system, about requirements and verifications. My focus moved more into organizational and documentation processes. Resources like Rich Hickeys, Robert Martin, Martin Fowler and others that speak about architecture. Then I'm trying to document and split the codebase in different components and provide a map like view of the system, where you can zoom on different levels. Trying to work out better specifications and define the verification process.

All of this is work in progress and I don't feel by any means comfortable in my experience, but what is your approach?

At the moment I'm trying to answer this question: "If a new guy comes in the team, what should we give him, how we ensure he is on the level where he can avoid these kind of problems?"
And I'm lacking a concrete answer to that question at the moment :/

Steve Freeeman

unread,
Jun 3, 2015, 5:19:44 AM6/3/15
to growing-object-o...@googlegroups.com
Rachel Davies makes the point that many Agile teams just don’t talk enough about the design.

There’s a failure mode, which possibly is worse in start-ups and consultancies, where the view is that “if I’m not typing in code of direct value to the business right now, then we’re all going to die!”. There are moments when that’s true, but not always.

It’s certainly a good idea to have some written overview of the structure of the system, at least a diagram on a whiteboard. The other thing is to spend the time to converge on a system of names within the code. It’s amazing how obvious broken models become when I change from naming things after the domain rather than patterns.

S

Matteo Vaccari

unread,
Jun 3, 2015, 7:31:37 AM6/3/15
to growing-object-o...@googlegroups.com
On Wed, Jun 3, 2015 at 11:05 AM, Evgeni Dzhelyov <evgeni....@gmail.com> wrote:
Hi Matteo,

Can you say that in your particular project you didn't have the knowledge and experience to avoid the problems you described?

If that's the case, what is your answer to obtaining the required knowledge and experience. What sources of information you seek, how you gain that experience?

What I did was to take a lot more seriously the literature on software design, and then try things out.  It's not easy, because there are very few established, go-to resources on software design.  GOOS is a good one :-)

Matteo

Uberto Barbini

unread,
Jun 3, 2015, 7:51:07 AM6/3/15
to growing-object-o...@googlegroups.com
Sometimes the opposite is true: they discuss too much the design and
it become a battle of egos.

The problem with TDD is that they can warn you about a bad design
(talking about grand design that span multiple classes) but it is very
hard to figure out how to improve it... so we just assume what we have
must surely be the best possible design...


Uberto

Steve Freeeman

unread,
Jun 3, 2015, 9:03:44 AM6/3/15
to growing-object-o...@googlegroups.com
actually, there are quite a few, but they’re not always obvious. For example, the OReilly Erlang book has lots of good patterns within OTP, similarly Bruce Schneier’s Practical Cryptography. More conventionally, there are all the pattern books plus most of Martin Fowler’s series.


S

Nicholas Henry

unread,
Oct 10, 2015, 8:19:53 PM10/10/15
to Growing Object-Oriented Software
Just wanted to confirm you are referring to "Erlang Programming" [1]. (there are a couple of  Erlang books published by O'Reilly)

Steve Freeman

unread,
Oct 11, 2015, 4:56:48 AM10/11/15
to growing-object-o...@googlegroups.com
Yes.

S
Reply all
Reply to author
Forward
0 new messages