23
votes

I've been working in the enterprise space for the past 4½ years and have noticed that generally speaking, enterprises are not conducive environments for the test-first style of development. Projects are usually fixed-cost, fixed-timeline and waterfall style. Any unit testing, if done at all, usually comes after development in the QA phase and done by another team.

Prior to working for an enterprise, I consulted for many small to medium sized companies, and none of them were willing to pay for a test-first style of development project. They usually wanted development started immediately, or after a short design stint: i.e., something more akin to Agile, though some clients wanted everything mapped out similar to waterfall.

With what types of shops, companies, and clients does test-driven development work best? What types of projects tend to be conducive to TDD?

6
  • 5
    "none of them were willing to pay for a test-first style of development project" - say what? The total time it takes to implement a method in a class, in my experience, is a lot less if you write the "test" first. These days though, you won't find it referred to as test-first development or test-driven development, since that's a rather antequated way of looking at it. You can think of unit-tests in TDD as programmatic descriptions of your code, which are then fulfilled during the "fixing of the test". Surely it's better to have some notion of what you want to do before doing it? :)
    – bzlm
    Commented Oct 19, 2010 at 19:54
  • 2
    @bzlm two situations where "paying for" test first is valid. Where the users are expecting many prototypes with massive rework at every step because they aren't certain what the best outcome is and where the expense of getting the developers to simulate the external behaviors correctly enough to have valid tests is prohibitive. Neither is necessarily a nice place to be, but both can be common in enterprise.
    – Bill
    Commented Oct 19, 2010 at 22:38
  • 6
    Two flawed assumptions: first, that TDD is more expensive. Agile is less expensive than waterfall because you don't spend time building the wrong thing and TDD is less expensive than test last because you don't spend time building things that don't work. Second, that TDD doesn't mean you can "start development immediately". With TDD, you do start developing immediately. TDD doesn't mean that you write all your tests first. It means you write a single test first. No one wants to do TDD the way you seem to understand it, including TDD users. Commented Jun 9, 2011 at 16:40
  • @Rein: amen, brother!!
    – IAbstract
    Commented Aug 20, 2011 at 12:25
  • Doesn't this question encourage list style answers with no real criteria as to when it's been answered "correctly"? Aren't these kinds of questions deemed unfit for StackExchange's Q&A format because we end up with 16+ answers, each of which addresses the question however none of which meet the non-existant exit criterea for "correct"? Commented May 10, 2013 at 5:05

16 Answers 16

33
votes

Every line of code I write is using test driven development. If management isn't on board with writing tests first then I don't tell management about it. I feel that strongly that test driven development is a better process.

10
  • 19
    I upvoted you not specifically because you do TDD, but because you do what you think is right without asking for permission. That is what professionals do. Commented Sep 10, 2010 at 21:01
  • 24
    @Sergio - that's a horrible definition of what a professional does. Thinking that something is right does not necessarily make it so, in particular in engineering matters. There is a time and place to sometimes break the rules to get something done, but to say that the mark of the professional is to do what one thinks is right without asking permission (specially when you are getting paid to do a particular process), that's a gross oversimplification of a complex subject. Commented Oct 15, 2010 at 11:49
  • 6
    Don't take what I said as the definition of what a professional is. And don't expect a two sentence comment to be an in depth treatment of a complex subject. Sorry. Commented Oct 15, 2010 at 20:24
  • 22
    How about this: "a professional does the right thing without having to be told to do it". Better? That was what I meant. Commented Oct 15, 2010 at 20:30
  • 3
    @CraigTp - There is a whole chapter in the book Peopleware: Productive Projects and Teams that rant against the "Methodology" saying that it kills the motivation and extinguish the inner flame one can have if the "Methodology" is too tight because it removes the liberty of individual supposing that they will make systematically bad choices. A good working environment is one where the individual can make decision that he judge are the best for the "greater good", if it fail then adjust, but otherwise, let the individual be the center of decision, not the "Methodology"
    – JF Dion
    Commented Jun 9, 2011 at 13:51
17
votes

My boss fed me a good one today on this, I think I'm going to steal it like he was stealing it from someone else.

"Would you expect a carpenter to measure the board before he cuts it?"

I took wood shop class in high school and worked construction through school. Our mantra was always "measure twice, cut once" which got followed up by the sarcastic "I cut it and cut it again and it was still too short!"

2
  • I can't say that I agree with that analogy. It doesn't really come close to the complexities in development. But then again, I don't fully believe in TDD.
    – xil3
    Commented Apr 29, 2013 at 17:06
  • @xil3 Yes, the analogy is not good. It would be more "measuring approximately, not checking after, and then cutting". But the answer is still very good Commented May 10, 2013 at 10:20
12
votes

If you test after, you create rework as the code you will have written will be difficult to test. When you test first, or even test-a-little-bit-in-the-middle-but-before-you-commit the software you create will be easier to test. An enterprise that creates unit tests after production code is written to satisfy a check list is wasting effort.

Integration with existing hard to test software will also create additional effort, as you will need to create test seams to be able to control the dependencies your shiny new test driven code consumes. In some cases, such as with frameworks that make heavy use of global state and god objects this can be very difficult to achieve. The perceived difficulty of test driven development is often down to a combination of inexperience with writing good tests and attempting to test tightly coupled code.

You can test drive code even in a waterfall project, it is an engineering discipline not a project management technique.

I'm not a TDD fanatic by any means, but it teaches you a lot about software design.

2
  • 1
    "If you test after, you create rework as the code you will have written will be difficult to test. " That's not actually true. It'll be only be true if you don't make loose coupled code. Are you sure you can't write testable code without testing it first? Commented Aug 20, 2011 at 21:04
  • @devoured elysium: I agree: writing tests first is not the only way to write testable code.
    – Giorgio
    Commented May 10, 2013 at 10:45
6
votes

Bear with me, as this will have a distinctively .Net flavour :p

With regard to types of projects that are amenable to the test-first approach, some things I'd look out for:

  • are you dealing with an existing code base? It's often prohibitively expensive to retrofit that a test suite in. Get an idea of how much inherited technical debt is there
  • certain platforms and frameworks are inherently test-unfriendly. Recent experience that is seared into my mind - SharePoint, for example is very hard (but not impossible) to TDD. For stuff like this, you may have to resort to a commercial isolator product like TypeMock can help.
  • certain implementation approaches lend themselves better to TDD than others. For example, ASP.Net with code-behinds - not so testable. ASP.Net MVC - testable. Silverlight with code-behinds - not so testable. Silverlight with MVVM - testable.

Ultimately, while "the organization" can do a lot to support the move to test-first, the key shift that needs to happen is in the developers' minds. I've given up on the "thou shalt write thine tests first" approach and instead look for teachable moments.

+1 on mpenrow's comment about not telling mgmt if they have an issue with it :p

1
  • 1
    Well said. A big problem comes about when there is a huge amount of technical debt because at that point you cannot even start to implement testing, and you cannot rewrite the application to eliminate the technical debt, and sometimes you cannot even refactor the technical debt away because you have so many additional features being assigned to complete. Commented Jun 9, 2011 at 16:07
6
votes

Your situation won't change quickly, and the key to getting it through is to make it part of your personal discipline, and to be good at it, before trying to push it on others. If you can be the example of it working then your managers should see objective benefits.

You can also make good business cases:

  • TDD can be simply summarized as "spec which the system can automatically verify itself against". It's not programming differently, it's not building a different product.

  • Unit testing is really just a form of automated-testing; which is just letting the computer do for itself what the company is likely paying meat-space engineers to do manually. Automated tests run faster, more consistently, and--when well written--provide fast, concise and accurate feedback and descriptions and direction for the issue

  • TDD, when being done by someone who knows what they're doing, produces results just as fast as code-first. There will be a learning/training curve (and, if your engineers are from the short-end of the talent pool then this may entirely kill your chances of pushing TDD--in this case the best you can do is to continue to champion it and make management question them rather than TDD)

  • TDD is very much about thinking through the task at hand before starting it. It's along the lines of "measure twice, cut once"--the extra measurment adds a marginal amount of time to the task, but avoids throwing away your most precious resource--dev hours).

...and just remember; the most important thing you can do is to lead by example. If you're rough in TDD, invest some extra hours in becomming better. Once you're proficient, just start doing it at work (would your managers really complain that you write tests?). Fight one battle at a time and make steps towards it--going for the whole shebang likely will result in failure and the blame will fall on you if you pushed hard for it.

2
votes

I do. Its my preferred way of development, and I work for a large finance company who are happy for me to work in the way I see fit so long as I meet deadlines and produce quality code. Done correctly, test first development need not take longer than test after development and let's not forget the other payoff's of test first development of less defects out of system testing later.

2
votes

The key to doing TDD is to just do it as part of writing your code, and if necessary, you do not tell anyone you're doing it. It's not necessary to explain everything you're doing. Your end result is working code.

If you explain "I am writing tests," then The Powers That Be can say "Oh, we can eliminate that!" But if you tell no one, then you still have the tests as residue of the coding process.

Programming is more than typing in working statements into an editor. If people can't handle that, then shield them from this truth until they are ready to handle it. "Ready to handle it" in this case means when you have a completed project or two, done on time with solid, reliable code, and oh yeah, look, you have unit tests for it, too.

1
  • Suppose that you are implemented a certain module and, after writing unit tests and implementing the corresponding classes and methods, you see that your design is flawed and you must throw away a few classes (and the corresponding unit tests)? Wouldn't it save time to start writing the unit tests when the design has stabilized a bit, i.e. when you have implemented enough classes for that module that the overall structure has become clear enough?
    – Giorgio
    Commented May 10, 2013 at 10:54
2
votes

Sad to say, I haven't gotten a chance to use it in the truly classic test-first sense myself, so I can't say "me! me! I do it!". I'm assuming that the question is asking "what industries/companies use TDD across the board" rather than "can anyone sneak TDD into their daily lives?". I agree that an individual developer can totally do TDD without forcing the entire group to do it, I just don't think that was the point of the question.

My impression from listening around the industry is that you are more likely to see TDD across most development groups in a company in situations where:

  • There is no large existing code base prior to the inception of TDD

  • The company is not enormous and therefore doesn't have lots of the "we've always done it the other way" pushback.

  • The company doesn't have an enormous buy in to formalized process. That's not to say that you couldn't implement TDD in, for example, a CMMI certified company - but if you had a not-TDD process, getting all the processes that you monitor with CMMI updated can be a major investment.

  • Tests can be scripted - this is most complex code bases, since even if you can't easily script the closest layer to the user, you can script some of the internals. But I see situations with well-developed options for test automation as the sweetest spots for TDD, since it's based on rerunning and not-breaking a whole battery of tests where you need feedback on testing very quickly. My thought is that a standalone web app is a good TDD target, a system with major COTS integration or input that isn't GUI based may be tricky.

  • Systems in a non-prototyped state. Ideally the next big version after the prototype - where the proof of concept is finished and the project is funded, but everyone knows that the next attempt has to jump in quality.

  • Stakeholders that are invested in the process.

1
  • 2
    +1 for the first point alone; to properly do TDD you cannot have a large, invested codebase done without TDD (or testing in general). If you do, you will likely never be able to add it since you would have to either A) Retrofit the entire application to support testing, since more than likely it wasn't written with proper abstractions to unit test, or B) Rewrite the entire thing from scratch and use TDD from the start. Commented Jun 9, 2011 at 16:09
2
votes

I've tried where possible - but I think it's really down to the corporate environment in which you find yourself. I worked in the games industry for many years (as an artist btw), and there was no concept of TDD - just a brute force QA approach. I moved into web development, and have yet to work in an agency with any formal recognition (or knowledge of...) unit testing / TDD. The same goes for most of my peers in the industry, who work in a broad range of disciplines.

In a sales focussed agency, TDD offers very little short term ROI to the customer, and so it's hard to sell to the line managers when scoping a project. The larger a project gets, however, the more convincing it becomes.

Given that books like Death March point to a prevalent phenomenon, i.e. an industry plagued by "crunch" and "milestone" driven development - I wager that TDD is probably rare outside well funded startups or monolithic enterprise shops. It's not that the people there don't believe in the value of TDD - but it's too abstract to sell to their customers.

2
votes

I'm trying to get into TDD myself. I think as long as you follow routes you allready know (the day to day work) it's rather simple. But I just can't wrap my head around tests for the UI parts or when you have to come up with a new solution to some problem you have not encountered before. Or using a framework you don't know.

So I guess you have to do some kind of LearningTests, seperate proof-of-concepts and rewriting it afterwards, etc. or am I wrong?

And (I know it's an old one but I just seen no good answer yet): how do you code algorithms using TDD (when the results might be to complex to really "Assert" on with ease)?

I can really see the positive sides of TDD and im on the boat but it's very hard for beginners when the code you write takes you allmost double the time (and you've got peers that don't see the pros at all and mock you with RAD)

1
vote

I tried a few times and it worked great. Unfortunately most of the time if I can manually test my app I postpone unit tests until I feel too bored to implement something else or there is a bug I cannot easily fix.

1
  • The advantage comes later, because you are basically documenting behaviour as code. Any code change must still pass the tests or behaviour has changed.
    – user1249
    Commented Oct 19, 2010 at 20:37
1
vote

I do it. The progress of our user stories is tracked on a Kanban board, which has a "Has a Test?" column to the left (upstream) of Development.

This somewhat unusual layout makes one policy explicit: a failing automated acceptance test (usually, a few of them) must exist. It must be traceable to a customer requirement. The acceptance tests arise from conditions of satisfaction, which result from conversations that begin with a story card. I facilitate regular workshops where we brainstorm requirements, identify gaps, and figure out the key acceptance tests that ensure user value is delivered when they pass (the definition of done). It's a collaborative activity involving programmers, business analysts and sometimes testers.

The acceptance-testing feedback loop is kind of long: it may take several days to complete the story. The development has its own, shorter TDD feedback loops.

"[...no test-first style...] More akin to Agile...."

This is a complete misrepresentation of Agile. Definition of done is a key component of Agile and one of the pillars it rests upon is the automated acceptance testing (what I described above is one way to do it.) If extreme programming (XP) is used as an Agile implementation method, then ATDD/BDD and TDD are prescribed.

1
vote

I do, but generally only for non ui components, and when I know I cannot keep the whole algorithm for a module in my head at a single time, or when it the module is a new part of whatever system I'm working on, so I can't rely on the majority of libraries I'm using to have have the been highly debugged.

Essentially, I do when the complexity of requirement means I could otherwise get lost in the code.

It is a difficult habit to start, and does require management buy-in, but, when your tests start breaking half way through development, it can be a life saver!

1
vote

I wanted to ask this very question, to see how many companies were actually practicing TDD.

In the 11 years I've been programming professionally only the last two organisations were even aware of TDD (that spans almost 5 years mind, before which time TDD wasn't as popular as it is today). I'll cut to the chase and answer your question before digressing into my sales pitch for TDD :)

At the last company I worked for (online academic publisher of humanities and science collections), we knew we needed to practice TDD but we never quite got there. In our defence we had a 250k code base, so adding tests to an untestable code base of that size felt insurmountable (I feel guilty typing that now!). Even the best of us make mistakes.

Anyone who's done even a small amount of TDD knows how painful retrofitting tests to brown field untestable code can be ... The primary causes are implicit dependencies (you can't pull all the levers to assert results from code - you can't mock scenarios) and violation of the single responsibility principle (tests are complicated, contrived, require too much setup and are hard to understand).

We temporarily grew our QA team (from one, maybe two people to half a dozen or more) to test the platform before any release. It was hugely expensive time wise and financially, some releases would take three months to complete 'testing'. Even then we knew we were shipping with issues, they just weren't 'blockers' or 'critical', just 'high-priority'.

If you've a years commercial experience you'll appreciate that every company asserts critical tasks, and then invents a higher priority level above that, and most likely one above that too - especially when someone from above is pushing a feature/bug fix. I digress ...

I'm happy to report I'm practicing TDD in my current company (telecommunications, web and mobile app development house), coupled with Jenkins CI to give other static analysis reports (code coverage being the most useful after asserting the test suite passes). The projects I've used TDD on are a payment system and grid computing system.

The sales pitch ...

It can often be an uphill struggle justifying automated testing to non-technical team members. Writing tests does add more work to the development process but ... the time you invest in testing now, you'll save in maintenance effort later. You're really just borrowing time. The longer the product is in use, the greater saving you'll make - and it'll help you avoid the big rewrite.

Test first means you're coding your intent first, and then confirming your code fulfills that intent. This provides focus and distills your code to do only what is intended and no more (read no bloat). It's an executable specification and documentation at the same time (if your test is well written, and tests should be as readable/clean as your system code, if not more!).

Non-programmers will (often) not have this insight and so TDD doesn't hold much value for them, and is seen as disposable shortcut to an earlier release date.

Programming is our domain, and in my mind this makes it our responsibility, as professionals, to advise on best practice like TDD. Not for project managers to decide if it's done to reduce development time, it's out of their jurisdiction. In the same way they don't tell you what framework, caching solution or search algorithm to use, they shouldn't tell you if you should be employing automated testing.

In my opinion the software development industry (on the whole) is broken at present, the fact that having tests for your software is NOT the norm.

Picture this in other industries: medical, aviation, automobile, cosmetics, soft toys, alcoholic beverages etc. I asked my fiancee to name an industry where they don't test the product and she couldn't!

Perhaps it's unfair to say no testing occurs because it does ... but in companies without automated testing, it's very manual/human (read clunky and often error prone) process.

One point I would contend in your question ...

They usually wanted development started immediately, or after a short design stint. More akin to Agile.

Being "Agile" doesn't prescribe proceeding without tests, the first member listed on agilemanifesto.org is Kent Beck, the creator of XP and TDD!

Two books I would highly recommend if you're interested in TDD, or just haven't read them and are a keen programmer (that's everyone reading this right? ;)

Growing Objected Oriented Software Guided by Tests

Clean Code - Robert C Martin ("Uncle Bob") Series

These two books compliment one another and condense a lot of sense into few pages.

Thanks for asking this question :)

0
votes

Those who implement clones. I can't think of a better process when you're to develope something, that works exactly like an existing program.

1
  • The same applies to prototyping/exploration. Instead of hacking at it until it looks right, you define what "looks right" means. (This doesn't apply when you need a human to say "it looks right".) And then you hack until you get the green bar. Commented Sep 23, 2010 at 13:35
0
votes

Obviously this is a pretty unusual case, but the developers of SQLite use tests extensively. (I assume their development process is test-first, although I’m not sure.)

  • 73,000 lines of code
  • 91,378,600 lines of test code

See http://www.sqlite.org/testing.html

Not the answer you're looking for? Browse other questions tagged or ask your own question.