BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Test Driven Development or Test Driven Requirements?

Test Driven Development or Test Driven Requirements?

Bookmarks

Where does one start when practicing test driven development?  With the requirements or with the design?  Or, put another way, top-down or bottom-up?  When one starts to write a test first, without any code, what does that test represent?  Both approaches are practiced in the Agile community, but there is little consensus on which provides more value.

Ryan Kinderman talked to some rails developers and asked them about their approach - do they do Bottom-up or Top-down TDD?  He expected everyone to be starting from the top down - i.e. start with the requirements, write tests for those, and then build the system to satisfy those requirements and only those requirements (this is also known as Behavior Driven Development - BDD - do we have enough acronyms yet?!)  What he found, to his surprise, is that almost everyone started from the bottom up:

The problem with the bottom-up approach is that it's difficult to really know how a component needs to be used by its clients until the clients are implemented. To consider how the clients will be implemented, the developer must also think about how those clients will be used by their clients. This thought process continues until we reach the summit of our mighty design! Hopefully, when the developer is done pondering, they can write a suite of tests for a component which directly solves the needs of its client components. In my experience, however, this is rarely the case. What really happens is that the lower-level components tend either to do too much, too little, or the right amount in a way that is awkward or complicated to make use of.

As Ryan reports it, it seems that you have to do either or, but not both.  On the other hand, others in the field have been writing functional tests (or automated acceptance tests) for a long time, and writing them first.  This is sometimes known as story driven development , test driven requirements (TDR), and behavior driven development (BDD).  Those who have practiced this, along with test driven development (both bottom-up and top-down) have found that, not only does it improve quality, but it helps build the social culture between customers, developers, and testers.

