Test-Driven Development topics

602 views
Skip to first unread message

Philip Markgraf

unread,
Jul 3, 2013, 3:41:16 PM7/3/13
to clean-code...@googlegroups.com
Bob,

I am very excited to see the new Clean Code Videos on Advanced Test Driven Development, particularly since it appears there will be several more than just this first pair. As I look over the software team I am involved with and consider what skills do we need to develop and what can help us go faster, I keep coming back to a need for greater intuition and greater sophistication in our use of Test Driven Development. I have some similar thoughts when I read the online debates about whether to use TDD in the early stages of start-ups. I suspect that TDD should be as fast as non-TDD for even short-sprint development, if the developer has a strong intuition for how to TDD. If the developer lacks this strong intuition for TDD, the break-even point seems like it will be a lot further down the road. So... our challenge (or, at least MY challenge as a leader in my organization) is how to help build a greater intuition for TDD.

About two years ago, I spent a fair amount of time hunting for "the book" on TDD. I had hoped to find a single text that could encapsulate the topic and allow someone to move from "I've heard and can parrot back the three laws" to a point where they can make reasoned choices about which TDD operation to perform next, what to do when they have introduced an error in the stream of development and how to handle returning to add greater functionality to an existing component. (I had also hoped for a thin primer for the field of test-design, which adds all kinds of concepts and complexity to the problem set.) Up until now, I think our sources for learning TDD were 1) the three laws of TDD, 2) a varied discourse on whether to Mock or not and 3) whatever could be gleaned experientially from kata sessions. I've found only dribs and drabs on more sophisticated concepts, like creating the test of least consequence and evolving the code from specific to generic. It is my sincere hope that the forthcoming videos on TDD will greatly expand on these concepts and provide a more complete education on the Test Driven approach.

I know you are very passionate about Test Driven Development. If I am reading you correctly in various interviews and emails, you spend a fair chunk of your time asking "why aren't more developers doing this?" or even "why aren't ALL developers doing this?". My theory is that developers aren't doing TDD because they aren't good enough at it to have the TDD cycle be second nature. Until they reach that point, it is only natural to fall back on old habits when the pressure is on. (And, lets be honest, when is the pressure NOT on in software development?) I'm sure there are other causes, but this is where I think is the greatest contributor.

So, please make this part of the series fairly extensive. I would like to see the topic of TDD fleshed out in great depth and sincerely believe this is the area of learning that will provide the greatest benefit to developers in general (or at least the developers I get to observe). 

Cheers,
Phil

Uncle Bob

unread,
Jul 4, 2013, 9:42:27 AM7/4/13
to clean-code...@googlegroups.com
Phil,

Thank you for the encouragement.  I was stunned when I started planning out my advanced TDD episode, and found that it was growing into a series.  Then I was stunned again when the first episode bifurcated into two hour long videos.  Apparently I've got a lot to say on this topic, and didn't realize just how much was below the surface.  So, yes, expect several episodes on this topic.  I may also break the series into two parts with some design patterns scattered between them.  

Oh and <tongue-in-cheek>thanks</tongue-in-cheek> youve made it clear that I've got another book I have to write...

Scott Burleigh

unread,
Jul 9, 2013, 9:03:41 PM7/9/13
to clean-code...@googlegroups.com
I am also excited to see what comes in the future for the TDD videos.  I am hoping that they are as thorough as uncle bob promises.  I have also read just about every book I can find on TDD and feel that there is not similarities between all the approaches.  Uncle bob's approach is inside out, GOOS way is outside in, mockist vs statist, etc.  I still have failed to see anyone really produce a ports an adapter implementation in a statically typed language for a web application.  Most TDD exercises are algorithmic, a bowling game, prime factors, tic tac toe, a name formatter.  I think this type of TDD is fairly obvious, and I don't think most people have trouble with how to do TDD in the small algorithmic way, the problem I think most development teams have in adopting TDD is on the bigger complex applications.  When doing web application development you'll find tons of articles on ATDD starting with an end to end test, even corey haines on uncle bob's clean coder website uses the cucumber approach to TDD a rails app.  I really feel there is no definitive approach to TDD.  This same uncle bob who swears that our applications should not scream rails or any application framework, has a clean coder screen casts that uses a rails framework and designs the application with the rails framework in the very first video.  I would say most developers are designing applications for the web/mobile and are desiring examples of TDD in a full blown application, even if its a simple CRUD application with a few reports.  Even the GOOS book decides to go in the direction of a xmpp chat application for the auction sniper, and then it even gets into multithreading, which isn't the problem most people are having testing.  Uncle Bob's PPP book develops an employment payroll application where he uses USE CASE driven design, but it also stops short of an example of top to bottom TDD, including a web application that has ports and adapters with tests written so well that one can refactor with "impunity"(I really want to see examples of this).  I have even looked at uncle bob's famous fitness app on github, the problem with this application is that its hard to find where to start to see from the very beginning how tests were written to drive the design that they are at today.  

I don't think the issue with TDD that people are having is the inability to TDD an algorithm, its the ability to test DRIVE the design to the point where the application follows a ports and adapters architecture so our user interface is pluggable and the persistent storage is pluggable.  I have failed to find a true ports and adapter application for the web or mobile on github that when looking at the first commit, you find a test.

So my challenge to you uncle bob, is at some point create a video series, or a book, heck i'm willing to pay good money for it, where you have an application that has the following:

-an application with simple business logic with a few validation rules
-has a pluggable UI with examples of a web UI and a mobile UI
-has pluggable persistent storage with examples of a relational database and a no sql document database
-either has an application framework that you have to choose because of the team your on (in real life this happens often), but if you design your own framework so be it.
-interactions with a 3rd party web service.
-and last but not least must be written in a statically typed language :)

Boas Enkler

unread,
Jul 10, 2013, 1:44:46 AM7/10/13
to clean-code...@googlegroups.com
I totally agree with that.

With the current episode i've learnt what it TDD is really meant to be. And with this knowledge I gave it a second try and from there on i always write my tests first and i'm much faster im implemting. Sometimes its scary when you have something really complicated and after finishing implementation the integration just works.

The missing part are the more complex cases. Especially the things pointed out in Scotts post. 

So it would be great to get some episodes, a book, (best both) on these "Integrating TDD into the Real World" stuff :-)


Uncle Bob

unread,
Jul 10, 2013, 3:40:56 AM7/10/13
to clean-code...@googlegroups.com
Scott,

Thank you for the note.  FitNesse was started with TDD, and has been TDD throughout.  The ports and adapters architecture is very evident on the persistence side; but not so much on the GUI side.  Since FitNesse is a wiki, it's hard to imagine it NOT using the web.  Even so, I still cringe a bit about that.  

The experience of writing the scripts for this series has convinced me that I have much more to say about TDD than I thought.  So I'll be continuing this series for awhile, though I might interpose some intermissions.  I'm also convinced I need to write a book on the topic.

Even so, what you are asking for is probably out of scope for videos or even books.  You want the whole experience of writing an app using TDD.  I fear the only way to get that experience is for _you_ to write an app using TDD.  I can give you hints and clues and explanations but I doubt I can give you the total experience that you've asked for.  Well...let me think on that...

BTW, keep watching Corey's series.  He's already begun the process of decoupling his app from Rails; and will likely continue that process.

Mohammed AMHEND

unread,
Jul 10, 2013, 10:10:56 AM7/10/13
to clean-code...@googlegroups.com
Why not starting a simple project from scratch on github with uncle bob in which we let uncle bob write the first tests and some sort of walking skeleton and discuss it here before going on !

Uncle Bob

unread,
Jul 11, 2013, 5:52:58 PM7/11/13
to clean-code...@googlegroups.com
I wish I had the time to do that.  Alas, I don't think the fates will allow it.

Philip Markgraf

unread,
Jul 12, 2013, 3:00:55 AM7/12/13
to clean-code...@googlegroups.com
Consider that book pre-ordered!

Paweł Zając

unread,
Nov 30, 2013, 10:54:38 AM11/30/13
to clean-code...@googlegroups.com
Hello fellow programmers.
I'm not sure if it's the right place to ask my question, but I didn't manage to read all previous posts and I don't like to spawn new topics.

The question is:
"How to start TDD? At which class?"
I mean that you probably have idea what your system/component is about, so you imagine some "blocks" responsible for some actions, hopefully with respect to SRP and whole SOLID.
For instance: I was making some warehouse software. It's use cases included making deliveries from warehouse, buying supplies for warehouse, calculating stock value according to FIFO rules, and interacting with third party software via proprietary text file format.
My idea was to start with functionality, that seemed most decoupled from the by itself, like these text files parser.
We separated concerns of text (formal) processing from data (semantic) processing and so on. It went quite well.

But after that I was trying to do a similar project, but I found myself in a trap. I wrote some code for "class1" with TDD, but at some point I decided that some code, which I didn't write yet, should be placed in a separate class/file/component. So I left the code I was currently working at, and I started to implement that other class, "class2". I used TDD of course. After another in mind "premature extraction", of code, that hasn't been written yet, I started to TDD implement "class3" on which "class2" was dependent. So I made a chain of unfinished and dependent classes. It really slowed me down, because i couldn't focus on one class. I had to leave it, to finish the class on which it depended first.
What do you think? Where did I make the mistake? Did I start extracting to early? Did I chose the "wrong" class to start with? Should I chose to start with "class3"? And what if I wrote all code inline in "class1" and then extracted it? Should I cover the extracted code with test? It won't be TDD, no test first approach. Do I really have to behave like linker/compiler and resolve dependencies? What do you think.

I was encouraged to write my first post in this group after watching CleanCoders E20, where Uncle Bob demonstrated TDD'ing Account class, which depended in Bank class, which wasn't done via TDD. I know it wasn't the main issues of this episode, but Uncle Bob didn't commented it at all, and that's kind of my case.

PS.
Uncle Bob's series resurrected my faith in that programmers job can make any sense and in that I can do this job. CleanCoders rocks!
THANK YOU UNCLE BOB!

Uncle Bob

unread,
Dec 2, 2013, 5:58:36 AM12/2/13
to clean-code...@googlegroups.com
Paweł, 

This is called the 'stack' problem.  You are working on problem A, but to solve it you need to solve problem B.  So you push A on your "stack" and start working on B.  But to solve B you need to solve C.  So you push B on your stack, and start on C.  If this happens more than a couple of times it can get very confusing.

The solution is to continue working on A by mocking B.  You don't need a fully functioning B in order to write all the tests for A.  Just create the appropriate stubs and spies that stand in for B while making sure A works properly.  Then you can start working on B when A is done.


Paweł Zając

unread,
Dec 2, 2013, 6:45:17 AM12/2/13
to clean-code...@googlegroups.com
Wow! Uncle Bob himself wrote to me! (or at least someone from his account :)
I'm impressed, that you have time for all these activities.
Thank you for answering so quick.
Thats right.Time to practice some mocking techniques, to level up in TDD.
 


--
The only way to go fast is to go well.
---
You received this message because you are subscribed to a topic in the Google Groups "Clean Code Discussion" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clean-code-discussion/lkkCA9ZJcUI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clean-code-discu...@googlegroups.com.
To post to this group, send email to clean-code...@googlegroups.com.
Visit this group at http://groups.google.com/group/clean-code-discussion.

Juan Diego Hereñú

unread,
Dec 2, 2013, 7:07:03 AM12/2/13
to clean-code...@googlegroups.com
If that is the case, when B is implemented, should we replace the stub with the real code? This can make the tests to change because stubbing objects is easier than finding a case for every behaviour of B (depends on what B does, but can happen). 
What do you think? We keep the tests as they are, or we change it with the real implementation?

Thanks!


2013/12/2 Paweł Zając <pav...@gmail.com>
You received this message because you are subscribed to the Google Groups "Clean Code Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clean-code-discu...@googlegroups.com.

Paweł Zając

unread,
Dec 2, 2013, 7:47:10 AM12/2/13
to clean-code...@googlegroups.com
I've thought that replacing stubs with final implementation is obvious, but your question Juan is interesting from practical point of view.
You need to rewrite the tests and spend time on it. When you keep asking, nothing is obvious :).
Maybe distinguishing Unit Test form Integration Test, like Roy Osherove suggests, would let us to decide.
I think in case of having implementation dependency you need to put real implementation in place rewrite your tets.
Hopefully you have them made clean, so it should go fast:).
In case of abstraction dependency, replacing the stub might be unnecessary.
 
Thanks for your question Juan.

Uncle Bob

unread,
Dec 2, 2013, 8:19:32 AM12/2/13
to clean-code...@googlegroups.com
Interesting question.  Should you replace the stubs once the real class is implemented?

Probably not in most cases.  The tests will be easier to read with the stubs and spies in place, because those stubs and spies strongly constrain the behavior being tested.

Jop van Raaij

unread,
Dec 2, 2013, 3:02:33 PM12/2/13
to clean-code...@googlegroups.com
Interesting question and answer, but I have a follow-up question which might be interesting (at least it is to me):

How do I test different implementations of B?

Suppose I have an application and I have implemented functionality A using B to get data from a REST service. Now I have another application with functionality A which uses a SOAP service to get the data (another implementation of B). B will have the same interface, but an other implementation. Ideally I'd like to have 1 testclass to ensure both implementations pass the same tests. But this is impossible, as I have different applications. Would you copy the testclass and run it with another implementation? Do you create a separate test-project for interface testclasses which are used by the applications? Do I inject multiple implementations in the same testclass, running it for each implementations, in a separate integration test?

