TDD Triage 207
With all controversy that has been generated buy my last two blogs (1, 2), I thought it would be wise to talk bout where TDD works and where it doesn’t
Is TDD a replacement for architecture?
No, of course not. The notion that you can generate a viable architecture by starting with a blank screen and then writing one test case after the other is sheer folderol. There are decisions that you need to make that have nothing to do with tests.
Of course many of these decisions can, and should, be deferred for as long as possible. For example, the database schema is something that can likely wait for quite a long time. The decision to use Spring, JSF, Hibernate, JPA, etc. can also likely wait. The beauty of business rules is that they can, and should, be implemented independently of database and GUI models.
In FitNesse, we deferred the database decision as long as possible. In the end we deferred it indefinitely and used flat files instead. At the beginning we did not think flat files would be the solution, we thought we’d be using mysql. But we kept on postponing that decision, and making our test cases pass. Finally, one of the stubs we’d been using to save fitnesse pages into flat files proved to be good enough.
Interestingly enough, one year later a user of FitNesse needed it to use mysql (because of corporate bureaucracy). It took him a day to make the changes. The architecture of FitNesse was so flexible, because of all the tests and stubbing, that shimming mysql in at the very end was trivial.
On the other hand, some architectural decisions need to be made early. For example you really do need to choose your programming language pretty early on. You also probably need to know whether you will be working in a web (batch) environment, or using a more intimate user interface. If you are in an enterprise environment, you’ll need to understand the existing database and plan how you will isolate your application from it.
When we started FitNesse, we made a very early architectural decision that has had a profound impact on the structure of the system. That decision was named “Download and go.” Before the first line of code was written we decided that FitNesse should not be bound to any other independent system, that you should be able to download it, and then execute it with a single command. In 2001 this meant we had to write our own web server…
Here’s the bottom line. You cannot derive a complete architecture with TDD. TDD can inform some of your architectural decisions, but you cannot begin a project without an architectural vision. So some up front architecture is necessary. One of the most important up front architectural activities is deciding which architectural elements can be deferred and which cannot.
Is TDD a replacement for design?
No. You still need all your design skills. You still need to know design principles, and design patterns. You should know UML. And, yes, you should create lightweight models of your proposed software designs.
TDD’s role is to inform your design decisions, not to replace them. The Bowling Game Kata is an example of how TDD can utterly invalidate early design decisions; but the Bowling Game is an extreme case. Usually TDD works to validate, and/or augment your design decisions.
A team of developers needs to have a design vision that they have agreed upon. This vision can often be gained with a relatively short design session at the beginning of each iteration. UML models can be proposed and negotiated on a white board. This gives everyone the context required to make progress without stepping all over each other.
However, the models should not be considered law. They are nothing more than an initial rough draft of the design. As the teams practice TDD, they will undoubtedly discover weaknesses in the designs, and uncover better solutions. These improvements should be quickly communicated to the rest of the team.
The bottom line is that TDD is a_ design technique but should not be the _sole design technique. All the old design rules and skills still apply; and TDD is a powerful way to inform and augment them.
Should TDD be used for every line of code?
No. There is a set of problems for which TDD is not particularly helpful. GUIs are an example.
In FitNesse, for example, we use Velocity templates to create our web pages. There is a lot of coding that goes into a Velocity template. But to use TDD for those templates would be absurd. The problem is that I’m not at all sure what I want a page to look like. I need the freedom to fiddle around with the formatting and the structure until everything is just the way I want it. Trying to do that fiddling with TDD is futile. Once I have the page the way I like it, then I’ll write some tests that make sure the templates work as written.
Of course it’s not just GUIs. It is the notion of fiddling that is the key. If you must massage the code into place. If you must fiddle with some aspect in order to please the customer. If there is some uncertainty that can only be resolved by a very rapid cycle of edit-and-run, then TDD is likely to be more of a hindrance than a help.
As another example, I once worked with a trading company that had to parse incoming streams of trading data. These streams did not have a well defined format. The teams had to fiddle with regular expressions and parsers in order to get the decoding just right. TDDing this would not have been wise. Writing the tests afterwards was imperative.
The trick to manage this is intense decoupling. You want to make sure you identify every bit of the code that does not need to be fiddled, and separate that code into modules that you can write with TDD. Make sure that the fiddled code is isolated and kept to a bare minimum.
For example, the Velocity templates in FitNesse draw their data from data structures that are built by the business rule processes (we call them Responders). I relentlessly use TDD to make sure those data structures are right. So when I fiddle with the templates, at least I’m not fiddling with the code that generates the data for those templates.
NOTE! Just because GUIs need to be fiddled with, does not mean that most of the code around the GUI should not be TDD’d. In fact, most of that code should be TDD’d. It’s just the tiny thin veneer of code that controls the format that needs to be fiddled. All code that can and should be TDD’d should be decoupled from that veneer. So, decouple, decouple, decouple, and then finally fiddle.
Well, if you are going to write some tests afterwards, why not write all tests afterwards?
Well, first, there’s the George-Williams study, which showed that teams who are instructed to write tests afterwards, don’t write tests at all. Of course this is human nature. Once you have the code “working” why write tests? Writing tests for code that you believe works feels like a waste of time.
But that can be countered with sheer discipline. The real reason to follow The Three Laws of TDD and write your tests first is that it greatly enhances the chances that every line and every decision is tested.
Code coverage is a sneaky metric. It is quite possible to create extremely high levels of coverage without a single assert. I don’t need to tell you that coverage without asserts is less than meaningful. When you write tests first, your assertion coverage is very high. When you write tests after, you assertion coverage simply cannot be that high. Even the most dedicated and determined developer will make some coding decisions that block later testability. When you write the tests first, this simply cannot happen. When you write the tests first every coding decision you make must support testability.
Clearly writing the tests first forces an extremely high degree of compatibility between the tests and the code. Writing the tests first also means that your first thoughts about the code are from the point of view of a user, not an author; and that also has benefits.
So, all else being equal, test-first is clearly better than test-after.
Given that we accept the need for tests, why the resistance to test-first?
Honestly, I don’t know. Clearly it can’t be a productivity issue since we are going to write the tests anyway.
Perhaps some people don’t like the fact that writing tests first interrupts the flow. It’s true, when you write tests first, you cannot write a whole algorithm. You have to assemble that algorithm bit by bit as you add one test case after another. Maybe some people just don’t feel comfortable working this way. Personally, I find working this way to be highly beneficial. It’s a way for me to think critically about the code I am writing. But I accept that some folks may find it difficult.
I once worked with an assembly language programmer who simply could not understand pointers. No matter how hard I tried to explain them, he simply could not grasp the concept. This made it hard for him to write certain kinds of programs. I fear that the folks who cannot train their brains to think in a test-first way are working at a similar kind of disadvantage, though not nearly so severe.
Wouldn’t it be faster without such high test coverage?
I’ll paraphrase Kent Beck once again. “If I don’t need to make it work, I can go a lot faster.”
I once consulted for a team that followed this rule. For them, the definition of “Done” was “checked in”. If the checked in code had bugs, then fixing those bugs went on a different schedule. Eventually the team started checking in empty source files in order to be “done” on time.
But let’s take the original question seriously. Do we really need to have close to 100% automated test coverage? Doesn’t the insistence on such a high level of coverage slow the development team down?
In a legacy environment it certainly does. Indeed, in a legacy environment I would not insist on high test coverage at first. I’d set the goal pretty low, and then gradually ramp it up over a period of months to years.
Legacy code (defined by Michael Feathers as: code without tests) is a big problem. Getting that code under automated test is a difficult and long-term activity. The pay-off is huge, but you can’t get there quickly.
In a non-legacy environment, and for all new code within a legacy environment the situation is different. High coverage with automated tests speeds you up; and it speeds you up a lot.
The reason isn’t difficult to understand. Firstly, you don’t do much debugging. How could you if you have tested virtually every line of code? My own experience with debug time is that it all but disappears. In the last year of intense development effort on FitNesse I have spent almost no time debugging. If I had to quantify that time, I’d put it at 5 hours or less.
Secondly, I simply cannot inadvertently break the code. The test suite finds such breakage within seconds! And this makes me fearless. When you are fearless, you can go a lot faster.
Thirdly, My tests are little examples of how to work the system. Whenever I forget how some part of the system works, I read the tests. They quickly get me back up to speed.
Fourthly, I’m not fighting a continuous barrage of bugs from the field. Even though I have thousands of users, my bug list is tiny. The time I spend in support is less than an hour a week, and usually that’s just pointing people at the right spot in the user guide.
So to counter Kent Beck’s quote above: “When your code works you can go a lot faster.”
Summary
I’m quite sure this blog will not quell the controversy. I expect that those folks who consistently berate TDD will continue to do so. But perhaps those who have honest doubts will find this blog useful, or even convincing.
This post was extremely useful. I tended not to follow the controversy, and was simply looking for a good understanding of what TDD really was. While it certainly wasn’t the end-all be-all explanation, it hit the mark as a good high-level introduction.
Please add a section – “Is TDD a replacement for testing?” – programmer unit tests vs application tests.
@Uncle Bob > “Well, first, there’s the George-Williams study…”
And the Maximilien-Williams study where “For each important class, we enforced complete unit testing” – enforced!
http://collaboration.csc.ncsu.edu/laurie/Papers/MAXIMILIEN_WILLIAMS.PDF
You are joking, right?
I wish I were. But no. When schedule pressure mounts, people can rationalize even the strangest behaviors.
Making the transition to TDD has accomplished one critical thing for me personally: it has exposed my weaknesses. Whenever I have to stop and take the time to think, “how can I write this so that it’s testable” or something along those lines, I have in essence failed a unit test myself. There is a bit of design knowledge or programming technique that I am lacking that will help me solve this problem.
That is a completely different class of problem than not knowing an API call or a particular piece of syntax. Once I fill that gap, that knowledge is transferable to other every other programming problem I have. The same cannot be said for syntax and API issues.
Bravo Bob Martin.
This post has none of the condescension that marked your earlier efforts (non TDD folks being called “stone age”, “unprofessional” and so on).
While the “TDD is a design method” idea is still not particularly convincing, this way you don’t insult programmers with different opinions and you sound like a reasonable person – non-preachy and non-zealot-ey.
Good Work.
Reading these blogs, and all the comments they’re generating, it strikes me that there is a key difference apparent between the two camps.
The pro-TDD lobby seem to mostly have experienced the other side of the fence, namely software development without TDD. Their position is informed by what they have learned without it.
However, the anti-TDD lobby, from what I can tell, don’t seem to have the equivalent experience of software developement actually using TDD. They’re refuting the opposing argument based on belief but not experience.
That anti-position suggests possible elements of second-order incompetence to me, as described excellently somewhere in Andy Hunt’s Pragmatic Thinking & Learning, which I guess most people on here have read.
For my own part, I’ve spent the last two years of a 12-ish year career using TDD where it fits and feel thoroughly enlightened. I don’t see myself going back to how I used to be.
This debate seems like it is unresolvable to me. Some people get it, but some clearly don’t and nor do they want to. Pretty soon, I’m sure, someone is going to compare the other side to Nazis. Then we’ll be able to cite Godwin’s law and move on to more productive discussion… :)
>You are joking, right?
I would guess he is not.
A friend of mine has a battlefield story about a “release” made up of holiday photos, burnt to a CD and delivered to the customer. This gained him more time to get the release in order. The cover story was that the wrong CD had been put in the cover. He did this on purpose rather than tell the customer he needed more time.
Checking in empty files is at least only visible internally, and the idea is probably much easier to entertain.
Uncle Bob: Very, very good post.
Well, that’s quite a bit of back-pedalling from what we usually hear from you about TDD. Refreshing, really.
“Of course this is human nature. Once you have the code “working” why write tests?”
Professionalism?
If you have developers who need to be ambushed into using TDD in order to write any tests at all, you have worse problems on your hands (and you can bet that even these TDD tests that they will write will be of poor quality anyway).
As for your last four points, they are all well taken but again, you are just saying that tests are very important, and we all agree on that. But none of these points explain why writing these tests first is so important, so you are basically confirming TDD skeptics in their position.
A lot of companies have very simple processes to make sure that both code and tests for that code is written, such as bug tracking, peer reviews, etc… All these fill the goal of making sure that tests are written and they don’t incur the heavy penalty that TDD imposes (code churn, analysis paralysis, working with broken code most of the time, etc…).
Anyway, I really like the tone of this post much better than your previous ones, thanks for that.
I’m really getting tired of the old saw “If you don’t like TDD you just haven’t used it”. I have, in plenty of places, and I can still understand where the non-TDD folks come from.
Instead of explaining what’s good or bad about TDD, let me just share with you what didn’t work for me.
#1: Large C++ projects and TDD
Pure compile/link times will kill any momentum you have with a test-code cycle. Yes, you can still do TDD, but it hurts. Large-Scale C++ is almost as bad as good old batch systems with punch cards when it comes to iteration time.
Of course, you can alleviate some of that with better decoupling – which leads straight to the next obstacle.
#2: Performance requirements For better or worse, I live in a world (AAA video games) where utmost performance is king. Unfortunately that often means a very tight coupling between systems. Hence, even small changes cause large rebuilds – your iteration time is dead, again.
I’d love to be proven wrong and see anything but the most trivial examples for TDD in games, but so far that’s a scratch.
#3: Fiddling A lot of work in the games space is “fiddling” – tune it until it feels just right. And as Uncle Bob rightly points out, that means TDD is actually in the way
#4: Implementing existing algorithms If I implement code based on a research paper – again, a common occurrence in games – TDD is not working that well. After all, I don’t want my tests to drive the code. I know what the end result must be already. You can write some tests before you start, but that’s not TDD.
#5: “No debugging” is not always true.
This claim fades away in the face of concurrency and manual memory management. Add to that the fact that we often need to treat data structures simply as a stream of bytes (for performance reasons), and you will be spending a lot of time in the debugger.
====
But all that does not mean TDD is useless – there are plenty of cases (low-level systems work) where you still can TDD. It just means that there are specific problems where you cannot apply TDD.
The tricky part is knowing what those problems are.
>>>Uncle bob said: ‘Eventually the team started checking in empty source files in order to be “done” on time.’
>>You are joking, right?
>I wish I were. But no. When schedule pressure mounts, people can rationalize even the strangest behaviors.
Perhaps this behavior is not that strange. What happened to the code that was “done” this way? I guess the missing functionality was eventually discovered by testers or users, so the developers had to implement it later… Well, this looks like the TEST FIRST strategy in action, even if it was applied unintentionally. As a matter of fact, this is very interesting: under pressure, the developers naturally decided to do The Right Thing. They decided to let the tests (regardless of the nature of the tests) fail first, before implementing any code…
Some languages don’t suit TDD and I think C++ is one of them. Tooling can get you so far, but if the time it takes to get the tests running is too high they loose some of the utility, especially for full on TDD.
Games do have a lot of fiddling, but your tests don’t necessarily have to be accurate either. There is still a lot of utility in only testing the parts of the algorithm you want to test. For instance jump speed calculations might get tweaked to allow higher or lower jumps based on play testing. The test doesn’t have to say it must increase by 0.5 the first tick and 0.4 the second, could simply state that it should increase the height and not specify by how much.
Most of the resistance however is not in these domains. Even in places like banks where we are talking risk calculations, balance updates and stock trading the code does not have unit tests. Finance developers for the most part are hugely opposed to unit testing, let alone TDD. I am not bothered about games developers working in C++ their position is justified in many cases, but the bank have exactly the attitude above. Never tried it and not interested.
Gosh, I thought I did talk about why writing tests first is important. Perhaps you missed it?
Well, Cedric, I’ve got to call you on this one. TDD certainly does not impose code churn, or analysis paralysis. When I do TDD I find the code develops quite far more linearly then when I did not do TDD. If you were to play back one of my editing sessions from 10 years ago, and one from this year, you’d find far less churn in the process in the later session.
Your last point is incredible. “Working with broken code most of the time”??? On the contrary a major aspect of TDD is working with working code most of the time. Again, if you were to compare how I worked 10 years ago with how I work today, you’d find that the time between working executions was several orders of magnitude longer in the past than it is today.
Let me expand on these points, then.
By analysis paralysis, I mean… well, just see the Ron Jefferies Sudoku example. It’s a perfect example of yak shaving that makes TDD developers lose track of their goal.
By code churn, I mean that I write tests for code that I’ll be throwing away. Many times. And when I change this code, I will have to change my tests as well because the signatures and the API will change.
So with TDD, I do
test v0
code v0
test v1
code v1
test v2
code v2
Without TDD, I do
code v0
code v1
code v2
now I’m reasonably happy that I have something stable, so I write a test
... and I’ve saved a lot of time by not writing tests for throwaway code.
As for my “broken code” comment, I was referring to the fact that when you use TDD, you spend a lot of time writing code that doesn’t compile.
That’s the idea, isn’t it? You write code to test a function that doesn’t exist, then you write that function to make the code compile and then more code to make the test pass.
Well, with this approach, you are basically incapacitating your IDE and preventing it from helping you write your code. You spend your time juggling files that light up your IDE windows with errors and prevent its most basic functions (auto completion, smart browsing, incremental compilation, etc…) from working properly.
Now, that’s what I call being back in the stone age :-)
I really appriciate all the hard work you do, I have read numerous articles, Clean Code book, and watched videos and just wonder where you get the time.
You have really helped me think hard about coding and taught me to try and code well. Programming is not a job its a practice of continuous improvment.
Thanks
A comment to Cedric because he wrote something that puzzled me.
“Well, with this approach, you are basically incapacitating your IDE and preventing it from helping you write your code.”
I practise TDD quite faithfully. I haven’t met anyone who operates Eclipse faster than I do. Not one; not yet. Your logic simply doesn’t hold. The only difference, perhaps, is that I use “Quick Fix” more frequently than “Code Assist”.
The page 66 of “Slides from Dissertation Defense” at http://works.bepress.com/djanzen/4/ is rather interesting. See also the conclusions.
That’s an example about not knowing the right algorithm for an algorithmic problem.
All problems at Project Euler are easy when you know the algorithm for solving them. If you don’t know the right algorithm, then you can spend lots of time trying different dead ends, regardless of which technique you use to write code.
If you need to change the tests because of changes to the signatures and APIs, then your tests are too tightly coupled with the production code. Such tests are bad.
Good tests are very decoupled from the implementation – they are focused on the desired behaviour (see BDD), and that behaviour stays the same when code is being refactored. The behaviour changes only when the requirements have been understood wrong or the requirements change.
If the requirements change completely (for example, initially you wrote a Tetris game, but then you realize you should have written a Pong game), no development technique is going to save you from a major rewrite. But if there are only minor changes to the requirements (for example, instead of a single-player Tetris game, it should be a multi-player Tetris game over the internet) then TDD will help to make the change easily, without loosing or breaking your previous effort.
With TDD all code is written in small increments, which are basically the same as many minor changes/additions to the requirements. So when some code has been written with TDD, it has already been proved to be easy to change and maintainable (or if the developer is not skilled enough designer to write as decoupled code as is required by TDD, then the project did grind to a halt already long time ago). So when the requirements change, it will be easier to implement those changes, than with code which has been written in one go, without the continuous battering of changes that TDD’d code has gone through and survived.
Code that does not compile for 5 seconds, to be exact. Otherwise you are not doing TDD: http://www.butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
With the non-TDD approach you write code that does not compile for many minutes. I’ve even heard rumors of traditional developers, who write code for many days before compiling.
With TDD that simply is not possible. You must run all your tests every minute or so, so of course it must compile at all times. Even stronger, it must work at all times. If over 5 minutes pass without getting all tests to pass, You Are Doing It Wrong™, and you should revert to last known working state (i.e. a commit to VCS from about 5 minutes ago; reverting is often faster than debugging) or soon you might enter Refactoring Hell.
Hi JB,
Indeed, I write a lot more code with Ctrl-1 than I do with any other content assist provided by Eclipse. I don’t even bother declaring the types of my variables any more, Ctrl-1 does it for me.
Still, my premise holds: by design, TDD forces you to spend a lot of time with files that don’t compile, which comes with a set of problems. The IDE lighting up like a christmas tree is only one of the negative consequences of this fact (somebody else pointed out that compilations can be very expensive depending on your language and your project).
Anyway, this particular point is pretty minor compared to my other problems with TDD, but I’ve never seen it mentioned by anyone, so I thought I’d throw it in here.
Hi Esko,
“That’s an example about not knowing the right algorithm for an algorithmic problem.”
Well, that’s a pretty common situation, isn’t it?
You have to solve a problem and initially, you’re just not sure how to do it. That’s what coding is and that’s why it’s such an iterative process.
The flaw of TDD is that it’s trying to capture every single stage of that iterative process, even those that are dead-ends.
It’s also trying to capture stages that are correct but suboptimal, or temporary prototypes, and that will be improved very soon.
I think that resisting the urge to write tests until you have code that looks in decent shape is common sense.
“If you need to change the tests because of changes to the signatures and APIs, then your tests are too tightly coupled with the production code. Such tests are bad.”
That’s circular reasoning. Eventually, your tests invoke a method in your production code, and if that method’s signature changes (which is pretty common in the early stages of solving a problem), you will have to update your tests. That’s needless churn.
“With TDD that simply is not possible. You must run all your tests every minute or so”
I’m sorry, but this is nuts.
And probably one of the reasons why TDD is simply not catching on.
There is such a thing as a “zone” for developers. You know, a very productive mental state during which your brain is completely immersed in the coding process. You know what you have to do, you’re not quite sure how to get there yet, but you code, run, debug, observe, refine. The world around you stops existing for a while. This is a great place to be for a developer, and on good days, you can be in that “zone” for several hours, until you finally reach a milestone that makes you feel that you are one step closer to your big final goal.
Having to interrupt your coding every few minutes just to run tests is a productivity killer, and it’s exactly what paralyzed Ron Jeffries in his attempts at writing a Sudoku solver.
It’s exactly what is wrong with TDD.
> Well, first, there’s the George-Williams study, which showed that teams who are instructed to write tests afterwards, don’t write tests at all.
Huh? Did you even read the paper you linked? The control team wrote tests.
> Once you have the code “working” why write tests? Writing tests for code that you believe works feels like a waste of time.
Ever heard of regression tests?
> When you write the tests first, this simply cannot happen. When you write the tests first every coding decision you make must support testability.
Not True. When you write black box tests, every line of your code does not need to reflect on the test. When you whitebox test, your tests are coupled to your code and you ends up maintaining 2 sets of code.
> Clearly writing the tests first forces an extremely high degree of compatibility between the tests and the code.
No it doesn’t. You have yet to present anything convincing to back up your assertion.
> Writing the tests first also means that your first thoughts about the code are from the point of view of a user.
The users care more about acceptance tests, not unit tests.
They also care about non-functional requirements e.g Does the system have high availability, reliability, performance? Does your test-first tests show any of that? I don’t think so.
However, I can give you some credit for finally having a post that isn’t childish
Cedric,
The Ron Jeffries thing is a red herring. He was allowing us to listen to him think-out-loud. The next time you have a difficult problem to solve, let us listen to you think-out-loud, and we’ll see if you are more linear and direct than Ron. <grin>
As for the churn, it just doesn’t happen that way. Sorry, but I’ve been TDDing for almost a decade now. The often feared churn between the tests and the code simply isn’t significant. It’s nice hypothesis, but it doesn’t hold in practice.
As for the spending a lot of time writing code that doesn’t compile, uh, exactly who doesn’t do this? In TDD you write a test, that may not compile, then you write production code that makes it compile. This cycle lasts a minute or so. So your code compiles correctly every minute or so. To me that’s spending very little time not compiling.
As for running your tests every minute or so, you said it was nuts. I must be nuts! Now in truth I don’t always run my tests every minute or so. Sometimes it takes five minutes. Sometimes ten. Rarely, but sometimes, 15. But if you counted the number of times I run tests in 4 hour coding session it would very likely be more than 100.
As for the “zone”. Warning to developers: Stay away from the zone! It may feel productive. It aint…
Does TDD disrupt the tunnel vision of the zone? No, tomatoes do. (e.g. frequent breaks). You can get into the zone while you are TDDing just as easily as you can get into the zone when you aren’t. At least I can. And so I set a timer to snap me out of it every 20 minutes or so. In my (rather long) experience, the zone is not the place you want to be.
As for TDD not catching on… what planet are you talking about?
Yes, but unrelated to TDD.
With simple algorithms, like 99%* of what are needed in everyday programming, it’s possible to derive the algorithm with TDD. Here are two examples: http://www.butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata http://www.butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata
With complex algorithms, such as “quick sort”, “concurrent mark and sweep” (Dijkstra 1978), “an on-the-fly cycle collector” (Paz 2005) and the like, it’s not possible to arrive at the solution by just writing more test cases which describe the problem. You need to have a clue about what the solution is, and after that you can use TDD to drive the code towards the solution.
But thankfully those “complex algorithms” are only 1%* of all algorithms that are used in everyday programming. And those algorithms you just have to learn by reading books and research articles about algorithms.
Maybe Ron Jeffries did not notice that the sudoku algorithm was one of those complex algorithms, or then he just wanted to experiment whether he could anyways test-drive the algorithm and deliberately decided to not check from the Wikipedia article “Mathematics of Sudoku” that what is the right algorithm.
* Statistics based on the Stetson-Harrison method.
When the method’s signature is changed with an IDE’s automated refactoring, all users of the method are changed simultaneously, both in production and in test code. There is no churn at all.
And if the change to the signature is such that it can not be done automatically, you will anyways need to change all users of the method, in both in production code and in test code. But because there are the tests, it’s very easy to know which places need to be changed, also when there are no compiler errors (e.g. the semantics of the method has changed), because through using TDD you have produced, as a side-effect (TDD is primarily a design technique), a very complete regression test suite, and running the tests will tell you, in the form of failed tests, that which places you must change.
So TDD makes changing the method signatures much easier.
And that’s exactly what TDD helps the developer to achieve. The fast feedback, the test-code-refactor cycle, helps the developer to get into the zone faster (the exact psychological term is “flow”). That’s one of the big reasons why TDD advocates like TDD so much, and they abhor going back into the old days of cowboy coding and endless debugging.
In my case, it usually takes some 5-15 minutes and a couple of new test cases (or some refactoring) to get into the zone.
Often at the end of the work day, when I’m not yet done with some feature, I leave some todo comments into the test code, and I write there the names of the couple of next tests that I would write. It’s easy to come up with those test names (or specifications) when I’m still in the flow.
Then the next day when I open the same project, I can just begin to write those tests, even though I’m not yet in flow, because the test name I wrote already says clearly what the test should do, and writing test code is very simple when you already know what you should test next. After making a couple of tests to pass, I’m already back in the flow and knowing what tests to write next just flows from my mind to the keyboard.
(Repost. The bloody spam filter appears to filter comments with links and no email, but this blog does not remember my email even though it remembers my name and url.)
Yes, but unrelated to TDD.
With simple algorithms, like 99%* of what are needed in everyday programming, it’s possible to derive the algorithm with TDD. Here are two examples: http://www.butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata http://www.butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata
With complex algorithms, such as “quick sort”, “concurrent mark and sweep” (Dijkstra 1978), “an on-the-fly cycle collector” (Paz 2005) and the like, it’s not possible to arrive at the solution by just writing more test cases which describe the problem. You need to have a clue about what the solution is, and after that you can use TDD to drive the code towards the solution.
But thankfully those “complex algorithms” are only 1%* of all algorithms that are used in everyday programming. And those algorithms you just have to learn by reading books and research articles about algorithms.
Maybe Ron Jeffries did not notice that the sudoku algorithm was one of those complex algorithms, or then he just wanted to experiment whether he could anyways test-drive the algorithm and deliberately decided to not check from the Wikipedia article “Mathematics of Sudoku” that what is the right algorithm.
* Statistics based on the Stetson-Harrison method.
When the method’s signature is changed with an IDE’s automated refactoring, all users of the method are changed simultaneously, both in production and in test code. There is no churn at all.
And if the change to the signature is such that it can not be done automatically, you will anyways need to change all users of the method, in both in production code and in test code. But because there are the tests, it’s very easy to know which places need to be changed, also when there are no compiler errors (e.g. the semantics of the method has changed), because through using TDD you have produced, as a side-effect (TDD is primarily a design technique), a very complete regression test suite, and running the tests will tell you, in the form of failed tests, that which places you must change.
So TDD makes changing the method signatures much easier.
And that’s exactly what TDD helps the developer to achieve. The fast feedback, the test-code-refactor cycle, helps the developer to get into the zone faster (the exact psychological term is “flow”). That’s one of the big reasons why TDD advocates like TDD so much, and they abhor going back into the old days of cowboy coding and endless debugging.
In my case, it usually takes some 5-15 minutes and a couple of new test cases (or some refactoring) to get into the zone.
Often at the end of the work day, when I’m not yet done with some feature, I leave some todo comments into the test code, and I write there the names of the couple of next tests that I would write. It’s easy to come up with those test names (or specifications) when I’m still in the flow.
Then the next day when I open the same project, I can just begin to write those tests, even though I’m not yet in flow, because the test name I wrote already says clearly what the test should do, and writing test code is very simple when you already know what you should test next. After making a couple of tests to pass, I’m already back in the flow and knowing what tests to write next just flows from my mind to the keyboard.
I think the debugging business is quite an important distinction. Even with my faulty TDD practise I see how little I need to debug. I wonder if some of the disagreement comes from differing definitions of “done”. In my early days, I’d finish coding and spend days (or weeks, or more) testing, during which time I might hardly change my code at all. Nowadays, shortly after I finish coding, I’m still “done”, possibly later than previously, but nowadays “done” means “ready to release”. There is no test-debug cycle.
I still drop into an IDE and debug sometimes, usually when I’m failing to use a library or framework properly and need to follow the code through to find out where my failure is occuring.
Testing and Debugging are two complementary activities, especially since users will catch bugs that you didn’t find before shipping (and therefore, never wrote tests for). If you don’t debug much, you probably don’t have a lot of users.
Debuggers are also useful tools during the development process.
I expanded on these ideas a while ago in the following post:
http://beust.com/weblog/archives/000437.html
@Cedric
You praise the mental state that traditional, non-TDD-like programming puts you in, and condemn TDD as a productivity killer:
Your view of TDD is diametrically opposed to that of Martin Fowler, who in his afterword to Kent Beck’s ‘Test Driven Development by Example’, says:
To try to convey the gist of Fowler’s view in a blog comment, I have turned excerpts of his afterword into bullet points:
@Uncle Bob
What Ron Jefferies demonstrated when he thought out loud is that he’s clueless about the problem and too focus on the solution. That’s what happen when you use TDD. You became too focus on the solution, even though it might even be the wrong solution, and forget to spend time to actually THINK about the problem. If Ron Jefferies succeed with the solver, then he might have some saving grace. He didn’t. He gave up.
> Sorry, but I’ve been TDDing for almost a decade now. The often feared churn between the tests and the code simply isn’t significant. It’s nice hypothesis, but it doesn’t hold in practice.
I’m sorry but since when personal anedote constitute a logical argument?
> In TDD you write a test, that may not compile, then you write production code that makes it compile.
So you don’t write your acceptance test first? Because that’s a long time before that test would compile
> As for the “zone”. Warning to developers: Stay away from the zone! It may feel productive. It aint… In my (rather long) experience, the zone is not the place you want to be.
You seem to keep getting back to the same points over and over again. “I have a lot of experiences, therere for I know best.” “I have been doing something for a decade now, therefore I must be right”
It sounds rather religious fundamentalist to me. Do you happen to also sell snake oil?
@Undle Bob “As for the “zone”. Warning to developers: Stay away from the zone! It may feel productive. It aint… In my (rather long) experience, the zone is not the place you want to be.”
Wow.
I think that puts you squarely against a LOT more research about the value of “flow” in software engineering than there is in support of TDD. This statement alone made me take you MUCH less seriously.
It’s funny how we are supposed to trust the opinion of a TDD advocate purely on the basis of his experience – seeing how all his arguments pretty much boil down to “my long experience with TDD proves that it works” – yet we can’t dismiss TDD for our needs based on our own experience.
Like other posters I liked the tone of this post much better, but there is still some snarkiness in there. For example he talks about people who can’t TDD because it breaks their flow, but then compares them to an assembly programmer he worked with who doesn’t understand pointers. Also the last paragraph seems to suggest that the TDD skeptics are being dishonest in their skepticism – notice the italicizing of the word “honest”.
What’s so hard about conceding that maybe, just maybe, the so-called TDD detractors don’t want to TDD for perfectly valid reasons?
@James,
Do you have any blog or some thing that a normal developer like me learn from before I fall in to Uncle Bob’s TDD trap?
You are saying he is wrong but what is right? I do want to learn to better my craft.
It just feels sick to read these disagreements without the alternatives!
@Chandra
Just try it for yourself, and see for yourself when and where it works for you (or not).
I don’t think TDD never works, or that it should never be tried. You should however be aware that among those who do not practice TDD are people who have been influential in implementing much of the software that are used to develop TDD style today. Many of these people do not practice TDD, not out of ignorance, but simply because it does not work for them. Considering that they have a lot more code under their belt, I think it is the height of arrogance to just assert, pretty much without backing it up, that they have been zigzagging their way around the grid and with TDD they would simply go from point A to point B.
So just try it for yourself. If it works, great! If not, then just move to something else, with the confidence that the evidence for successful software development without TDD is overwhelming.
I suppose that because I left two comments, somehow the first one didn’t make it through moderation. I’ll try again.
Bob, I’m surprised that you don’t test-drive Velocity templates. I do, although I only test-drive the structure of the template (notably which placeholders for data I need, and which HTML IDs I assign to those placeholders) and leave look and feel to manual inspection during the fiddling activities. Have you tried this and it didn’t work, or have you just not tried it? I demo it all the time to quite good effect.
“It’s funny how we are supposed to trust the opinion of a TDD advocate purely on the basis of his experience – seeing how all his arguments pretty much boil down to “my long experience with TDD proves that it works” – yet we can’t dismiss TDD for our needs based on our own experience.”
Ahh but Uncle Bob’s experience is of a better quality than yours , didn’t you know? ;-)
“Like other posters I liked the tone of this post much better, but there is still some snarkiness in there.”
Yes there is. What did you expect?
My view: Uncle Bob hasn’t written such a reasonable post (relatively) advocating TDD (vs his usual name calling) in ages, if ever. So, progress.
Hopefully he’ll eventually come to the point that “TDD works for me” and stop there without casting aspersions (even through mild snark) at programmers who think and feel differently.
“There is such a thing as a “zone” for developers. You know, a very productive mental state during which your brain is completely immersed in the coding process. You know what you have to do, you’re not quite sure how to get there yet, but you code, run, debug, observe, refine. The world around you stops existing for a while. This is a great place to be for a developer, and on good days, you can be in that “zone” for several hours, until you finally reach a milestone that makes you feel that you are one step closer to your big final goal.
Having to interrupt your coding every few minutes just to run tests is a productivity killer, and it’s exactly what paralyzed Ron Jeffries in his attempts at writing a Sudoku solver.
It’s exactly what is wrong with TDD.”
Running tests does not take me out of the zone. It used to, but it doesn’t any more. In general, new techniques tend to disrupt flow until the practitioner internalizes them. This is not a new problem, it is not a difficult problem, and it is most certainly not a TDD problem.
Try replacing “TDD” with “a new technique” in your paragraphs, and you don’t change the meaning at all.
“Still, my premise holds: by design, TDD forces you to spend a lot of time with files that don’t compile, which comes with a set of problems. The IDE lighting up like a christmas tree is only one of the negative consequences of this fact (somebody else pointed out that compilations can be very expensive depending on your language and your project).”
No, your premise does not hold, because you have an unspoken assumption.
If you write a test that introduces 10 or more new identifiers into the system at once, then you do spend several minutes without code that compiles. I see how that could create problems in some cases, although I don’t find the problem onerous in Java with Eclipse or even in Ruby with Textmate. I can see this disrupting flow and creating problems.
I tend not to write tests that big. I tend to write tests that introduce a small handful of identifiers at once, and often only one or two. (Sometimes none!) I spend seconds, not minutes, with code that doesn’t compile.
Good stuff.
Great article. One sentence that really stands out for me is this:
“A team of developers needs to have a design vision that they have agreed upon”.
I totally agree with this – I have worked on a number of projects where teams were starting out with TDD (and Agile) and had a lot of really strong senior developers but no tech lead to drive the design/vision and the project forward, perhaps because of a misconception that you didn’t need such a beast when doing this style of development.
The result was conflicting test driven designs and lots of arguments in daily meetings about the direction the designs should take. “We should do it MY way because look, I’ve written all this (TDD’ed) code.” “No, we should do it MY way because I’ve written even more (TDD’ed) code than you have AND I have better coverage.
and so on….
The point is that, without a single, clear vision, all the TDD and Agility in the world matters not one jot….
Balanced and convincing. I’ve seen a lot of posts about TDD which struck me as verging on religious statements. This post tackled many of my concerns, because I’ve always wondered when it is appropriate and when it isn’t.
I don’t always use TDD, as a lot of what I have to do falls into the category of “how do we get this thing working?” but I will say that the first project in which I was able to apply it started off as a prototype without TDD and morphed over a fairly short time into a well designed system that used TDD and has pretty good coverage. The prototype let me learn about the problem space and realise that I was solving the right problem and the TDD let me be certain that I was solving the problem right.
Both activities were equally important: without the prototype I wouldn’t have understood the problem as well as I did when I got to the point of designing the solution, and without the TDD the resulting code would have been far more coupled than it needed to be.
(Seems like the spam filter ate this post, but did not vomit it out during last night. Let’s try again, but without clickable links. Does this blog get so much spam that such a moderation queue is needed? I wonder what they advertise… “a pill to make your tests always pass”, “enlarge your test suite”, “replica code”, “pics of elegant design”?)
Yes, but unrelated to TDD.
With simple algorithms, like 99%* of what are needed in everyday programming, it’s possible to derive the algorithm with TDD. Here are two examples: xttp://www.butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata xttp://www.butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata
With complex algorithms, such as “quick sort”, “concurrent mark and sweep” (Dijkstra 1978), “an on-the-fly cycle collector” (Paz 2005) and the like, it’s not possible to arrive at the solution by just writing more test cases which describe the problem. You need to have a clue about what the solution is, and after that you can use TDD to drive the code towards the solution.
But thankfully those “complex algorithms” are only 1%* of all algorithms that are used in everyday programming. And those algorithms you just have to learn by reading books and research articles about algorithms.
Maybe Ron Jeffries did not notice that the sudoku algorithm was one of those complex algorithms, or then he just wanted to experiment whether he could anyways test-drive the algorithm and deliberately decided to not check from the Wikipedia article “Mathematics of Sudoku” that what is the right algorithm.
* Statistics based on the Stetson-Harrison method.
When the method’s signature is changed with an IDE’s automated refactoring, all users of the method are changed simultaneously, both in production and in test code. There is no churn at all.
And if the change to the signature is such that it can not be done automatically, you will anyways need to change all users of the method, in both in production code and in test code. But because there are the tests, it’s very easy to know which places need to be changed, also when there are no compiler errors (e.g. the semantics of the method has changed), because through using TDD you have produced, as a side-effect (TDD is primarily a design technique), a very complete regression test suite, and running the tests will tell you, in the form of failed tests, that which places you must change.
So TDD makes changing the method signatures much easier.
And that’s exactly what TDD helps the developer to achieve. The fast feedback, the test-code-refactor cycle, helps the developer to get into the zone faster (the exact psychological term is “flow”). That’s one of the big reasons why TDD advocates like TDD so much, and they abhor going back into the old days of cowboy coding and endless debugging.
In my case, it usually takes some 5-15 minutes and a couple of new test cases (or some refactoring) to get into the zone.
Often at the end of the work day, when I’m not yet done with some feature, I leave some todo comments into the test code, and I write there the names of the couple of next tests that I would write. It’s easy to come up with those test names (or specifications) when I’m still in the flow.
Then the next day when I open the same project, I can just begin to write those tests, even though I’m not yet in flow, because the test name I wrote already says clearly what the test should do, and writing test code is very simple when you already know what you should test next. After making a couple of tests to pass, I’m already back in the flow and knowing what tests to write next just flows from my mind to the keyboard.
@Esko Luontola: Nice comment. Thanks
I like this post very much. One thing I’d like to comment: “There is a set of problems for which TDD is not particularly helpful. GUIs are an example.” Apart from GUIs people are afraid of tdd because it seems to many of them that they will be taken the fiddling with code away. And fiddling with the code is how they’ve been producing code so far. All the test they have to write now – it’s so rigid afterwards – you can’t break the test anymore and you have to put down what the code has to do – and it get even veryfied every time someone hits the bloody button :) I can see it over and over again.
Rachel ‘Groby’ Blum:
It’s true (in #1) that having a long cycle time can prevent use of TDD. I find that if it takes more than 30 seconds then emotional foot-dragging steps in and running the tests becomes a decision the programmer has to make. I have also seen programmers change the code to make it dramatically faster. Incremental builds and separate, smaller test builds can help a lot. Testing “in context” is a killer. Sympathy, but you will find that if you can improve build/test time, it is well worth the investment.
On #2 I’m assuming you’re being scientific and measuring all the performance issues and the reasons for them. I have been frequently surprised at which changes will increase performance and how little some other changes will hurt it. Un-weaving multiple concerns from “if” and “for” statements hurts surprisingly little, but using more primitive data structures can make code more confusing to read. The more confusing the code is, the more useful naming and testing are… within bounds of course.
Outside of the game world, a lot of performance management is done by old wives tales and rules of thumb and “seeming” faster. It would be cool to see what you’ve learned about performance in a series of blogs. Post a URL if you get a chance.
In #5, I also agree. However, it is much easier to debug from a test entry point than it is to debug a system that is running. Some weird bugs may still require exploratory debugging, sure, but overall my debugging time is far less and far easier with TDD.
As for #3, I’m fiddling now in a web system, before going in with TDD to nail down what we decide is “right”. Fiddling is like that.
Cheers.
All this discussion about TDD or not TDD is what led to the development of BDD. It really confused me while unit testing my objects, but everything changed when I started to test the behaviour.
I didn’t get why the “zone” or flow is so bad.
I stopped using the pomodoro technique just because it was taking me off the zone. I think it is worth to try it if you’re having concentration problems.
@Chandra: Do you have any blog or some thing that a normal developer like me learn from before I fall in to Uncle Bob’s TDD trap?
No. Just use your common sense. If you have a complex problem, research and understand the problem. This might involve breaking the complex problem into smaller problems. Hopefully solutions to those small problems fit to solve the complex problem.
When you are attempting to solve problems don’t attempt to write production quality code right away. Write enough for you to understand the problem.
From my experience, the majority of project failures are caused by lack of understanding of the problem/requirements.
Analyse, prototype, experiment and search for known solutions or recognizable problem patterns, which Ron Jefferies failed to do. Once you are happy with your prototype and are confident that the logic works for small subsets, write tests to catch bugs for larger subset. Be diligent to clean your code
If your problem is mission critical, use formal methods to prove your solution e.g induction, deductions, etc. Most of the time, tests inputs are only the subset of the domain inputs. Tests ONLY catch the bugs you EXPECTED. Not all tests are of equal value. There is little value spending 90% of the time testing something that is only used by your users 10% of the time. Recognize the point of diminishing return; which is hard to do when you write all your tests first.
Personally I use tests to verify and validate the solutions, not to drive my thinking. Why? Because I find writing test-first cause me to have tunnel vision of the problem. It’s like solving maze by placing your hand against the wall instead of having a top down view of the maze. I also find that it is faster for me to model and design on paper than to deal with the syntactic sugar of the language when writing test codes.
Thank you! This was extremely helpful. And, FWIW, I recently started playing with the UI Automation Framework for Windows that actually allows you to test-drive a .NET UI from nunit, and this is really cool! You can actually test-drive your user interface.
I agree that sometimes you want to fiddle. And I think this is true not only in the UI but sometimes in your backend code as well and so I like the flexibility to take larger or smaller TDD steps to accommodate this. I often find it hard to work in the micro steps, but I think maybe it helps to switch it up a bit – sometimes very tiny steps sometimes larger ones. I do worry if you’re always tiny step by tiny step you can miss the forest for the trees. But then you can, of course, end up too far in that direction as well. So switching it up maybe helps keep you thinking about the code in new ways.
Hi Esko,
“With simple algorithms, like 99%* of what are needed in everyday programming, it’s possible to derive the algorithm with TDD. Here are two examples: xttp://www.butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata xttp://www.butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata”
You seem to assume that all coding problems are based on algorithms. These are pretty rare cases, in my experience. TDD is pretty easy to use in such easy cases, which is why all the slides that demonstrate TDD are based on trivial problems such as bowling scores or a Stack class.
More common coding problems involve things such as thread safety, updating databases, synchronizing UI’s with models, manipulating GUI elements, etc… And TDD is not applicable to most of them, or so much extra work that it’s just not worth spending the time writing the tests first.
“And if the change to the signature is such that it can not be done automatically, you will anyways need to change all users of the method, in both in production code and in test code. But because there are the tests, it’s very easy to know which places need to be changed”
You don’t need tests to tell you that if you are using a statically typed language. And whether the changes are made automatically by your IDE or not, it’s still code churn, which causes needless recompilations.
Compilation churn is something that keeps being overlooked by TDD advocates as if it was negligible, which makes me wonder if they are actually using TDD on huge code bases.
“TDD is primarily a design technique”
TDD advocates should probably get the story straight about this particular point, because I keep hearing this and its opposite…
“So TDD makes changing the method signatures much easier.”
TDD forces you to change much more code and to adapt tests for code that you will throw away, so I don’t think that “easier” is the correct description.
“And that’s exactly what TDD helps the developer to achieve. The fast feedback, the test-code-refactor cycle, helps the developer to get into the zone faster (the exact psychological term is “flow”).”
TDD forces you to switch between two zones constantly: the coding zone and the testing zone. Again, Ron Jeffries’ example is a perfect illustration of the kind of paralysis this can lead to. It works for you, JB and Bob, but why is it so hard to understand that it doesn’t work for everyone?
“That’s one of the big reasons why TDD advocates like TDD so much, and they abhor going back into the old days of cowboy coding and endless debugging.”
You seem to imply that the more tests you write, the less you debug, which is quite a stretch. If you have a lot of users, you will have to use the debugger, if only to investigate bugs that you shipped with and for which you never wrote tests for since you didn’t know they existed in the first place. Besides, I also find the debugger to be very convenient when writing the code. Unit tests are useful, but they don’t expose your naked code as well as a debugger does. I expanded on these ideas here: http://beust.com/weblog/archives/000437.html
Finally, I’m curious: do you have some open source code out there that I could take a look at? Obviously, TDD works for you so I’m curious if there’s something about the project you work on that makes the code you write more amenable to TDD than others.
Think Xradar is an excellent tool to use to measure total quality of systems.
Gives an rough estimate based on code, design,test & architecture.
Example report from my current project http://cia.sourceforge.net/xradar/index.html .
Highlights the balance between different types of effort to improve quality.
All the best
Hi James,
“Because I find writing test-first cause me to have tunnel vision of the problem. “
Couldn’t agree more. TDD encourages micro-design over macro-design.
It basically makes all problems boil down to the level of individual methods, while it’s often preferable to think in terms of classes, hierarchies or design patterns. Suddenly, you are no longer trying to solve a problem with reasoning: you are trying to come up with the best signature for a method that will make it easy to test.
This is not a bad reflex to have, by the way, but it should not be your top priority when you are making your first steps on a specific problem.
“Do the simplest thing that could possibly work” (YAGNI) is equally harmful to the reasoning process. If your experience and skills tell you that you will need three different classes to solve the problem at hand, then go ahead and write these three classes, even if two of them will only come in handy in a few hours.
Basically, use your judgment and rely on what your intuition is suggesting to you instead of obsessing over making sure you don’t write a line of code unless it already has a test.
Nobody here has even claimed that TDD would miraculously solve those kinds of problems. Instead, we have been saying that those are hard to deal with.
Use the right tool for the right problem. It’s not the hammer’s fault that somebody tries to use it like it was a saw. A hammer is good for many things, and a saw is good for many things, but those things that they are good for are different.
Dealing with things such as concurrency, databases and GUIs is done for example by using suitable design patterns, which minimize the code for which writing tests is too hard.
Compiler finds some kinds of problems, tests find the same problems and a lot more. The guarantee given tests is a superset of the guarantee given by a compiler. Even so much, that in a dynamic language the tests very much compensate for the lack of compile-time checking.
Even if you don’t have tests, when you change a method, you will need to recompile. So your argument has no basis. A recompile of the changed files (and their users) is needed in any case.
You appear to have the opinion, that throwing code away is a bad thing. On the contrary, throwing things away is quite often a reasonable thing to do, because the value is not in the code but in the programmer’s head: After you have written some code, you will know how you should have written it, and often that is not how you did write it. Refactoring or even rewriting will then let you to arrive at a better solution, with just a fraction more time. xttp://objectmentor.com/resources/articles/craftsman4.pdf
No. There coding and testing are not different zones. They both are the same zone. In TDD they become intertwined. TDD supports the factors that produce flow: xttp://en.wikipedia.org/wiki/Flow_(psychology)#Components_of_flow
When you stop thinking about TDD as testing, then everything about TDD slowly begins to make sense. In TDD, when you first write a “test”, it is when you decide what should be done. Then when you write the code, you decide how it should be implemented. And finally when you run the tests, you verify that your “what” equals your “how”.
So the TDD cycle is in traditional terms this: specify, implement, test. Sounds familiar, eh? TDD is not really test-first, but instead TDD is specify-first and test-last.
Every programmer does the same things of thinking about the “what” and the “how”, and finally verifying whether they match. The difference is that traditional programmers are not as strict about it as TDD programmers.
A traditional programmer will think in his head that what the code should do, after which he thinks how to implement it and writes the “how” down as code. After that he will try to verify that his “what” equals his “how”, which he does by running the program, reviewing the code and by debugging it.
A TDD programmer on the other hand is more organized and formal about defining the “what”. He writes it down as an executable specification of the desired behaviour, which he can then automatically verify at any point in time. Even all developers on the project can verify them, including the original programmer long after he has forgotten the “what” that he had in his mind weeks and months ago.
Here is my primary hobby project at the moment, fully written using TDD: xttp://dimdwarf.sourceforge.net/
My GitHub account (xttp://github.com/orfjackal) has some more projects. I started using TDD in 2007, so projects older than that were not done with it (in case you find some of them with Google). Since 2007 just about everything I’ve written has been with TDD, except maybe some small scripts. Also in projects written before 2008, the code is probably not as clean as I would like them to be today.
Here is a summary of the projects under my GitHub account:
tdd-tetris-tutorial – Tutorial for learning TDD. This reflects the kind of style that I prefer, with well organized tests and clean code (see the “beyond” branch or “step7-done” tag for the final result). I’ve been using that as exercise material this autumn, as I’m lecturing a course “TDD programming technique and designing code” in the University of Helsinki.
dimdwarf – Very complex project, done with TDD. I’m right now restructuring its architecture (explained in my blog xttp://blog.orfjackal.net/), so some of the needlessly complex parts (task scheduling, transactional in-memory database, database garbage collector) will be rewritten to be much simpler. When using TDD, the tests started to emit code smells “Fragile Test” (concurrency bugs) and “Big Setup/Test” (for testing concurrent code), which were indicators that shared-state concurrency was not a solution. This is what initiated the architecture rewrite, but thanks to using TDD and writing clean code the change of architecture is painless.
extformatter – Plugin for IntellJ IDEA. The core was written with TDD, but the parts that integrate with IDEA were not. IDEA’s plugin architecture is not testing-friendly.
visualvm4idea – Plugin for IntellJ IDEA. Only small parts were written with TDD, but the parts that integrate with IDEA and with VisualVM were not. IDEA’s plugin architecture is not testing-friendly, and neither is VisualVM (or NetBeans Profiler).
longcat – Very small example application, done with TDD.
bytecode-detective – Incomplete utility, written in order to learn Scala and Java bytecode, done with TDD.
weenyconsole – The second application that I wrote using TDD. (My first TDD application was a small utility at my work. It generated test data for stress testing a securities clearing and settlement system.)
classmembersorter – Small utility, done with TDD. Used by the JDave testing framework.
thematrixtime – Small utility, done with TDD.
puzzle-warrior – Very incomplete game, done with TDD.
pommac – Very incomplete utility, done with TDD.
Also xttp://code.google.com/p/darkstar-contrib/ has some projects which I wrote using TDD: DarkstarIntegrationTest and DarkstarRPC.
@James, @Cedric
While I understand where you are coming from, I find it interesting that some points you mention are completely opposite to the way I experience TDD.
TDD != production quality. When I am doing some quick experiments, I find it very helpful to use tests to get quick & dirty feedback. If I write code that just compiles, I don’t know anything. If I need the real system to try it out, I will probably need to change/add some boilerplate in the production code, and my feedback loop goes up dramatically. From my experience, TDD usually a very efficient and productive way to experiment with new code.
I think you mean: tests only test the behavior you expected? The whole point of testing is finding bugs you didn’t already knew about. And the whole point of TDD is that you write each new behavior with corresponding tests, so the missing behavior in tests is less.
If some code is in the “fiddle” category, why would you not recognize this is in a TDD fashion? If I hit some UI coding, I go “OMG I need to stop doing TDD here” and go fiddle.
TDD does not mean that you stop doing modeling or are not allowed to use paper. As Uncle Bob mentions, TDD can be great to validate your design, and enforces that interface is written from a client-first perspective versus implementation-first. But if I am doing TDD and my initial modeling turns out bad, I just switch back to modeling first, instead of messing around with tests and code.
Thank you for this good post.
I don’t understand how our industry is still fighting on this. To me, every professional developer knows and says that tests are critical. How you end up writing your tests is really a matter of individual technique.
@Cedric and others tlaking about “the zone”: Don’t you think, some can feel “the zone” without TDD, some can feel it with TDD (I do), some fear “the zone”. There are left-handed and right-handed. Do you agree that the difficult part is not how they write tests, it’s how they can compromise to work together?
In a team, recognizing that TDD is only a matter of taste is critical. How you get to quality is not important.
Now, if you want to TDD and if you feel comfortable with it, you need to learn how to do it well and quick: learn the IDE shortcuts, learn auto-complete, quick-fix, templates… Use a continuous testing tool like Infinitest. Learn how to write not only refactorable code but also refactorable tests.
@David,
Fair point.
It’s pretty obvious to me that the “zone” is a personal experience, so everyone has a different perception of it.
What is baffling to me is that people who say that they can switch from writing production code to testing code back and forth every few minutes claim that:
- It doesn’t impact their productivity on the production code. When you have hard deadlines, any time not spent on writing production code is a threat to make you miss that deadline. Writing tests helps you make your code more robust and easier to refactor down the road, but it also takes away time spent on writing production code. It’s just common sense. I think TDD advocates don’t see that because they don’t really write production code under hard deadlines (i.e. “deadline missed = no pay check, or bad review, no bonus, or no promotion, or other consequences”).
In short, I think they just don’t put feature #1 (“ship on time”) at the top of their priority list.
- This constant switching is simply not for everybody. I’d claim that it’s actually only for a very small minority, and I’ll argue further that the evidence that it produces better code is pretty spotty.
At least, it should be pretty clear by now that not practicing TDD can lead to code that is just as good as that written with TDD.
It doesn’t matter whether you code tests first or test last as long as you write tests.
I can’t say that TDD is better than writing the tests after. But I see a couple of benefits.
1) The tests actually gets written. No manager can cut the time after the productioncode is written and say that there are other more important things to do.
2) Writing code after is damm boring. Trying to write good tests on existing code is also harder than writing them first. It’s to easy to make the code work and forget about how to test it. If there are pressure it’s even easier to forget testability. Writing the tests needs special gifted people that isn’t like any other i know.
But the lack of studies of TDD is disturbing. The question should be: why are there so few studies? So far it seems like first experiance is whats make or breaks peoples views.
2) Last sentence should have been: Writing the tests after needs special gifted people that isn’t like any other I know.
@Cedric,
Don’t you think you are trying to make your own case a general case again? Come on, peace and love :-)
Do you really think that all TDD advocates don’t write production code under hard deadlines? It looks like you are saying that TDDers are not coding for a living then? Not all TDD advocates are consultants-only or book-writters-only. I code for a living, I put “ship on time what the customer needs” first and I sometimes advocate TDD. Isn’t there any developper doing TDD at Google?
Also, that dichotomy between production code and tests looks so strange to me. We ship tested features, not production code. The size of code typed is NOT a good measure of the time spent building a feature. So is NOT the size of the code trashed on the way. One can spend one week writing one line of shipped code, TDD or not TDD.
You are right when you say that writing tests is what matters. How can we improve our tests? I currently focus on decreasing test feedback loop (test quality begin stable). Tools like Infinitest or TestNG // tests really help me on the way.
There is for example this study, which somebody already linked in one of the other articles’ comments:
xttp://works.bepress.com/djanzen/4/“An Empirical Evaluation of the Impact of Test-Driven Development on Software Quality” (Janzen 2006)
The conclusions in the slides of that paper’s dissertation defense say:
If good design and good testing are both necessary for constructing complex software development then shouldn’t there be a level of software complexity where the design of software testing becomes important?
When I compared Peter Norvig’s Sudoku solver to Ron Jeffries’ it made me wonder how Peter Norvig would design tests for complex systems, such as the Google search engine, Android etc. Google has a lot of smart people besides Peter Norvig and this is an important enough issue to occupy some of their time.
I would be much more interested in seeing Google’s software testing systems than their employees’ Sudoko solvers.
The original post made several claims about testing including this oneThat was not the whole story about legacy. My own experience tells me that a little design of testing can get you there faster. It’s hard to imagine that the smart people at Google are not doing a lot better than this. Norvig is a ML guy so I guess he would have some interesting ideas on applying ML to software testing. Can’t find anything on that so let’s see what he has to say on Agile.
“tests are critical. How you end up writing your tests is really a matter of individual technique.”
No one argues with this. Waht you say makes sense. It is Uncle Bob’s zealotry that people who don’t use TDD (which is NOT the same as having a good tests suite, TDD = tests first) are “unprofessional”, “stone age” etc which sound stupid (and invite reactions).
In other words, tests are good. This has been the case from the dawn of software. No one disputes this. The benefits of TDD are more debatable and the insistence that its use is somehow the mark of “professionalism” is idiocy.
“I would be much more interested in seeing Google’s software testing systems than their employees’ Sudoko solvers.”
Google does not mandate TDD to design or code software. Google does emphasize unit testing and code review (unit testing != TDD. I’ m repeating this because TDD aficionados blur the line between unit testing and TDD when it serves their propaganda purposes).
“When I compared Peter Norvig’s Sudoku solver to Ron Jeffries’ it made me wonder how Peter Norvig would design tests for complex systems, such as the Google search engine, Android etc.”
@Peter: I think you mean: tests only test the behavior you expected? The whole point of testing is finding bugs you didn’t already knew about. And the whole point of TDD is that you write each new behavior with corresponding tests, so the missing behavior in tests is less.
WRONG!! When you write tests, what you are doing is validating your solutions against known stimulus. For example: considering you’re testing a method called foo(n). Just because you have passing test cases for foo(1), foo(2) and foo(3) does not mean that foo(n) will pass for every number n. In fact, sometimes there might be a number outside your test cases that you didn’t think about that cause foo(n) to failed. The problem is more prevalent when you start using concurrent programming as your typical XUnit framework breaks down and you might have to resort to formal methods such as petri-nets.
Thus tests only catches KNOWN BUGS, not unknown bugs.
Personally, TDD benefits two groups of people, the trainers who make a fortune selling something blessed water, and the hackers who attempt to do software engineering without understand the fundamentals of: design, algorithms, testing, quality assurance, etc
@James:
TDD is not a good method for finding new bugs, and that’s not what its goal is (TDD != testing). TDD is good for evolving the design and for checking whether the programmer’s specifications match the implementation. But because programmers are humans, their specifications can be wrong or incomplete. That’s where real testing methods come to the rescue: xttp://www.infoq.com/presentations/francl-testing-overrated
“TDD is good for evolving the design “
TDDers keep going back and forth on this one. As Cedric says above, “TDD advocates should probably get the story straight about this particular point, because I keep hearing this and its opposite…”
Design of a substantial piece of software happens at a level well above individual methods and classes, where TDD operates – What Peter Norvig does in his Sudoku Solver is design. Jeffries’s Sudoku Solver is an example of what happens when “design” is done with TDD. He trundles around for a week “listening to his code” waiting for “objects to emerge” and so on and ends up with substandard (but TDD’d !) piece of code that does nothing.
The latest whitewash attempt (by people who make a living selling TDD as a “design method” it must be noted) is “he was explaining his thought process not really trying to solve the problem” or “He was showing how to use TDD to “explore” a domain not really write a Sudoku Solver. Ha ha! Hilarious. Code walks, incompetence talks.
Utterly unconvincing. In the end, if you claim TDD is a design method, you must provide examples of codebases evolved with TDD which show superior design (as compared to non TDD’d code bases).
Pointing at some random successful code base that has unit tests (but not developed TDD fashion) is the best the TDD fanatics have managed so far, by using the “blur the distinction between unit tests and TDD when it suits them” propaganda method.
It doesn’t help that most of the people pushing TDD as a”design method” are “agile coaches”, who can’t really claim any authorship of substantial software.
“He trundles around for a week “listening to his code” waiting for “objects to emerge” and so on and ends up with substandard (but TDD’d !) piece of code that does nothing.”
It is quite impossible to reconcile the Sudoku fumble with the claim that its protagonist “could code us all under the table with one hand tied behind his back”.
@Esko
I find it hilarious that the concept of writting test first, implementation later sprout so many apologist’s definitions of TDD:
1. TDD is test first 2. TDD is quality control 3. TDD is design techniques 4. TDD is specify first, test last 5. TDD is good for evolving designs 6 … 7. Profits
> TDD is good for evolving the design and for checking whether the programmer’s specifications match the implementation.
There are 2 types of specifications, user requirements such as functional and non-functional, and formal specifications such as z-specs, UML, etc. Saying TDD validates specification is half-truthful as ALL tests, written before or after or even by a different teams validate specifications.
Have a read briefly through Software Engineering book by Ian Sommerville before you throwing around your definitions.
As another example, I once worked with a trading company that had to parse incoming streams of trading data. These streams did not have a well defined format. The teams had to fiddle with regular expressions and parsers in order to get the decoding just right. TDDing this would not have been wise. Writing the tests afterwards was imperative.
Not, this is perfect example for testing. Just record some of those data, parse them and compare with expected result.
This discussion reminds me about xttp://xkcd.com/386/ – it won’t lead anywhere.
If you want something to compare, you can compare xttp://www.projectdarkstar.com/ and xttp://dimdwarf.sourceforge.net/ as they both try to solve exactly the same problem, and they both are written in the same language (at least for now; Dimdwarf will quite soon begin using Scala).
Darkstar has not been developed with TDD. It is very much test-last and it has quite a large integration test suite (over 3000 tests which take some 20 minutes to run, which would be unacceptably slow for TDD; in comparison Dimdwarf’s about 500 tests run in 2-3 seconds). Darkstar’s development started in 1999, and it was picked by Sun Microsystems in 2005, after which it has been developed by a team of full-time developers at Sun Labs (right now their efforts are concentrated on making it to scale in a server cluster; on a single server it has been working already a couple of years).
Dimdwarf has been completely developed with TDD. I’m the sole developer, working on it on my spare time since 2008, and this far I’ve worked on it about 170 hours (the man-hours are listed on the project page). Measured in lines of code, Dimdwarf is right now maybe one tenth of Darkstar’s size. It will still take at least 200-300 hours before it is ready for use, which in my schedule means 6-12 months.
You can use whatever metrics you like for comparing them. If you find out something, please write a report and email me or something (although you will probably claim that it is just anecdotal evidence). I’ve once used Sonar for analyzing Dimdwarf’s code, and the reported complexity numbers were lower than just about every project listed on xttp://nemo.sonarsource.org/
Esko
You seem to have interpreted my sentence wrong
When I said,
“In the end, if you claim TDD is a design method, you must provide examples of codebases evolved with TDD which show superior design (as compared to non TDD’d code bases).”
Let me clarify.
What I meant was “In the end, if you claim TDD is a design method, you must provide examples of codebases evolved with TDD which show superior design as compared to superior non TDD’d code bases”
IOW plenty of high quality code bases have been developed without TDD. (Emacs, linux OpenBSD, doom, WoW , TeX). These are the people interviewed in CaW and against whom Bob Martin was railing (as unprofessional” and “stone age”).
When the TDD folks can use their superior design tools to build something of comparable magnitude and quality, then preach the virtues of TDD as a design method.
IOW I was saying “TDD is a design method” is an unproven claim. Use TDD to build a browser better than Firefox, an editor better than VI, a game better than DOOM or World of WarCraft, a language better than Haskell or C, (say), a database better then PostGres, an Operating System better than Linux, Search Engine btter then Google (all examples of codebases NOT developed with TDD and the authors of these code bases being the kind of people interviewed in CaW – the kind of “unprofessional”, “stone age” programmers in Bob Martins’ words .
Once you write a world class product which amazes your fellow developers with TDD (not unit tests, btw ;-) we see through that ruse) , then let’s talk about what is or is not a superior design method.
The measure of superior design methods is the output – superior/world class codebases that are way better than the competition. Not blog entries or vituperation of fellow developers.
Ok! Show us!
I made no claim that you (Esko) can’t do better than some random developers in Sun.
””Seibel: What about the idea of using tests to drive design?
Norvig: I see tests more as a way of correcting errors rather than as a way of design. This extreme approach of saying, “Well, the first thing you do is write a test that says I get the right answer at the end,” and then you run it and see that it fails, and then you say, “What do I need next?”—that doesn’t seem like the right way to design something to me.” “
Do you think we should believe Ron Jeffries (or any other TDD “guru” when he says TDD is a superior design method ?
Let me repeat again so you don’t get it wrong. If you think TDD is a superior design method and people who don’t use TDD are “unprofessional” or “Stone Age”, please show us. Write code better than the best non TDD developers. Demonstrate superiority vs preaching it and condescending to those with different ideas..
First code. Then preaching.
In other words, when Jefrries (as a TDD guru) writes a Sudoku Solver with TDD and Peter Norvig writes a Sudoku Solver without TDD and the former is better, then we’ll listen to what you say.
I decided to elaborate some on what I meant by saying that TDD is not test-first. I wrote about it in my blog:
http://blog.orfjackal.net/2009/10/tdd-is-not-test-first-tdd-is-specify.html
@James
That is true for any test form. In order to predict outcome, you need to have known stimulus.
Sure, but if I write a test for foo(3) and it blows up unexpectedly, I find an unknown bug. Also, most code is simple enough that it either has very small ranges of possible input or has a very linear reaction to it. Of course, for the code that is more sensitive, I’d also so do some additional formal verification and design.
But James, I wonder, if you think testing using known stimulus is a waste of time, how do you ensure quality? You don’t run your application, you don’t trust bug reports with a steps-to-reproduce list? You just do some petri-nets, formal design, hit save and everything just works??
As said in “No Silver Bullet”, the differences between the great and the average people approach an order of magnitude. A great developer can be 10x times better than an average developer.
TDD is not a silver bullet, because it does not give 10x better productivity/quality/etc. in less than 10 years (as a “silver bullet” is defined in “No Silver Bullet”). We can expect 1.2x, 1.5x or at most 2.0x improvement from using TDD – current research supports these numbers (see pages 18-19 of the slides at http://works.bepress.com/djanzen/4/ for references to 6 researches which have produced such numbers).
Because the differences between normal and guru developers are so huge, using any gurus for comparing the benefits of a development technique, which produces at most 2x improvement, will not produce measurable results. A guru will produce good results regardless of the technique he uses, and an average developer whose performance has improved by 2x is still 5x worse than a guru whose performance was originally 10x better.
(And anyways, a Sudoku solver is such a small application, that the differences between any techniques will not be measurable. It’s only after the problems being solved are so big, that the resulting application can’t possibly fit all at once into the head of any developer, that the differences begin to show up.)
And, I suppose, even between gurus there are big differences. The only thing that a guru can be compared to, is the same guru before. You can hear Uncle Bob and other TDD-using gurus telling how TDD has improved their work compared to what they used to produce before. They have personally experienced its benefits, so that’s why they are recommending also everyone else, who wants to become a better developer, to have an honest try at starting to use TDD.
Have you given an honest try at using TDD? Have you read about how it should be done, and then really used it full-time for at least some months? If not, it’s pointless for you to try to raise arguments here (and even after that, arguments are anyways pointless).
But if you really want to give an honest try at TDD, instead of trying to start a flame war, then have a try at completing the TDD tutorial at http://github.com/orfjackal/tdd-tetris-tutorial (see the README.html for instructions – first read the theory, then code using purely TDD). It will take over 20 hours to finish that tutorial, after which you should have a rough idea of what TDD is about. After that you will still need to complete one or two medium-sized projects with TDD, until it’s possible for you to say that you understand TDD. And if you are having problems, that TDD is not working for you, then ask somebody with more experience to instruct you – pair programming with a skilled developer would be the best way to learn.
If you want more help in knowing where to start, posting honest questions on this blog is a good place to start (that’s how I also got started). From now on I’ll stop feeding the troll and only answer honest questions.
Esko,
“Have you given an honest try at using TDD? Have you read about how it should be done, and then really used it full-time for at least some months? “
Why do you assume I haven’t tried TDD?
Peter Seibel has tried TDD, as he makes clear in his latest blog entry. He is still dubious of its use as a design method and very dubious of Bob Martin’s claim that TDD always makes you go faster.
TDD fanatics assume that anyone who doesn’t sing the praises of TDD hasn’t given it a good try. Again this smacks of religious cults! If you really get it, Scientology is awesome. Give it a try! ;-)
Seriously, I have tried TDD, including “pure” TDD on some large projects. My last employer was a pure XP shop, working on some very large. 100% XP, years long projects.
So yes, we get it. TDD is a (somewhat) useful technique to have in your bag of tricks. As Peter Seibel says it can (not must!) be used to drive the implementation. But it is not a design method and certainly not a superior design method and no world class developers ever said so.
If the best TDDers in the world end up coding like Jeffries, it doesn’t make a strong case for TDD. If TDD is so superior, – first produce awesome code and wait for the rest of us unwashed programmers to ask how you did it.
Quoting my earlier post, let the best TDD developers in the world
“Use TDD to build a browser better than Firefox, an editor better than VI, a game better than DOOM or World of WarCraft, a language better than Haskell or C, (say), a database better then PostGres, an Operating System better than Linux, Search Engine btter then Google (all examples of codebases NOT developed with TDD and the authors of these code bases being the kind of people interviewed in CaW – the kind of “unprofessional”, “stone age” programmers in Bob Martins’ words .”
In other words, show us the world class , non “stone age” code developed by your superior design method, that is obviously better than the non TDD people produce, or stop preaching and calling names.
Say “I got better with TDD”. No one will object. Say “Those who don’t use TDD are non professional” and you can bet your keyboard, people will ask “So where is all this superior code that gives you the credentials to say things like that? “
And then when you have a TDD guru stumble around for a week using his favorite “design method” and ending up with ridiculous results on a minor coding problemt, you are surprised people are skeptical?
People not accepting your claims of superior development methods without seeing evidence is not “trolling”. They are just saying “Ok you showed us the hat. Now show us the cattle”.
The evidence for superiority of a design method is the code it produces. Not blog entries. Not tweets. Not name calling. Not flawed research results. Not slideshows.
Show us superior code produced with TDD “design”. Then preach its virtues. if you only preach and never show world class code, don’t be surprised when experienced developers flip the bozo bit on you when you rant and rave against people who’ve shipped a ton more high quality code than you.
“The only thing that a guru can be compared to, is the same guru before. You can hear Uncle Bob and other TDD-using gurus telling how TDD has improved their work compared to what they used to produce before.”
You mean Jeffries (as a TDD guru) was even worse before using TDD? Boggles the mind! We don’t want to hear his advice. Thanks! ;-)
This is my last submission here. When you have a world beating codebase produced with TDD. let us know.
Till then, Au Revoir. ( meanwhile, please, more code, less preaching ;-))
> You still need to know design principles,
My experience is that mockist-style TDD (that is interaction-based TDD) put in use a set of “generative rules” with the consequence of writing code that adhere to the SOLID principles when doing mockist-style TDD . Here in short the explanation follow:
- When doing mockist-style TDD and the code violate the SRP and the ISP you end up with a test that stub half on an offending interface/class members while set expectations on the other class/interface half.
This smell suggest to split the class/interface and this make the code adhere to the SRP and ISP.
- When doing mockist-style TDD, while making a class testable all the dependencies are decoupled from the class so all the dependencies can be replaced with a stub or with a mock. this make the class code adhere to the OCP and the DIP.
- Mockist-style TDD promote the use of composition over inheritance and this somehow help to avoid violations to the LSP, anyway this is the only one of the solid principle that get a little help from TDD so it is necessary to know it in order to not violate it.
Esko,
I think you are vastly overestimating the complexity of understanding TDD.
Here it is:
- Write a test that doesn’t compile (and doesn’t succeed, obviously)
- Make it compile (by writing the production code it’s supposed to test)
- Make it pass
- Repeat
That’s it. That’s TDD.
Take a few hours to reshape your thinking in these terms and try to apply it to your work.
Saying that you need months before really understanding TDD and that you’re not allowed to criticize until you’ve spent at least that much using it is a cheap way to deflect criticism.
Go can be described with 10 simple rules. Can you say that you understand Go, after you know its rules?
Mathematical domains can be derived from a small set of axioms. Can you say that you understand mathematics, after you know the axioms?
Can you say that you understand programming, after you know the syntax of a programming language?
TDD is the same. It has a simple set of rules, but their implications are far-reaching.
+1 for esko. I’m never saying that TDD is superior. I think it’s a matter of taste. But if one wants to say it’s inferior, then he needs to prove he practiced and understood. @Cedric: forgetting the cleaning/redactoring part in TDD cycles is not what I would call a good understanding.
@Esko,
You’re making a mountain out of an ant-hill.
I remember when Krispy Kreme was a huge thing. Everyone loves it and people lined up for hours just to buy some. One year down the track, people just woke up and realized: hey it’s just doughnuts wrapped in a whole lot of bullshit marketting.
See? Anyone can draw parrallels.
“Go can be described with 10 simple rules. Can you say that you understand Go, after you know its rules?
TDD is the same. It has a simple set of rules, but their implications are far-reaching.”
So you claim. Where is the evidence?
It is easy to demonstrate the complexity and elegance of Go by showing a sample game by GrandMasters, with commentary if required. Many aspects of GO (e.g the branching factor) are mathematically provable. There is no debate about whether Go is a deep and subtle game. The Go Grandmasters aren’t propagandists. They play Go – they don’t sell “Go playing methodogies”. They don’t insult other players or players of other games.
TDD “grand masters” have produced nothing impressive in terms of code (unless you want to count the Sudoku example . ;-) ). Bowling “katas” aren’t enough. Sorry. Bob Martin has a sorry little itsy bitsy testing framework and Ron Jeffries has his Sudoku.
So Go is the wrong analogy. Try again.
If TDD is so subtly grand, show us some great code that resulted from TDD. We await with bated breath.
TDD zealots (who are mostly process consultants btw and have a vested economic interest in blowing up the merits and hiding the demerits of TDD) talk up a storm about the limitless possibilities of their favorite technique. Ask for code comparable (leave alone superior) to the best non TDD’d code and there is a deafening silence.
Broken by more talk (no code), justifications (no code), accusations that others haven’t understood (yet, no code) whining (but no code), flaky metaphors(no code).
First show code. You are talking to developers here. Show us works of programming magnificence designed and developed with TDD.
Sound of crickets ? That’s what I thought.
All the justifications and whining and metaphors (the game of Go this time) don’t help unless you back your favorite “design technique” with brilliant code that resulted from its use and is obviously superior to teh alternatives.
Where are all these brilliant TDD’d programs which are so much better than the best non TDD’s programs?
There aren’t any? We thought as much.
Now, stop whining and go build something to validate your claims. Then preach.
Interesting that MS Research has just completed a research project on TDD and does provide some evidence, per a number of commenters’ requests. They conclude that while it can take 15-25% longer to complete a project (although this could be attributed to the fact that their teams may not have been as familiar with TDD as a more experienced team), but that code quality increased 60-90%. Considering the lifetime of a typical software application, this seems like a clear justification in favor of TDD. See the report at http://research.microsoft.com/en-us/news/features/nagappan-100609.aspx
: I hear you whine and preach – loud and clear.
Even if someone were to provide you with all you demand, you would find a reason why this is not enough and doesn’t “prove” that TDD works. Frankly I’d rather try to argue with a wall than with you.
You’re visibly feeling well attacking others from your imaginary position of superiority. Sign of a balanced personality I guess…
Go your way. Have a life. Your nickname is revealing I suppose. Be someone and take it easy.
“If it works for you…” Man, I’m a bit shocked threads like this take off like wild-fires. I guess it proves holy wars in software development are still rife in the world. :)
@Cedric: You’re missing one important aspect of TDD: - Write a test that doesn’t compile (and doesn’t succeed, obviously) - Make it compile (by writing the production code it’s supposed to test) - Make it pass + Re-factor and make it clean. - Repeat
IMO that point is one of the most important drivers for TDD, or simply test-focused development, whether you test first, or test after. Basing coding practices and design practices around building test-able and tested code, re-factoring the code as you go becomes a lot simpler and safer.
By the spirit of the law I’m TDD, but by the letter of the law I’m not. I am test-driven in that when I set out to write software, test-ability is never far from my mind and an important factor to how I structure code. However, I typically build the tests in during developing that functionality, my tests go in before I consider a feature “complete” which is always before re-factoring functionality. I call it Yellow-Green-Refactor. (Flashing yellow is probably the best description…)
@ErikFranzK: as it happens too often, you’re defending TDD from a claim nobody made and you’re making personal attacks (just like the Church of Scientology). There’s quite a difference between saying TDD works (which I assume we all agree) and saying that anyone who doesn’t do TDD is an unprofessional stone age programmer (which is just plain, unjustified name calling).
@ErikFranzK: You’re visibly feeling well attacking others from your imaginary position of superiority. Sign of a balanced personality I guess.
Taking this statement of yours by itself, it’s at least as applicable to Uncle Bob himself! Interesting, no?
@Filipe: I’m not defending TDD – or do you see anything indicating it in my words?
My opinion about TDD doesn’t matter here. noone makes it quite clear that no arguments anyone could provide will change his opinion about TDD and people who think that TDD works. That is what I’m attacking.
I don’t attack the person (I don’t know him/her), I attack the attitude and the tone – which I simply consider childish.
Just to make a point clear: I definitely do not share the opinion that someone who does not practice TDD is less worth as a developer. I’m actually interested to know his/her reasons not to: they could be quite good. I am also interested to hear the positive feedback (not the preaching) from someone being successful with TDD.
Last but not least: keep your comparison with the Church of Scientology for yourself. Demonizing your imaginary “opponent” just makes you worse than anything what you think you’re denouncing.
Take it easy: I don’t think there is a TDD conspiracy (maybe a little hype?), and if TDD doesn’t work it will die :-)
@noone: you/we end up mirroring the image we have of our “opponent” – whether this image represents the truth or not.
I was somehow expecting this response of yours – so my picture of you is probably not totally false.
But I think you are a bit wrong about me: tell me calmly (without bold characters etc.) what your problem with TDD actually is – and I will hear you. Don’t shout for evidence, when you’re not interested in them – and I’ll be more willing to listen to you. I’m interested to learn about your real motives – I don’t care about your diatribes. And maybe you could tell why you think I feel superior ;-)
More concerning the position of superiority: well, Bob Martin has a long history in the field of software development. He has written quite many books stating his views (with lots of code BTW). This certainly doesn’t mean he is always right or that his views on TDD are to be accepted without questions. But: what is the source of your authority? What are your achievements?
BTW: the sentences above in no way imply in my eyes that authority should not be questioned or that your achievements cannot be as valuable as those of Bob Martin. But I’m certainly wondering why someone hides behind the nickname noone.none@org – if “nomen est omen” that’s not a good sign ;) – and why he gets so agitated about such an minor issue as TDD ;)
@ErikFranzK: I’m sorry I mistook you for one of the people who blindly agree with Bob Martin on the professionalism/stone age bit. That is pure dogmatism IMO and it hits a nerve.
@DDickinson
I’d be willing to bet that the VS team that tried TDD and took ‘25%-20%’ longer to create their code that had 90% fewer bugs was at release quality a LOT faster than the other team that didn’t use TDD.
I’d like to second , that having had the experience of Agile, TDD, etc., it seems pretty clear by now that’s purely a fad driven by “consultants” and “coaches” who’s highest level of sophistication is writing Velocity templates.
If you think that makes you a better programmer, prove it with great code, not stupid blog posts.
In general I think the best way to tackle complex problems is to break them down into simpler problems, and to find and encapsulate what varies. TDD as a design practice encourages these habits, and in very complex cases forces them. Once a problem is sufficiently broken down, it is much easier to design. This also makes it easier to use TDD practices.
The ability to mercilessly re-factor is possible because of these design benefits along with the test coverage. When not using TDD, I am more likely to write code that is difficult to test.
Also the fact that the google searches have turned up a lot of testing tools is likely due to the fact that a search term used is “test” or “TDD” and therefore results return mostly related products.
NASA has used TDD since the 1960’s and of course the need for quality there is extremely high. IBM’s JavaPOS (point of sale) is a highly successful project using TDD practices.
@tune5ths You’re confusing “automated testing” and TDD.
One is useful and has been done for ages, the other is consultantware.
Esko,
Oops… Sorry Esko, on my last post your name got linked to a wrong ref ( a copy past mistake)
“well, Bob Martin has a long history in the field of software development. He has written quite many books stating his views (with lots of code BTW)”
Not true. Worked with 2 book authors before who are supposed to be “EXPERTS” but were very bad when it comes to technical matters. Oh yes they are also authors stating their views and with lots of code and also has a long history in the field of software development.
@BewareOfAuthors Have you read Bob Martin’s books (and some of his articles in C++ Report), or are you just trolling?
I know it doesn’t prove he’s right in any way (and wrote it) – but I’d like to know from which high horse you’re speaking….
PTO generators
Thanks for sharing this great article! That is very interesting Smile I love reading and I am always searching for informative information like this.
buy art online—New Art Originals.com Online Gallery
Green Printing
All solutions are created twice. Personally, Whenever I have a problem to solve, I first visualize the solution as an image, a sketch then I put the actual resolution in place using my IDE.
it is my pleasure to read it
This is a great and very valuable information about Is TDD a replacement for architecture. Thank you very much for sharing this information with us.
Thanks.
Great efforts for generator.
This is one of the beautiful article i have seen and its interesting too; thanks.
REally great article !
Like your writing method which is unique and productive. Keep it up.
Great efforts for generator.
Really great article !
Yes, this is lovely information ERP Software
It’s also trying to capture stages that are correct but suboptimal, or temporary prototypes, and that will be improved very soon.
I think that resisting the urge to write tests until you have code that looks in decent shape is common sense.
“If you need to change the tests because of changes to the signatures and APIs, then your tests are too tightly coupled with the production code. Such tests are bad.” cheap VPS That’s circular reasoning. Eventually, your tests invoke a method in your production code, and if that method’s signature changes (which is pretty common in the early stages of solving a problem), you will have to update your tests. That’s needless churn.
write tests until you have code
It’s funny how I find junior to intermediate developers talking a storm about TDD and its glory. I’m not saying TDD is a bad thing. I like that fact that it CAN (not will) promote decoupling of code and CAN (not will) provide a better more extensible architecture in the long run, a very good thing. In essence, TDD can server to be a testing guideline promoting good habits of what your application must do to meet most functional tests based on requirements. I’m all for it if you need this to create software using general good best practices and design patterns.
Now, I’ve been architect for well over 18 years with a total 25 years in software development industry. I will admit, I have used TDD once to see if it will benefit me. Well, I had some benefits to a point. But because I have some many years of write software to be extensible, reusable and loosely coupled using good design patterns as a general habit, I found TDD to be a waste of my time – honestly. As for what TDD is supposed to promote, I already do naturally without the need of a test guideline – TDD
Maybe I’m an old fart, but I do allow my team to use TDD as they see fit. With some developers I found it benefitted them and because of this, I’m all for it. But I’m not going to shove it down ones throat.
Just what I was looking for and quite thorough as well. Thanks for posting this, I saw a couple other similar posts but yours was the best so far. I hope it stays updated, take care.
so good post i like it china nfl jerseys
When you play WOW, for you can get WOW Gold and high experience volumes. Rare mobs are more difficult to hunt and the World of Warcraft Gold you can obtain is also higher. So you can get your WOW Money easier and easier in our site.
to make that have nothing to do with tests.
news , Style and info This is one of the beautiful article i have seen and its interesting too; thanks.
I travel a lot and I get to visit a lot of different companies. No matter which industry a company is in or which programming language a team is using, there is one commonality in all of the code that I see – classes are just too damn big and methods are just too damn long. (What did you think I was talking about?)
think you ! http://www.yourvoguemall.com
Maybe I’m an old fart, but I do allow my team to use TDD as they see fit. With some developers I found it benefited them and because of this, I’m all for it. But I’m not going to shove it down ones throat. Now, I’ve been architect for well over 18 years with a total 25 years in software development industry. I will admit, I have used TDD once to see if it will benefit me. Well, I had some benefits to a point. But because I have some many years of write software to be extensible, reusable and loosely coupled using good design patterns as a general habit, I found TDD to be a waste of my time – honestly. As for what TDD is supposed to promote, I already do naturally without the need of a test guideline – TDD
This post was extremely useful. I tended not to follow the controversy, and was simply looking for a good understanding of what TDD really was. While it certainly wasn’t the end-all be-all explanation, it hit the mark as a good high-level introduction.
Great article, thank you very much
Thanks for such a wonderful information.
Very pleased that the article is what I want! Thank you
best Video Converter for iPad for Converting Video for iPad with high quality. Guide on How to Convert Videos to iPad and Convert Movies to iPad.
What a fantastic post on TDD Triage.
news , Style and info This is one of the beautiful article i have seen and its interesting too; thanks.
so I’m wondering if my mapping of functions to data structures is odd.
Ek gelir ?mkanlar?
Risk almadan Sermayesiz Evinizden yönetebilece?iniz Kendi i?inizin sahibi olmak istermisiniz ?
Thank you for this nice post
my blog: alpha male | how to run faster
Thanks for sharing such a useful stuff!
know you could have received a fan suitable the next who valuations what you could have got
to say along with the way you’ve got introduced by yourself. Very good on you!
Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds, Intertech is also very professional for making flip top Cap Molds in the world.
Your article is really great and I truly enjoyed reading it, keep walking.
Good article! Thank you so much for sharing this post. Your views truly open my mind.
TDD is certainly no replacement for design.
Nice post though. I certainly like your blog http://blog.objectmentor.com/articles/
Even you can visit my blog here : Bed bugs how to get rid of them
Regards, JVW
The story comes with a young man.He comes from a small town.chat
Very interesting. I do believe this story is a bit one-sided though. I just can’t help thinking that there are better options available now… Dev has changed drastically in the last couple of years.
This is really interesting
GHD australia have fairly very rated for rather a few of elements just like pattern durability and ease of use.
This is great! Love it. Thanks for sharing!
wanted to get more lv backpack
very interesting post. love it!
Great article. Your articles are a pleasure to read and very helpfull indeed. Thank you
We are the professional coats manufacturer, coats supplier, coats factory, custom coats.
I like what you’ve done here, I’ll be sure to bookmark
know you could have received a fan suitable the next who valuations what you could have got to say along with the way you’ve got < a href=”http://www.rictechs.com/”>introduced by yourself. Very good on you!
You do not need any oily residue there, since this is the spot where you will be applying your lace.. You can also use skin prep and let dry before applying glue.
your blog is so good
def bookmarking thank you
This was a great post. I think that I will be able to use this in getting a more widespread focus on drug addiction and rehab. Thank you for sharing this information.
This is a good post. Thank you so much. Keep up the good works. Social Network
cadran noir et solide en acier inoxydable avec un bracelet noir brillant, réplique montre Omega peut se produire danspar rapport à ceux bijoux finement con?u montres a publié un éloge et le doute Gossip sur les bijoux et les montres replique montres de luxe la mode des plus classiques, voir le CD en noir réplique montre rolex pour montrer la force et de caractère, partout dans le vague replique de montre noire en conformité avec l’horloge ma?tre, transformée en aval montres repliques de la classique pour hommes. n’importe.Selon vague “Black à l’alambic” série de montres montres de luxe suisses à l’aide mouvement à quartz et un rendement supérieur. Caisse noire,
A Seobaglyak éjszakai életmódjukból kifolyólag nappal elég ritkán láthatóak. Ha ki is mozdulnak a rejtekhelyükr?l, akkor álcázóképessségüknek köszönhet?en teljesen beleolvadnak a környezetükbe. Ilyenkor nyugodtak, a felt?nést kerülik, nappal akár még csoportokba is ver?dhetnek, és az embereket sem kerülik.
This is interesting to note, writing and very useful info.
61% OFF cheap beachbody p90x cheap on sale p90x videos offer high quality p90x for sale at cheap price,all p90x dvds cheap are Free Shipping!No tax! http://www.p90xdvdforsale.com/
finally i found this complete article about TDD triage.. very thank you..
Finally i found this complete article about TDD Triage.. very thank you..
With TDD all code is written in small increments, which are basically the same as many minor changes/additions to the requirements. So when some code has been written with TDD, it has already been proved to be easy to change and maintainable (or if the developer is not skilled enough designer to write as decoupled code as is required by TDD, then the project did grind to a halt already long time ago). So when the requirements change, it will be easier to implement those changes, than with code which has been written in one go, without the continuous battering of changes that TDD’d code has gone through and survived.
i’m still confuse about this :(
Thanks so much for the information about TDD Triage..
thanks sir, but i often found many debug :( any body can help me
I have really enjoyed to read this blog. Thanks for writing this article and giving us the knowledge. Hope to see some more of these.
wow.. so long blogs but they so informative blogs i like it,, thanks for sharing.
Great post on TDD architecture!
This is excellent reading on controversy that TDD brought upon us. However expectations are high and so demand it seems. But not all will adopt it immediately, as there have to be some time for people to take good look at it and decide if they want to leave their current workflow, or go with TDD. My 2 cents tho…
This post is great about TDD a replacement for architecture.That is helpful for anyone who is interested about this.So i would like to see more details on this topic
This post is great about TDD a replacement for architecture.That is helpful for anyone who is interested about this.So i would like to see more details on this topic
They already are!
“well, Bob Martin has a long history in the field of software development. He has written quite many books stating his views (with lots of code BTW)”
I have really enjoyed to read this blog. Thanks for writing this article and giving us the knowledge. Hope to see some more of these.
What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say. Im sure youll reach so many people with what youve got to say.
I wait behind the visit … Techno News
What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say. Im sure youll reach so many people with what youve got to say.
I wait behind the visit … Techno News
I’m really interested to see how TDD can be applied in the future. I know it’s kind of been swirling on the side and used by those who are dedicated to it… it kind of reminds me of what linux is to operating systems.
Thanks for the write up. Good material here.
This post is great about TDD a replacement for architecture.That is helpful for anyone who is interested about this.So i would like to see more details on this topic
Thanks for letting me discuss here.Really exciting and informative blog.Learn and enjoyed the staying very much.
Great, I get improved with this.
5788
Great Article, I really enjoyed reading it.
Nintendo DS & Lite consoles are using next generation flash card called as cheap r4 ds in the market. R4 DS, R4DS, The cheap r4 ds is the most famous nds card in the world today. R4, R4i-SDHC, Users should be tension free as cheap r4 ds is giving complete solution without any help of additional component in the market. r4i, buy r4, ds r4, Acekard 2i, Consumers should be aware with the features of cheap r4 ds now. The users of cheap r4 ds can avail best performances in the market. R4 card, r4i gold, Various activities like watching movies, playing MP3’s and storing hundreds of homebrew applications are handled by cheap r4 ds in the market. Under Creative Commons License: Attribution No Derivatives R4 nintendo, R4i, R4 Card, The cheap r4 ds is well known product of Nintendo DS flash card. Acekard 2i, Acekard2i, Dsi R4, The cheap r4 ds plays major role in the small and powerful nds. Even the cheap r4 ds carries the same apperance as the original nds cart in the market. R4 Dsi, R4 SDHC, Now most of the productions of cheap Nintendo R4 are done by branded companies in the world ???? .
This is excellent post. Its having good description regarding this topic.It is informative and helpful.I have known many information from this. Thanks for shearing.
complete websites for sale
It is nice to find a site about my interest. My first visit to your site is been a big help. Thank you for the efforts you been putting on making your site such an interesting and informative place to browse through. I’ll be visiting your site again to gather some more valuable information. You truly did a good job.
I am very enjoyed for this blog. Its an informative topic. It help me very much to solve some problems. Its opportunity are so fantastic and working style so speedy. I think it may be help all of you. Thanks a lot for enjoying this beauty blog with me. I am appreciating it very much! Looking forward to another great blog. Good luck to the author! all the best!
hmm ,i’m not sure if this is what i’m looking for but anyway this is interresting and could be useful some day,thanks for taking time to write such cool stuff
Thanks for letting me discuss here.Really exciting and informative blog.Learn and enjoyed the staying very much.
This is excellent post. I am very enjoyed for this blog,You truly did a good job.
This is one of the most incredible blogs Ive examine inside a extremely prolonged time. The level of details in right here is stunning, like you practically wrote the book around the topic. Your website is wonderful for any person who would like to fully grasp this topic a lot more. Wonderful things; please preserve it up!
Good Luck!It is nice of you to post it. Discount fashion women Supra Lowcut shoes from China for wholesale free shipping,more order,more discount
Those are amazing. Wonderful collection. This is real design. Love it man. Thank you so much for shearing.
asd asd+f6s86s6ss
asdf+098+9 fhf44ffff
as asd9+f8sa798+8s8s8sss
Wow doesn’t anyone read the entire post before they post comments anymore? Some of the comments on this page are just really weird..
Oh my there are a lot of comments on this page! I think you should consider getting some sort of anti-spam solution or at least clean up a bit.. Maybe you could turn on comment moderation, though I guess that would be a ton of work so might not be viable.
??? ????1856??????????? ????????1835??????????? 1924??” ??? ????”??????????????????????????? ??????????? ??? ? ( Burberry) ??? ??????1856????????? ??? ???????????? ??? ??????????????????? ???????????? ? ??????????? ??? ???.
?? ?? ??????????????? ?? ?????????? ?? ?1968??????? ?? ???????????? ????????? ?? ???????? ?? ??????? ?? ??????? ?? ???????? ?????? ?????5 ?????????TOMS ??????????? ????????????????????????? ????????????Supra ????????? ?????????????? ??????
??? ????1856??????????? ????????1835??????????? 1924??” ??? ????”??????????????????????????? ??????????? ??? ? ( Burberry) ??? ??????1856????????? ??? ???????????? ??? ??????????????????? ???????????? ? ??????????? ??? ???.
?? ?? ??????????????? ?? ?????????? ?? ?1968??????? ?? ???????????? ????????? ?? ???????? ?? ??????? ?? ??????? ?? ???????? ?????? ?????5 ?????????TOMS ??????????? ????????????????????????? ????????????Supra ????????? ?????????????? ??????
??? ????1856??????????? ????????1835??????????? 1924??” ??? ????”??????????????????????????? ??????????? ??? ? ( Burberry) ??? ??????1856????????? ??? ???????????? ??? ??????????????????? ???????????? ? ??????????? ??? ???.
?? ?? ??????????????? ?? ?????????? ?? ?1968??????? ?? ???????????? ????????? ?? ???????? ?? ??????? ?? ??????? ?? ???????? ?????? ?????5 ?????????TOMS ??????????? ????????????????????????? ????????????Supra ????????? ?????????????? ??????
??? ????1856??????????? ????????1835??????????? 1924??” ??? ????”??????????????????????????? ??????????? ??? ? ( Burberry) ??? ??????1856????????? ??? ???????????? ??? ??????????????????? ???????????? ? ??????????? ??? ???.
?? ?? ??????????????? ?? ?????????? ?? ?1968??????? ?? ???????????? ????????? ?? ???????? ?? ??????? ?? ??????? ?? ???????? ?????? ?????5 ?????????TOMS ??????????? ????????????????????????? ????????????Supra ????????? ?????????????? ??????
Good artical,I learn something!
Australia Beats By Dre Studio dr dre beats headphones beats studio beats pro beats solo hd pro headphones music Official store Monster Beats By Dre Pro
okeeeeeeee
No, of course not. The notion that you can generate a viable architecture by starting with a blank screen and then writing one test case after the other is sheer folderol. There are decisions that you need to make that have nothing to do with tests.
Of course many of these decisions can, and should, be deferred for as long as possible. For example, the database schema is something that can likely wait for quite a long time. The decision to use Spring, JSF, Hibernate, JPA, etc. can also likely wait. The beauty of business rules is that they can, and should, be implemented independently of database and GUI models.
Ramen Noodle Recipes Thank you for putting such a wonderful effort on this post.. I really enjoyed reading about.
[http://www.ramennoodlerecipess.comRamen Noodle Recipes] this is great article, i very helpfull with this articles and to admin thanks
I had really like it very much for using the nice technology in this blog. This website design is very great for the way of presentation is very great. I am very much interesting info in this blog
Hi Bob You are making some really good points here. I totally agree with most. keep up the good work. Amit
Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds,
Intertech is also very professional for making flip top Cap Molds in the world. Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Molds for their worldwide customers.
With more than 20 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.
For the overseas market, we work very closely with local representatives in order to take care of the technical communication and after-sales service to our customers. We also participate in the EUROMOLD & FAKUMA exhibitions and meet our customers every year in Europe. By concentrating on mold “niche markets”, we play a very useful mold maker role from the Far East whenever customers want to develop their new projects. We provide services from A to Z to our customers on a very economic cost and effect basis.
Intertech Machinery Inc.
With more than 25 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.
Main Products:
Injection Mold, Silicone Molding, Rubber Mold, Silicone molding, PC High-Gloss Plastic Mold, Die Casting Mold, Silicone Mold, Silicone Rubber Mold, Liquid Silicone Rubber , Cosmetic Packaging Mold, Medical Products Mold, Engineering Plastic Molds, Home Appliances Mold, etc…