So, how do you practice TDD?  Do you do so in a top-down or bottom-up manner?  Does your team practice TDR?  Do you take an either/or approach or practice both?  And, most importantly, what are your goals for doing so?

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • What's first: Test or Code?

    by Dmitriy Setrakyan,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    So, how do you practice TDD?

    We at GridGain tried TDD and it didn't really work for us. The truth is that after you write your tests and then start on development, your understanding of requirements and class APIs change so much that you have to re-factor tests multiple times before you even finished coding.

    What we do right now is semi-TDD. Basically, we start with development and make sure we implement the most straight forward use case first. Once it is done, we write tests for it, and then start implementing edge cases and deeper requirements. This approach allows us to save on constant test refactorings, but it also provides relatively stable test harness in the middle of development process which can be used and extended to further down more thorough implementation of requirements and API's.

    I think the real value to productivity and overall quality of a product is brought with Continuous Integration (and not TDD). By constantly rerunning our entire collection of test suites with every commit (we have around 400 tests) you ensure that quality of your product is not sacrificed as you expand on features or fix bugs (of course we use our own Distributed Junit to speed up our test execution to 13 minutes which otherwise was taking over 40 minutes ;-)

    Best,
    Dmitriy Setrakyan
    GridGain - Grid Computing Made Simple

  • Wrong question

    by Steven Devijver,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    The right question is: how do you manage your design?

    TDD regardless of its direction is just a tool. If you of course disregard the fact that there is any design to be done you're only left with testing which becomes your focus. That tends to lead to confusion and unsatisfactory results.

    So how do you manage your design? Every project is specific but that are some ideas about design (how meta can you get?) that in my experience won't go away.

    One idea is that when you don't do any specific design efforts you end up with a design anyway. You can consider it as a defacto design if you like, the result of not specifically designing or not concentrating design efforts where it's most required.

    Another idea is that design can only work if you really understand the stakes. What are the intentions of the users of your software? What are your intentions? What are the gaps in your understanding? ...

    Other ideas are:

    - you can only get good design through consistency.
    - to properly design you have to know what you're doing.

    You obviously have to test software but this has nothing to do with design. Designs themselves have to be tested as well. By using TDD to design your application - and not considering design as a primary concern - you're both testing software and testing design.

    Testing design means that you're trying to iron out what something has to look like given the constraints you're facing. Testing software means that you're verifying expected behavior.

    Clearly, trying to iron things out and at the same time trying to verify behavior that's not fully understood is counter-intuitive.

  • Top-Down Design with Mocks

    by Geoffrey Wiseman,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    The jMock Paper, Mock Roles, No Objects is one of the better examples I've run into of an approach to top-down design using TDD. A good mock framework seems like a key element in your ability to top-down design without immediately running into the problem that most of the code your high-level requirement needs to invoke does not yet exist.

  • Re: Top-Down Design with Mocks

    by Amr Elssamadisy,

    Your message is awaiting moderation. Thank you for participating in the discussion.


    The jMock Paper, Mock Roles, No Objects is one of the better examples I've run into of an approach to top-down design using TDD.


    Agreed.


    A good mock framework seems like a key element in your ability to top-down design without immediately running into the problem that most of the code your high-level requirement needs to invoke does not yet exist.


    Not necessarily. You could use a variant of objectMother or just write the mocks yourself. Coding is not about typing speed.

  • Re: Wrong question

    by Amr Elssamadisy,

    Your message is awaiting moderation. Thank you for participating in the discussion.


    Clearly, trying to iron things out and at the same time trying to verify behavior that's not fully understood is counter-intuitive.


    OK - but TDD isn't just about testing - it never has. In fact, writing a test for something you still have not designed hones your understanding of the requirements before you start.

    So, by focusing on design without ironing out your understanding of requirements - what I'm reading here - is better because you it is confusing doing two things at once?

    Let me suggest that it is natural to learn about both the design and requirements as we build the system. They feed into each other as our understanding grows. That is a good thing.

  • Re: What's first: Test or Code?

    by Amr Elssamadisy,

    Your message is awaiting moderation. Thank you for participating in the discussion.


    The truth is that after you write your tests and then start on development, your understanding of requirements and class APIs change so much that you have to re-factor tests multiple times before you even finished coding.


    So it is a bad thing to understand about your requirements? Or are your tests not about requirements?

  • Re: Wrong question

    by Steven Devijver,

    Your message is awaiting moderation. Thank you for participating in the discussion.


    Clearly, trying to iron things out and at the same time trying to verify behavior that's not fully understood is counter-intuitive.


    OK - but TDD isn't just about testing - it never has. In fact, writing a test for something you still have not designed hones your understanding of the requirements before you start.

    So, by focusing on design without ironing out your understanding of requirements - what I'm reading here - is better because you it is confusing doing two things at once?

    Let me suggest that it is natural to learn about both the design and requirements as we build the system. They feed into each other as our understanding grows. That is a good thing.


    Design and requirements are two different things. A requirement is to make a million dollars. A design makes people want to spend money.

    Likewise requirements tell what should be done. A design provides a way to do it. If you don't understand requirement how can you make a design that is even remotely significant?

  • Re: What's first: Test or Code?

    by Steven Devijver,

    Your message is awaiting moderation. Thank you for participating in the discussion.


    The truth is that after you write your tests and then start on development, your understanding of requirements and class APIs change so much that you have to re-factor tests multiple times before you even finished coding.


    So it is a bad thing to understand about your requirements? Or are your tests not about requirements?


    A requirement is always very high-level. A requirement doesn't provide a solution, it presents a problem.

    Tests may help you to extend your mental model of requirements. But so can writing code or designing a database schema or reading documentation or a good night sleep.

    Focusing just on tests to figure out your requirements can work just as well as any other method. People can even evangelize this and make a living out of it.

    Put it dismisses a lot of other things. It's a proposition that seems tempting at first. It's the string theory of software development and that's hardly a compliment.

  • Re: What's first: Test or Code?

    by Dave Rooney,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    We at GridGain tried TDD and it didn't really work for us. The truth is that after you write your tests and then start on development, your understanding of requirements and class APIs change so much that you have to re-factor tests multiple times before you even finished coding.


    TDD as defined isn't about writing a whole mess of tests first. It's about the Test/Code/Refactor/Integrate cycle happening in very, very small steps. That's how your overall design and API definition evolve, rather than making assumptions up front and recording them as tests.

    Storytest-Driven Development (SDD) is where you define the business requirements at a much higher level. Tools like FIT work well at that level, and don't affect your architecture as much since they are business facing tests.

    Dave Rooney
    Mayford Technologies

  • Re: What's first: Test or Code?

    by Steven Devijver,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    We at GridGain tried TDD and it didn't really work for us. The truth is that after you write your tests and then start on development, your understanding of requirements and class APIs change so much that you have to re-factor tests multiple times before you even finished coding.


    TDD as defined isn't about writing a whole mess of tests first. It's about the Test/Code/Refactor/Integrate cycle happening in very, very small steps. That's how your overall design and API definition evolve, rather than making assumptions up front and recording them as tests.


    Don't forget bug fixing. Tests (unit or integration) is about testing your software. Any incidental other benefits they may provide is great. Basing fundamentally different things on tests seems like a bad idea.

    Storytest-Driven Development (SDD) is where you define the business requirements at a much higher level. Tools like FIT work well at that level, and don't affect your architecture as much since they are business facing tests.


    X-Driven Development (XDD) is great as far as it takes you. The question is: how far will XDD take me and how much time do I have to invest to get those benefits.

    Testing your software is great. Managing your requirements is great. Scrum does a pretty good job at both.

    You'll never be able to make cunningness, foresight, understanding of technologies, understanding pitfalls, understanding limitations, ... unimportant.

    Software development is a very complicated business and our desire to simplify it will take us only so far. There's enormous value in accepting this, it's the only road to improvement.

    You won't be able to hack your way out of complexity with silver bullets.


    Dave Rooney
    Mayford Technologies

  • What about contract first?

    by Sadek Drobi,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I recently wrote about this particular question on sadekdrobi.com/2007/09/29/draft-design-driven-t...

    In my opnion solutions like FIT and BDD came to rescue from the TDD nightmare. I do write tests before code, but I don't do TDD (as it is defined in books)

    sadekdrobi.com/2007/09/22/i-always-write-tests-...

  • Re: What's first: Test or Code?

    by Dave Rooney,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Don't forget bug fixing. Tests (unit or integration) is about testing your software. Any incidental other benefits they may provide is great. Basing fundamentally different things on tests seems like a bad idea.

    There's an enormous difference between writing tests and performing Test-Driven Development. The former is testing, which is good, and the latter is a design process. With TDD, the resultant tests are a side effect of using tests to describe the intended behaviour of a class. If you perform a side-by-side comparison of code that was written then had unit tests written around it with code that was produced through TDD, you would see that they're considerably different.

    However, TDD alone isn't enough...

    X-Driven Development (XDD) is great as far as it takes you. The question is: how far will XDD take me and how much time do I have to invest to get those benefits.

    Agreed - you need to combine a couple of XDD's to be able to see the maximum value. For example, combining TDD with SDD will cover both the low-level software design and the functional requirements. Behaviour-Driven-Development seeks to cover more of both, but I don't have enough experience with it to comment yet. Perhaps someone else could chime in.

    Testing your software is great. Managing your requirements is great.

    Also agreed.

    Scrum does a pretty good job at both.

    You just lost me. It does an OK job on requirements, but it says nothing whatsoever about testing software.... or did I miss that chapter? ;)

    You won't be able to hack your way out of complexity with silver bullets.

    Where did silver bullets come from? These are tools and techniques for improvement, and I have yet to hear anyone claim that XDD's are the answer to all evils.

    Dave Rooney
    Mayford Technologies

  • Re: What's first: Test or Code?

    by Steven Devijver,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    This article starts with:

    Where does one start when practicing test driven development? With the requirements or with the design?


    Based on that:

    Don't forget bug fixing. Tests (unit or integration) is about testing your software. Any incidental other benefits they may provide is great. Basing fundamentally different things on tests seems like a bad idea.

    There's an enormous difference between writing tests and performing Test-Driven Development. The former is testing, which is good, and the latter is a design process. With TDD, the resultant tests are a side effect of using tests to describe the intended behaviour of a class. If you perform a side-by-side comparison of code that was written then had unit tests written around it with code that was produced through TDD, you would see that they're considerably different.

    However, TDD alone isn't enough...


    You can call it any way you want. The only difference I can see between TDD and merely writing tests is that practitioners of TDD write their tests first but there's no real basis for that interpretation.

    X-Driven Development (XDD) is great as far as it takes you. The question is: how far will XDD take me and how much time do I have to invest to get those benefits.

    Agreed - you need to combine a couple of XDD's to be able to see the maximum value. For example, combining TDD with SDD will cover both the low-level software design and the functional requirements.


    I don't see how TDD alone can lead to a relevant design.

    Behaviour-Driven-Development seeks to cover more of both, but I don't have enough experience with it to comment yet. Perhaps someone else could chime in.

    Testing your software is great. Managing your requirements is great.

    Also agreed.

    Scrum does a pretty good job at both.

    You just lost me. It does an OK job on requirements, but it says nothing whatsoever about testing software.... or did I miss that chapter? ;)

    You won't be able to hack your way out of complexity with silver bullets.

    Where did silver bullets come from? These are tools and techniques for improvement, and I have yet to hear anyone claim that XDD's are the answer to all evils.


    They are too low-level and they risk to restrict focus to those concerns they attempt to cover. Software development requires a holistic approach, a vision on how to deliver and design the particular software that needs to be implemented.

    It is my understanding that to adapt Scrum as a methodology is a good start. Another good practice is to respect a list of non-negotiable constraints, like Nokia's 8 questions.

    Skills are also very important, like knowing how to maintain your code base and knowing how to handle various architectural situations.

    Start with that and you'll find that the way in which you write your tests becomes much less important. Not because testing becomes easier. But because questions regarding requirements and design will be answered on holistic levels above the level of testing.


    Dave Rooney
    Mayford Technologies

  • Re: What's first: Test or Code?

    by Juan Bernabo,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Hi,

    Here maybe is the point:


    You can call it any way you want. The only difference I can see between TDD and merely writing tests is that practitioners of TDD write their tests first but there's no real basis for that interpretation.


    TDD is not about tests at all. Is about growing the software, or doing transformations on your design from executable specifications or shall I say constraints, this process allows your design to emerge from them. When done correctly the processes shift from Invention to Discovery, the nature of the decision making process changes completely.

    In my opinion it´s a way of emulating how nature grows complex structures versus how humans usually have designed and builds things, Christopher Alexanders talk about this shift in processes in his Nature of Order book series.

    It´s a change from a push to a pull decision making on design, but it´s difficult to see any difference without actually experiencing the difference.

    Juan.

  • Re: What's first: Test or Code?

    by Steven Devijver,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Hi,

    Here maybe is the point:


    You can call it any way you want. The only difference I can see between TDD and merely writing tests is that practitioners of TDD write their tests first but there's no real basis for that interpretation.


    TDD is not about tests at all. Is about growing the software, or doing transformations on your design from executable specifications or shall I say constraints, this process allows your design to emerge from them. When done correctly the processes shift from Invention to Discovery, the nature of the decision making process changes completely.

    In my opinion it´s a way of emulating how nature grows complex structures versus how humans usually have designed and builds things, Christopher Alexanders talk about this shift in processes in his Nature of Order book series.

    It´s a change from a push to a pull decision making on design, but it´s difficult to see any difference without actually experiencing the difference.


    I doubt experience (with what exactly?) makes this any easier to understand.

    The fundamental problem here is that design becomes something accidental, something that was discovered. Writing tests - even for the purpose of finding a design - is a poor way to go about things.

    A more meaningful way would be to look at constraints. For example: you need an abstraction for calling a specific web service. What should happen if a call to this web service returns a soap fault?

    This is a basic design question. Do I have to write a test to figure out what the best approach is? Can't I come up with some options and weigh them against what callers of this abstraction layer would expect to happen? Or look at how such a situation is elsewhere? Or come up with some guidelines in case there are none available?

    Frankly I think that any of these options is more valuable because it actually looks at the problem and tries to solve it. You could consider these options when writing a test. Then the design is purposeful in the context it emerged from and the test accidental.



    Juan.

  • Re: What's first: Test or Code?

    by Amr Elssamadisy,

    Your message is awaiting moderation. Thank you for participating in the discussion.


    It´s a change from a push to a pull decision making on design, but it´s difficult to see any difference without actually experiencing the difference.


    BINGO. Thank you Juan for putting it so succinctly. By writing only what needs to be written for tests you are relying on PULL.

  • Re: Wrong question

    by Amr Elssamadisy,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Many who have tried test-first (in any of its flavors) find that we really don't understand requirements as well as we thought we did.

    Even without test-first, you always get your requirements 100% correctly? If not, wouldn't it help better understanding the problem before you proceed so that you solve the right problem?

    TDD is not the only way, but it is much more than tests. And it forces you to think of requirements AND design in small incremental steps.

  • Re: Wrong question

    by Steven Devijver,

    Your message is awaiting moderation. Thank you for participating in the discussion.


    TDD is not the only way, but it is much more than tests. And it forces you to think of requirements AND design in small incremental steps.


    Unfortunately software development as an economic activity forces you to take a different approach.

    The most important benefit of agile development is that you get working, tested software at the end of each iteration (again, see Nokia's 8 questions). Tests play an important role here but honestly whether you write them first or not won't make a big difference as long as they are written.

    What gets easily ignored however is the long-term view of the software you're building. To design software means you build in specific purposed. For example, if you want to make a user interface easy to use in certain ways you won't get that by doing just iterations.

    You need to work on this for a longer period of time. The same is true for performance. If you want specific performance characteristics you need to work on this for a long period of time. The same for good software quality. The same goes for building the right architecture.

    TDD typically only tends to look at functionality. All the rest if blissfully ignored in the YAGNI way. That's fine if you want to develop software like that.

    TDD may seem like a good solution if you don't have a clue what you will build. And some areas of an application can indeed be hard to figure out. But you can't build entire applications like that and expect they will be equally successful and impressive as software that has been purposefully build.

  • Re: Wrong question

    by Sadek Drobi,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    So here we can agree that TDD does NOT test against user's requirements. It just forces us to think of design in small steps? Based on userstories? Well I guess that this incremental design that is only based on userstories lacks the global vision. A simplist example is to design for saving information without thinking about how will be retieved! I guess that TDD turns your code into procedural because units for these tests are methods!

  • Re: What's first: Test or Code?

    by Dave Rooney,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    It´s a change from a push to a pull decision making on design, but it´s difficult to see any difference without actually experiencing the difference.


    Beautiful - very well said! It's the Last Responsible Moment concept from Lean Software Development at the finest grained level.

    Dave Rooney
    Mayford Technologies

  • Re: What's first: Test or Code?

    by Dave Rooney,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I doubt experience (with what exactly?) makes this any easier to understand.

    That sounds to me like the voice of someone who hasn't experience it. How much TDD or SDD have you done in a production environment?

    The fundamental problem here is that design becomes something accidental, something that was discovered. Writing tests - even for the purpose of finding a design - is a poor way to go about things.

    A more meaningful way would be to look at constraints. For example: you need an abstraction for calling a specific web service. What should happen if a call to this web service returns a soap fault?


    Using TDD doesn't mean throwing your brain out the window. You do sit down and plan before writing that first test. You just don't plan for as long or as far ahead as you would using a traditional approach. The amount of up-front planning required, I believe, is a function of the developers' experience and overall competence. For example, I would imaging that Kent Beck can conceptualize a problem considerably better than I can. As a result, he needs to do less up-front planning than I do. However, I do substantially less planning than I did before hearing about TDD 7 years ago and my code is now simpler, more focused, supported by a naturally grown suite of tests and is of better overall quality than before I started using TDD.

    Having said that, it was a leap of faith to move to using a test-first style of development and sometimes I do fall off the wagon. I regret it pretty quickly, though, since quality suffers.

    Your mileage may vary, of course.

    Dave Rooney
    Mayford Technologies

  • Re: What's first: Test or Code?

    by Steven Devijver,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I doubt experience (with what exactly?) makes this any easier to understand.

    That sounds to me like the voice of someone who hasn't experience it. How much TDD or SDD have you done in a production environment?


    If you want to put in doubt my arguments by doubting my experience that's up to you. My arguments still stand despite.



    The fundamental problem here is that design becomes something accidental, something that was discovered. Writing tests - even for the purpose of finding a design - is a poor way to go about things.

    A more meaningful way would be to look at constraints. For example: you need an abstraction for calling a specific web service. What should happen if a call to this web service returns a soap fault?


    Using TDD doesn't mean throwing your brain out the window. You do sit down and plan before writing that first test. You just don't plan for as long or as far ahead as you would using a traditional approach. The amount of up-front planning required, I believe, is a function of the developers' experience and overall competence. For example, I would imaging that Kent Beck can conceptualize a problem considerably better than I can. As a result, he needs to do less up-front planning than I do. However, I do substantially less planning than I did before hearing about TDD 7 years ago and my code is now simpler, more focused, supported by a naturally grown suite of tests and is of better overall quality than before I started using TDD.

    Having said that, it was a leap of faith to move to using a test-first style of development and sometimes I do fall off the wagon. I regret it pretty quickly, though, since quality suffers.

    Your mileage may vary, of course.


    Again, TDD doesn't address performance, code quality, any kind of consistency you want to achieve, architecture, usability design, ...

    None of this can be reduced to isolated behavior. Testing is really useful but it's far from everything.


    Dave Rooney
    Mayford Technologies

  • Problem with the comments....

    by Amr Elssamadisy,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Sometimes the comments are useful and really express an exchange of information. These comments (and I'm part of the problem) seem to be a back and forth debate with very little useful information exchanged.

    Is TDD good or bad? Try it for yourself and do what works for you.

    To the article itself - is Top Down TDD better/worse/complementary to Bottom Up TDD?

    Or, if it is the wrong question, what is the right question? Should be we focused on design - or does design itself have no customer value (in Lean terms) and should we be focused on something else?

  • Re: Problem with the comments....

    by Steven Devijver,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Sometimes the comments are useful and really express an exchange of information. These comments (and I'm part of the problem) seem to be a back and forth debate with very little useful information exchanged.

    Is TDD good or bad? Try it for yourself and do what works for you.

    To the article itself - is Top Down TDD better/worse/complementary to Bottom Up TDD?

    Or, if it is the wrong question, what is the right question? Should be we focused on design - or does design itself have no customer value (in Lean terms) and should we be focused on something else?


    What do you mean with design? Is it purely the design of an API you're talking about?

  • Re: Problem with the comments....

    by Amr Elssamadisy,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I mean design in the broad sense - what components exist? What are their responsibilities (this implies their APIs)? How should the components communicate? How much generalization should there be? etc....

    Is 'good design' an end in itself? Or is it something intermediate - a way we try to achieve ... (fill in the blank).

  • Re: What's first: Test or Code?

    by Chris Edwards,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I have a very different approach to TDD. On my project, we hold a group design session before we write any tests or code. In that design session, we determine the object structure and bombard our design with edge cases and such. We continue modifying it on the whiteboard till it satisfies all the requirements. After we have the design, we enumerate all the tests that will ensure the implementation works as expected (considering our user requirements as well). We actually end up with a list of test names that need to be implemented.

    This is one of the hardest parts of our design session. Its so easy to say...it works...just implement it. But it is the most important part of our design...proving that it works. Many times we come up with tests that bring to light issues with our design that force us to tweak it. This list of tests is absolutely invaluable when you implement the code to ensure your design does what it should.

    It is only after we have the detailed design and a list of tests that prove it work that we actually begin implementation. We implement it using TDD. We write each test one at a time and then implement the code that will make it pass. When the last test has been implemented and passes, the task is done...

    If we wrote the tests last, we probably would skip them, and we wouldn't have a clear path of what to do. Our tests provide that...they give us a goal to accomplish before moving on to the next one. (We order our tests during the design session in the order they should be implemented).

    I realize this is a hybrid approach and differs from purist form of TDD where TDD itself is used for design discovery. We separate our design and I find that we spend more time in design than we do coding. Writing an application is far more than just typing in the code. Typing is the easy part...I leverage the whole team for the hard part...design. The code is usually implemented in no time...as long as the design was correct. In fact, typing in the code is almost an afterthought.

    TDD is invaluable to this design and implement process. Without the tests, we cannot make huge sweeping design changes in the code (which we do quite often). Refactoring tools go a long way to help as well.

    The tests are the primary key to having an "Agile" codebase (one that can be easily modified to accommodate changing requirements).

    In the absence of tests, you can't change code without having the confidence it will work after the change. Tests give you that confidence. If they pass, your code will work... If they don't, you can just roll back the changes (worst case) or fix the code so they do pass.

    In the absence of Tests, changes to design are painful because you break things. You will still break code when you have tests, but you immediately know that its broke, what broke it, and where it broke. (because you just did it). If you wait a month before a tester tells you it broke, you have no idea where to start fixing it.

    The design is another key to having an agile codebase... While tests ensure your changes were successful, Design allows you to make these changes easily.

    In the absence of well-designed code, changes are difficult. If you don't have a solid design to work from, (I am talking about the codebase you are working with here..) with your concerns consolidated and cleanly separated, you can't change things quickly. The codebase must be very clean and well designed for you to truly reap the benefits of agile.

    In the absence of well-designed code, TDD (or testing in general) is truly painful. You may not even be able to test a lot of your code because it wasn't designed to be testable.

    In the absence of well-designed code, further design is very difficult: You can't "get your head around" the design. You try to consider all the things that need to be "updated" when you make a change but its too difficult because your concerns are scattered all over the system. Things aren't simplified and consolidated, so you can't make one change in one place...its many changes everywhere...and until you implement it and see it break, you may not even know where those changes are needed.

    Maybe I am rambling, maybe I am off topic... I am just passionate about this because just came from an well-designed app built from the ground up with TDD. We had great success...design and testing were simple. We could make huge design changes in no time to adapt the application to any change they threw our way. I was blown away by our productivity. I am now on a project that was not well-designed, and had little test coverage. TDD and design were VERY painful when I came onboard. If I had not had such an awsome experience with TDD on the prior project, I would have given up long ago. However, I stuck with it. We have been at it for 4 months. The project's codebase is now 95% covered in tests, and has been 80% redesigned and it is going so much smoother. We are finally making great progress. I am now finding that the mere 20% of the codebase that is still poorly designed is where we have all our pain. Everything else is a simple to work with.

    The bottom line? If you think TDD is not working...your codebase might be all out of whack. If you have good design, and complete test coverage, Design and testing will be a breeze and you will reap the benefits of it. Otherwise, it may be a long slow (and painful) road to get your codebase where you can see the benefits. It has taken us 4 months of pain so far to get to where we are now. We are now seeing the light at the end of the tunnel and I can honestly say it was worth every second of it!

    -Chris Edwards

  • Re: What's first: Test or Code?

    by Amr Elssamadisy,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Thanks Chris for that detailed report!

    Not that it matters much - because this is ultimately working VERY WELL for you - but do your tests read as mini requirements or mini-specs for each class? That is, do the tests reflect the design decision that's already made during your session, or what the design must solve? (Or, for a 3rd rephrasing, do they describe the problem or the solution ;) )

    Amr

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT