Opinion: Test Driven versus Test First

Discussions

News: Opinion: Test Driven versus Test First

  1. Opinion: Test Driven versus Test First (18 messages)

    The terms Test Driven and Test First are often used interchangeably. Dave Thomas has written about the difference, and that although he believes in test driven approaches, he may not be a fan of test first. Well, of course, he is always pragmatic :)

    Excerpt
    I recently got into a discussion with Cobbie Behrend, following on from some comments I’d made about test-driven development. I’d said that I rarely do test-first, but I often do test-driven coding.

    Cobbie pushed me to distinguish between them, particularly in light of references on the Object Mentor site, the C2 wiki, and other sites, which seem to equate the two.

    I disagree—test-first is different than test-driven development.

    For me, test-driven development is an important way of thinking about coding. It’s about using tests to gain perspective on your design and implementation. You listen to what the tests are telling you, and alter to code accordingly. Finding it hard to test something in isolation? Refactor your code to reduce coupling. Is it impossible to mock out a particular subsystem? Look at adding facades or interfaces to make the separation cleaner. Tests drive the design, and tests verify the implementation.

    Test-first development takes this a step further. In test-first, you never write a line of production code until you first have a failing test that will be "fixed" by the code you write. Want to write a new class? First write a test that instantiates it, watch the test fail, and then implement the class body to fix the broken test.
    Read Test Driven or Test First?
  2. intent is first[ Go to top ]

    Intent in your mind comes before the test or the function.
    Writing the test first is just a process you can
    follow or not follow. It's not magical in anyway.
    What is magical creating the intent. By the article
    i do test driven development. I pretty much simultaneously
    develop code, documentation, and tests depending on what
    makes more sense for where i am at. Being religious on
    what comes first is taking a long step towards dogma.
  3. I feel that properly designing an object to work defensively among the other objects is your safest bet in writing software. I would not write a test beforehand to test if the vapor will eventual work once it forms an object and passes those tests. I fail to see how that added work will prevent problems. I find that it is better to write sanity checks into the code which essentially act as continual unit tests as well as prevent other developers on the team from misusing your work. Exporting the sanity checks to unit tests only run on request will only place that useful information in a place a developer will likely never go. It is like all that unread Javadoc that nobody seems to read.

    The problem with unit testing is that you only test for what you can predict and your tests will fail you horribly for the unforeseen problem. It seems more feasible to simply design each object in the system to protect itself and leave the unit tests to the relationships between objects (design contracts) to verify the desired interactions are exactly as they should be. There has to be a reasonable balance between time spent on unit tests in relation to the actual application.
  4. I agree that you cannot write tests to predict things that can go wrong. The value of test driven dev comes in regression testing. When you are adding new features, its arguably easier to run existing tests that manually exercise all aspects of your system (of course, you can always setup automated testing to do the same, if economically feasible).

    When faced with client pressures to meet crazy deadlines, test driven always goes out of the window...
  5. A Reply to Brennan[ Go to top ]

    The problem with unit testing is that you only test for what you can predict and your tests will fail you horribly for the unforeseen problem.
    This is the second time that I've heard you say this. Just because test miss somethings, does not lessen the benefit of the tests. They are completely unrelated! The benefit is that they do catch errors when written well. Thats like saying, because every once in a while someone dies while jumping out of a plane with a parachute, its pointless to have a parachute when you jump out of a plane!

    But back on topic, whether you write them first or last... it does not matter. The benefits can be the same, depending on how you code. More on the conversation can be found here: http://www.cobbie.com/blog/archives/000028.html .

    Cobbie
  6. I'm OK, You're OK[ Go to top ]

    Robust design, TDD & TFP are all efforts toward the same thing--better software. A decent programmer will use them all in apprpriate measure. Robustly designed, well implemented code coupled with a killer test suite makes for a flexible and longer-lived end result.
  7. I'd have to disagree that the test first process adds no benfit.

    Recently I've been reviewing some code written with TDD in mind, but where the test first approach had not been taken. I picked up on a few tests that had incorrect assertions and would never fail. These were broken useless tests. In fact, they were worse than useless, as they still covered the code (so they didn't identify missing tests in my code coverage tool), but would never break if the code was accidently broken during a refactor !

    If the test first process of always running a broken test before implemention was followed these tests would never have failed, and the mistake in the test would have been identified.

    It could be said that the tests were simply bad coding mistakes, but it can't be argued that the test first approach would not have identified the mistakes and added great value in this case. That's what a process is for, right ?

    The test first process is quite a mind shift from traditional development, so it has an initial learning curve. I think this is the main reason it is seen as being slow and a lot of overhead. I'd recommend anyone to try for a while with TDD (TFD :-) before they give up.

    Cheers,
    Darren.
  8. If the test first process of always running a broken test before implemention was followed these tests would never have failed, and the mistake in the test would have been identified.
    This is one of the most common oversights I've observed and experienced personally --not validating the unit test by running and failing it before any business code is written. It's also one of the most common, "Aha," moments when people ultimately grasp the concept.
  9. IIRC, Test-Driven is just a newer name for Test-First. They are the exact same thing. Test-First used to confuse people into thinking it meant writing *all* of your tests before you code, when in reality it means writing a little bit of test code, then a little bit of business code, and so on in very small, tight iterations. So, they changed the name. Same concept, new name. AFAIK, there is no difference and therefore no other relationship between the two.
  10. The author says: TFP is a way to do TDD. I agree, but I don't think that's the best way to do TDD.

    Well, TDD is important to me to clarify and consolidate my design decisions. If I can't figure out a design or implementation strategy the tests very often help me to find a good solution or a good idea. In addition, TDD <bold>always</bold> can help you to design easy-to-use APIs.

    I think that TFD discipline is not very suitable to me in <bold>every case</bold>. I don't need to implement a test to a trivial method. This would be a loss of time. I would really to implement a test to a critical piece.

    Regards,

    Forte.
  11. sorry the typos in above message...

    :)
  12. Test this!
  13. The deeper question is...[ Go to top ]

    ...does the test drive the design, or does the design drive the test.

    Answer: the design drives the test, but the test is essential.
  14. The deeper question is...[ Go to top ]

    ...does the test drive the design, or does the design drive the test.Answer: the design drives the test, but the test is essential.
    In test diven development (TDD) it is the writing of the test that drives the design of the system.

    There is no up-front design in TDD, it emerges as you write the test.
  15. Test vs. Design[ Go to top ]

    In test diven development (TDD) it is the writing of the test that drives the design of the system. There is no up-front design in TDD, it emerges as you write the test.
    Put another way, in TDD, the design is expressed as a set of tests. Maybe I need to get out more, but strikes me as an exciting idea.
  16. The deeper question is...[ Go to top ]

    There is no up-front design in TDD, it emerges as you write the test.
    Rather, there is no Big Design Up Front. There still should be upfront design, just not to excess.
  17. The deeper question is...[ Go to top ]

    Hmmm... I disagree with both positions.

    You can do TDD even if you've done Big Design Up Front. Remember, Test-Driven Design is, among other things, a way of focusing on how a client programmer would use the code, thus providing the test writer with insight on how to improve the design of the tested code. Those programmer tests also serve as an excellent regression suite. Even if you happen to be that poor programmer stuck under the deluge of a waterfall, you can still allow the tests to drive refactoring of the code. So BDUF and TDD are not mutually exclusive.

    Aslak mentioned that there is no up front design when doing TDD, that the design emerges. I think this is also false.

    Even in XP, there is an architectural style agreed upon by the team. In most agile projects, there will be some agreement before programmers go off and code. The agreements, or small design up front, may take the form of whiteboard models in Agile Modeling. In other processes it might take the form of CRC cards or be as basic as a few conversations.

    I don't know about you, but I'd find it frightening if I happened to test myself into a domain object architecture when everyone else is building event-driven message consumers and producers.

    I think the real point is that TDD teaches us to acknowledge that the work of design continues well after the code is written. The techniques of TDD belong in the skill box of every accomplished programmer.

    Like any technique, however, there is a vanishing point beyond which absurdity lies. Don't go there.
  18. IMO, "Test First" practice requests us three essentially different things:

     1.Write automated tests for the codes we write.
     2.Use these tests as the operational specifications of the codes.
     3.Write tests (specifications) before we code.

    I thoroughly agree to the first and the second one, and to the third one to some extent. It is usually better to clarify what we should do before thinking about how we should do it. But if the “what” is clear enough, we may be able to skip the first step. But even in such a case, we should be prepared to go back to “what” (namely, writing the tests first) when we get stuck.

    I imagine what Dave is saying is not very far from my opinion.
  19. Overloaded terminology[ Go to top ]

    The problem here is that Dave Thomas is trying to overload a term that has existing meaning. Yes, test-driven and test-first are the exact same thing.

    The underlying message that Dave is suggesting is that you don't have to be a 'test-first' nazi in order to achieve good design and adequate test coverage. I think that if he had called it "test-friendly development" instead of "test-driven design" we wouldn't be having this conversation.