• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Junilu Lacar
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Ganesh Patekar

ready to learn TDD

 
Bartender
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's time for me to take the next step in my growth and start learning TDD. It looks like Kent Beck's work is now 13 years old. Is it still a good book for getting started?

I see that Jeanne had lots of good things to say about this book by Lasse Koskela but I get the impression that it's geared more toward developers that are already comfortable with jUnit.

I'll probably end up getting both of them unless someone can recommend a better introductory book. I don't find a Head First book on testing. Might be an opportunity for someone.

So, recommendations?
 
Sheriff
Posts: 4674
308
IntelliJ IDE Clojure Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
While I do like Test Driven and Effective Unit Testing by Lasse Koskela, and you'll find me recommending them many times on these forums, I really really like Kent's TDD by Example book. Sure it's getting on a bit now but the taught principles are the same.

I like the fact that it was written 12 years ago. Kent is just showing you a development process that he found worked very well. There's no hype, no hipster-ism, just a practical straight forward demonstration of his 'TDD' workflow.
 
J. Kevin Robbins
Bartender
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks. I think I'll start with Kent's book. It sounds like a good starting place. I wish there was Head First book on the topic. That learning style works for me.

Maybe we can convince Junilu to write one.

It's his posts that convinced me that I need to learn this. I wish I could work for him.
 
Ranch Hand
Posts: 254
1
MySQL Database Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know if this is off-topic but still but speaking of TDD and Junilu I had to comment. From a couple of days I'm following this Design of Vending Machine topic and needless to say that thread is full of profound wisdom. I do wish my design skills improve as well.
 
J. Kevin Robbins
Bartender
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yeah, when Junilu starts on one of those refactoring threads I always learn something and can't help but think, "I wish I could code like that". I don't know if I'll live long enough to get that good, but I'll keep working at it.
 
Marshal
Posts: 14053
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for all the kind comments, guys. I can't believe my ears are actually hot as I write this; I'm probably blushing like a schoolboy right now.

Of all the books I have read that discuss TDD in some way, these are my current gotos:

- Refactoring by Martin Fowler
- Refactoring to Patterns by Joshua Kerievsky
- The GOOS book (Growing Object-Oriented Software, Guided by Tests) by Nat Pryce and Steve Freeman
- Understanding the 4 Rules of Simple Design by Corey Haines
- Pragmatic Unit Testing in Java 8 in JUnit by Jeff Langr
- Agile Software Development: Principles, Patterns, and Practices by Robert Martin

I think Kent Beck's book is still relevant and even though the code in the examples are outdated, the motivation behind writing the tests and the intent of the tests are really what you need to study. The Haines book is a relatively recent discovery that I made and it is chock full of great advice and examples.

Your mileage may vary but my approach to learning TDD was breadth-first. When I first started learning TDD, I had a hard time applying and sustaining the practice in my real-world work. This was quite discouraging for me since I knew that others were using the technique to great advantage. It was only when I realized that TDD is just a small but significant part of the larger design process that I started tying in my study of TDD with the study of code/design smells, refactoring to patterns, design principles and patterns, and even continuous integration and source control practices like branching and merging. When I did this, things started clicking in my head and I was soon able to apply the practice in my real-world work. That's probably why it took me so long to get to a point where I could say that I had a good handle on TDD. It wasn't enough to learn the mechanics of the Red-Green-Refactor cycle -- I needed to understand the motivations behind developing that way. I needed to understand the bigger picture into which TDD fit. That's why some of the books that I list above aren't about TDD specifically.

In the workshop that I give at work, I ask the participants to strive for simple design first, guided by the four rules discussed in the Haines book, and concentrate on three basic refactorings with the goal of clarifying intent and eliminating duplication:

1. Rename variable/method/class
2. Extract Method
3. Composed Method

IMO, this is sufficient for 80% of the code you write and it's a great way to make the connection with the importance of refactoring and understanding design principles and patterns when you do TDD.

I'm glad my contributions here help others understand the importance of TDD. I'm sure Uncle Bob would be happy, too.
 
Junilu Lacar
Marshal
Posts: 14053
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here's a great passage from Kent Beck's TDD by Example book:

Kent Beck wrote:Test-driven development is a set of techniques that any software engineer can follow, which encourages simple designs and test suites that inspire confidence. If you are a genius, you don't need these rules. If you are a dolt, the rules won't help. For the vast majority of us in between, following these two simple rules can lead us to work much more closely to our potential.

· Write a failing automated test before you write any code.
· Remove duplication.

How exactly to do this, the subtle gradations in applying these rules, and the lengths to which you can push these two simple rules are the topic of this book.


Going by this alone, I believe Beck's book will be relevant for quite a while despite the code examples being a bit outdated. As I've said before in these forums, understand the principles and you can adapt to any changes in the technology. Read the book with the goal of understanding the principles behind the "subtle gradations" and you will still get a lot of value out of it.
 
Junilu Lacar
Marshal
Posts: 14053
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is what I mean by looking for the principles in Beck's book:

Kent Beck wrote:Here's a simple example of multiplication:

(I know, I know, public fields, side-effects, integers for monetary amounts, and all that. Small steps. We'll make a note of the stinkiness and move on. We have a failing test, and we want the bar to go to green as quickly as possible.)


The test code is obviously pre-JUnit 4 but the part in parentheses is full of principles: write a failing test first, quickly go to green, make small steps, don't mind the initial stinkiness, make sure you don't forget to go back and refactor. It even lists some of the code smells he recognizes are there. Many programmers will recognize only the public fields and integers for monetary amounts. Fewer will recognize the side-effects smell. If you're not one of those few, then you will have learned something already just from this small example.
 
J. Kevin Robbins
Bartender
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, lots of good information. But I'm going to have to play dumb and ask about the side-effects from that last example. I don't see it. What am I looking for? Maybe you can give me a definition for "side-effect"?
 
Junilu Lacar
Marshal
Posts: 14053
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The side effect is that when you call the times() method, the amount changes. Dollar mutates as a result of a calculation operation. The primary goal of times() was to calculate amount * argument. The side-effect was that amount got changed. There's a design guideline that states that a method should either mutate an object or return the result of a calculation but never both. This is related to the Single Responsibility Principle (SRP) and sometimes also to Demeter's Law. Violating either or both of these is a code smell and you should look at the code/design more closely. When novice TDDers recognize the smell, they will typically go direct to refactoring. Sometimes that's fine but I have learned to write another test to illustrate the problem with the current design first. I've said this here before: "Don't let your intuition drive the design process; that's what tests are for." Use your intuition about code smells to guide you to new or modified tests instead.

Subsequent refactorings modify the API to make Dollar immutable. A few more things you learn from that first round of design are:
1. You probably won't get the API right the first time, hence
2. It's OK to change the tests.
3. Change the tests, then change the API.
 
Junilu Lacar
Marshal
Posts: 14053
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I wrote:There's a design guideline that states that a method should either mutate an object or return the result of a calculation but never both. This is related to the Single Responsibility Principle (SRP) and sometimes also to Demeter's Law.


I suppose you could say "Well, times() doesn't return anything since its return type is void. How does that violate the design guideline?"

This is an example of what I mean when I say "Listen to what the code wants to do." Recognizing "what the code wants to do" requires familiarity with design principles and guidelines. When these are violated, the code is telling you it really wants to do something else. In this example, the code wants to be more like this:

But that's not the end of it. In fact, it makes the smell more apparent and it's that it really wants to have Dollar as immutable so you can write something like this:

and with that, the redundancy says that the code really wants to be just:

I said it's also sometimes related to the Law of Demeter (the correct name, BTW, not "Demeter's Law" as I wrote before -- it's named after a project, not a person). In the original assertion that follows the call to times(), you reach into Dollar to get the value of the amount field. Even if you introduce a getter for amount, you should recognize that you're still reaching into Dollar to get the amount. This violates the part of the Law of Demeter that says "You can play with your own toys (but you can't take them apart)". Reaching into Dollar to access amount or even calling a getter method is "taking Dollar apart" because you are using the encapsulated value separately from the object itself.

Beck writes about "subtle gradations" and that's why I find many parallels in practicing TDD to my practice of Aikido. In Aikido, I am always finding new subtle gradations in basic techniques when I work with new people even if I have performed the techniques hundreds or thousands of times before. Programming and design are no different. There are so many problems to which guidelines and principles can apply that the variations and gradations are practically countless. That's what keeps both programming and Aikido fresh and fun for me. The day I stop learning new things is the day I stop doing both.
 
Junilu Lacar
Marshal
Posts: 14053
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I guess I think of it this way: Code wants to be simple and elegant. A lot of the things you write gets in the way of that. Your job is to divest the code of any encumbrances that keep it from being simple and elegant.

A related quote that I like:

Antoine de Saint Exupéry wrote:
Il semble que la perfection soit atteinte non quand il n'y a plus rien à ajouter, mais quand il n'y a plus rien à retrancher.

(It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to remove.)


 
J. Kevin Robbins
Bartender
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I had to read this several times to understand what you are talking about. I see it now, but it's so subtle, it's hard for me to identify. I bet my past code is riddled with bad structure like this. Even now that I know what to look for, it's going to take a lot of practice to be able to recognize it.

Junilu Lacar wrote:I have learned to write another test to illustrate the problem with the current design first.



So how would you write a test that demonstrates this problem?
 
Junilu Lacar
Marshal
Posts: 14053
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

J. Kevin Robbins wrote:

Junilu Lacar wrote:I have learned to write another test to illustrate the problem with the current design first.


So how would you write a test that demonstrates this problem?


Beck writes the test in the book. He writes that he would have liked to do something like this:

Of course, that's still a little bit off. Beck reminds us again that we probably won't get the API right the first few times. So he tries something else:

Since all this appears to have piqued your interest, I suggest you start with Kent Beck's book. I'm re-reading it now myself and seeing a lot of things in a new light that I didn't quite get when I first went through this book.
 
Junilu Lacar
Marshal
Posts: 14053
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here again is a parallel with Aikido practice. As a white belt, I would watch sensei demonstrate techniques all day and he would explain how he was able to control the other person by doing this thing or that thing. When I would try it myself, it didn't come at all as easy as it looked when sensei was doing it. But the more I progressed in my study and the more experience I gained with the techniques, the more I discovered the subtleties of what sensei was really doing. So don't worry too much about getting all of it now. Recognizing the subtleties will come with constant practice and careful study.

Here's one exercise I was thinking about doing: My company has data centers all over the world so many of the applications we write need to be able to handle date/time data from many different time zones. The kind of design choices made in the Money example seem to be very similar to the choices you might make when working with Dates/Times from different locales. I was going to see if I could use the same thought processes in test-driving a design for multi-locale Date/Time calculations.
 
J. Kevin Robbins
Bartender
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't quite understand that last example, but you've convinced me to order the book. It's on it's way.

I'll revisit this thread after I've worked through part of the book and see if it make more sense to me.

It's interesting how you often compare the study of software development to the study of the martial arts. It's like the Zen of Programming.
 
Junilu Lacar
Marshal
Posts: 14053
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

J. Kevin Robbins wrote:I don't quite understand that last example, but you've convinced me to order the book. It's on it's way.

I'll revisit this thread after I've worked through part of the book and see if it make more sense to me.

It's interesting how you often compare the study of software development to the study of the martial arts. It's like the Zen of Programming.


Kent Beck explains it a lot better, obviously, so yeah, go through the Money example and I'll be happy to give my perspective on anything you find unclear.

References to martial arts are not uncommon. Musashi's "Book of Five Rings" and Sun Tzu's "Art of War", for example, are often cited in books about Agile and software development among others. What really got me thinking about the parallels was Alistair Cockburn's Agile Software Development book. In one appendix, he discusses the concept of Shu-Ha-Ri and the advice of Musashi, the legendary swordsman, one of which is to "practice and observe reflectively" and these are things that strongly resonate with me.

I suppose you could draw parallels to any kind of activity that requires study, skill, creativity, and problem solving.
 
Greenhorn
Posts: 7
Spring Clojure Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I read "TDD by Example" and I really liked it. The book contain a lot of hints how to approach tests, what to test and how.

One thing to note is Refactoring, which is, often missed, part of "Red-Green-Refactor" mantra. Remember that refactoring is part of the TDD and should be done constantly. Tests should be refactored too.
 
Live a little! The night is young! And we have umbrellas in our drinks! This umbrella has a tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!