Rusi Filipov

unread,
Dec 2, 2013, 3:10:09 PM12/2/13
to clean-code...@googlegroups.com
This is an interesting discussion to me too. I am missing more advanced, more real-life TDD stuff. Although the videos show very very valuable insights so far, I feel state-based testing of one class isn't really advanced. 

Recently, I was mentoring a group of two novice TDDers on their way of implementing a kata. We analysed the problem and came up with this object model on paper, that consisted of 6-8 classes. That model should support the implementation and should be evolved gradually during the implementation using TDD. 

I suggested them to implement bottom-up in a TDD fashion, since I thought it would be easier for them to go. But deep inside I feel top-down is the better approach. Bottom-up forces you to think backward at many levels and has a risk of designing APIs that are not the best. Top-down pins you to mocking and relying on those mocks, but the resulting API is much more natural.

Uncle Bob, don't you think an example with multiple collaborating classes would fit good in the Advanced TDD series?

Best regards,
Rusi

Paweł Zając

unread,
Dec 3, 2013, 3:54:36 AM12/3/13
to clean-code...@googlegroups.com
Jop, once I managed do solve the issue of testing classes in inheritance hierarchy by constructing similar hierarchy of tests. There was an "abstarct" test class for root of inheritance hierarchy and a set of inherited test classes for each implementation class. The "abstract" test class tested common funcionalities and inherited test classes tested specific funconalities. For test framework it was equal to copying all code of test class for each implementation, but for me it was less to write.
Of course this solution might not work if your implementations return different results, but it is suitable for cases where results are the same, but mechanisms delivering them are different. I believe that after replacing REST by SOAP you expect the same results, at least by means of returned data structures.
 
Rusi, thank you for writing my question in more clean way:). I was alwys trying to start top down in my mind, but I was doing bottom up while writing code. That required searching a class that would be on the bottom. I was trying to choose classes with least dependencies (hopefully with none) and with methods operating on simple or universal types, like strings or streams. But i had to do it myself and it wasn't TDD which lead me to this design. And in case of choosing the "wrong" class to start, I encountered a "stack problem" as Uncle Bob described it. All in all I need to learn more about mocking, stubing e.t.c. Mayme after that I would understand, that this question is irrelevant :)


--

Uncle Bob

unread,
Dec 3, 2013, 4:41:19 AM12/3/13
to clean-code...@googlegroups.com


On Monday, December 2, 2013 2:10:09 PM UTC-6, Rusi Filipov wrote:

Uncle Bob, don't you think an example with multiple collaborating classes would fit good in the Advanced TDD series?


Indeed, Episode 25 will be such a case study. 

Rusi Filipov

unread,
Dec 3, 2013, 11:51:39 AM12/3/13
to clean-code...@googlegroups.com
On Tue, Dec 3, 2013 at 10:41 AM, Uncle Bob <uncl...@8thlight.com> wrote:

Indeed, Episode 25 will be such a case study. 

That is great! Looking forward to see Episode 25.

felix medina

unread,
Jan 8, 2015, 6:58:48 AM1/8/15
to clean-code...@googlegroups.com

Hi Uncle Bob!

Just a quick question. Do you still plan on writing “Episode 25: Test Driven Development Case Study” or do the videos under the “Java Case Study” section intended for this purpose? 

Robert C. Martin

unread,
Jan 8, 2015, 9:08:41 AM1/8/15
to clean-code...@googlegroups.com
Indeed, the Java Case Study series _is_ the promised TDD case study.


----
Robert C. Martin (Uncle Bob) | uncl...@cleancoders.com
Clean Coders | @unclebobmartin
847.922.0563 | cleancoders.com

felix medina

unread,
Jan 8, 2015, 2:37:06 PM1/8/15
to clean-code...@googlegroups.com
OK

I suspected it so but just wanted to check with you.


Thanks a lot for your reply and thanks a lot for your videos, books and in general, for sharing your years of experience with us.

Cheers,
Felix

Paweł Zając

unread,
Feb 9, 2015, 2:28:14 PM2/9/15
to clean-code...@googlegroups.com
Dear Uncle Bob,

I'm currently reading "The Art of Unit Testing" second edition by Roy Osherove, with your foreword :).

What do you think of his definition of unit and integration tests?

It's more or less:

"Unit tests controls every aspect of code execution"
and
"Integration tests has external dependencies out of it's control"

Does fully mocked integration test becomes unit test as it looses "uncontrollable" dependencies?
Reply all
Reply to author
Forward
0 new messages