Loading ...
Sorry, an error occurred while loading the content.

TDD - Planning Ahead

Expand Messages
  • Brandon Olivares
    Hi, I m writing a class now that I m really not sure how I m going to implement certain parts. Of course, I m writing each test before implementing it. I ve
    Message 1 of 22 , Dec 31, 2008
    • 0 Attachment
      Hi,

      I'm writing a class now that I'm really not sure how I'm going to implement
      certain parts. Of course, I'm writing each test before implementing it.
      I've read before about not thinking too far in the future, and only writing
      the code that makes the test pass. How literally do you take this? Is it
      wise to try to look in the future to find the best implementation of the
      class, or literally only write as much as is needed to make the test pass
      right now, even if it will be changed later?

      Thanks,
      Brandon
    • Olof Bjarnason
      ... Take it literally. Given just one test function returns 0 for empty lists I implement the function like this: function F(List l) { return 0; } Given
      Message 2 of 22 , Dec 31, 2008
      • 0 Attachment
        2008/12/31 Brandon Olivares <programmer2188@...>:
        > Hi,
        >
        > I'm writing a class now that I'm really not sure how I'm going to implement
        > certain parts. Of course, I'm writing each test before implementing it.
        > I've read before about not thinking too far in the future, and only writing
        > the code that makes the test pass. How literally do you take this? Is it
        > wise to try to look in the future to find the best implementation of the
        > class, or literally only write as much as is needed to make the test pass
        > right now, even if it will be changed later?

        Take it literally.

        Given just one test "function returns 0 for empty lists" I implement
        the function like this:

        function F(List l) { return 0; }

        Given another test "function return 2 for list containing element with
        value 1" I change it to:

        function F(List l) { if(l.Length==0) return 0; else return 2 }

        I continue like this, as long as it is easier to "fake" than to
        implement something real.

        The smell to do something "real" is that is starts to get "hard" to fake.

        >
        > Thanks,
        > Brandon
        >
        >
      • Brandon Olivares
        ... Wow, didn t know one could take it that literally. How does your code turn out? I would be afraid of the code just being inefficient. Technically, you
        Message 3 of 22 , Dec 31, 2008
        • 0 Attachment
          > -----Original Message-----
          > From: extremeprogramming@yahoogroups.com
          > [mailto:extremeprogramming@yahoogroups.com] On Behalf Of Olof Bjarnason
          > Sent: Wednesday, December 31, 2008 7:24 AM
          > To: extremeprogramming@yahoogroups.com
          > Subject: Re: [XP] TDD - Planning Ahead
          >
          > Take it literally.
          >
          > Given just one test "function returns 0 for empty lists" I implement
          > the function like this:
          >
          > function F(List l) { return 0; }
          >
          > Given another test "function return 2 for list containing element with
          > value 1" I change it to:
          >
          > function F(List l) { if(l.Length==0) return 0; else return 2 }
          >
          > I continue like this, as long as it is easier to "fake" than to
          > implement something real.
          >
          > The smell to do something "real" is that is starts to get "hard" to
          > fake.
          >

          Wow, didn't know one could take it that literally. How does your code turn
          out? I would be afraid of the code just being inefficient.

          Technically, you could go on faking it indefinitely, but you know you mean
          to actually do something else with it. For instance if I have a method that
          needs to return a count of something, I could return the expected number,
          but I know I really want the count, no matter what it is.
        • John A. De Goes
          The main point of passing tests in the simplest possible way is to force your tests to truly drive the functionality you want. When the simplest way to pass a
          Message 4 of 22 , Dec 31, 2008
          • 0 Attachment
            The main point of passing tests in the simplest possible way is to
            force your tests to truly drive the functionality you want. When the
            simplest way to pass a test is to implement the functionality you
            need, you know you have a good test.

            Moreover, passing tests in the simplest possible way also results in
            code coverage of all code paths -- a very important property for safe
            refactoring.

            Now, all that said, I don't buy the "don't think, just code," mantra.
            Even passing tests in the simplest possible way, it's useful to think
            about where the design is heading and what you can do to make clean
            abstractions appear. In particular, during the refactoring phase of
            TDD, there are often many ways you can refactor code to improve its
            usability and modularity -- providing you know what you're doing.
            There are times I even skew the code that I write to pass failing
            tests, to take the design where I want it. And there are still other
            times I simply abandon TDD in favor of a test-first approach to
            implement a design I already know I want (because frankly, for some
            kinds of work, lightweight but upfront design leads to far superior
            results than TDD).

            If you're new to TDD, then just do everything "literally". After you
            come to understand why TDD is the way it is, and what benefits it can
            (and cannot) provide, then you'll be in a better position to bend or
            even break the rules where doing so is more productive.

            Regards,

            John A. De Goes
            N-BRAIN, Inc.
            http://www.n-brain.net
            [n minds are better than n-1]

            On Dec 31, 2008, at 6:40 AM, Brandon Olivares wrote:

            >
            >
            > > -----Original Message-----
            > > From: extremeprogramming@yahoogroups.com
            > > [mailto:extremeprogramming@yahoogroups.com] On Behalf Of Olof
            > Bjarnason
            > > Sent: Wednesday, December 31, 2008 7:24 AM
            > > To: extremeprogramming@yahoogroups.com
            > > Subject: Re: [XP] TDD - Planning Ahead
            > >
            > > Take it literally.
            > >
            > > Given just one test "function returns 0 for empty lists" I implement
            > > the function like this:
            > >
            > > function F(List l) { return 0; }
            > >
            > > Given another test "function return 2 for list containing element
            > with
            > > value 1" I change it to:
            > >
            > > function F(List l) { if(l.Length==0) return 0; else return 2 }
            > >
            > > I continue like this, as long as it is easier to "fake" than to
            > > implement something real.
            > >
            > > The smell to do something "real" is that is starts to get "hard" to
            > > fake.
            > >
            >
            > Wow, didn't know one could take it that literally. How does your
            > code turn
            > out? I would be afraid of the code just being inefficient.
            >
            > Technically, you could go on faking it indefinitely, but you know
            > you mean
            > to actually do something else with it. For instance if I have a
            > method that
            > needs to return a count of something, I could return the expected
            > number,
            > but I know I really want the count, no matter what it is.
            >
            >
            >



            [Non-text portions of this message have been removed]
          • Tim Walker
            Personally, I think this is right and well put. It requires an excellent environment where the per-successful-step is verified. Autotest, for example, runs the
            Message 5 of 22 , Dec 31, 2008
            • 0 Attachment
              Personally, I think this is right and well put. It requires an
              excellent environment where the per-successful-step is verified.
              Autotest, for example, runs the test with each save of the file. What
              I think gets folks hackles up about this is the 'implication' that the
              we're somehow not thinking ahead or that it's even possible to stop
              thinking about whats coming up.

              I mean, you know you're going to California (with an aching in my
              heart) but right now you're just driving.

              Tim

              On Wed, Dec 31, 2008 at 5:24 AM, Olof Bjarnason
              <olof.bjarnason@...> wrote:
              > 2008/12/31 Brandon Olivares <programmer2188@...>:
              >
              >> Hi,
              >>
              >> I'm writing a class now that I'm really not sure how I'm going to
              >> implement
              >> certain parts. Of course, I'm writing each test before implementing it.
              >> I've read before about not thinking too far in the future, and only
              >> writing
              >> the code that makes the test pass. How literally do you take this? Is it
              >> wise to try to look in the future to find the best implementation of the
              >> class, or literally only write as much as is needed to make the test pass
              >> right now, even if it will be changed later?
              >
              > Take it literally.
              >
              > Given just one test "function returns 0 for empty lists" I implement
              > the function like this:
              >
              > function F(List l) { return 0; }
              >
              > Given another test "function return 2 for list containing element with
              > value 1" I change it to:
              >
              > function F(List l) { if(l.Length==0) return 0; else return 2 }
              >
              > I continue like this, as long as it is easier to "fake" than to
              > implement something real.
              >
              > The smell to do something "real" is that is starts to get "hard" to fake.
              >
              >>
              >> Thanks,
              >> Brandon
              >>
              >>
              >
            • Olof Bjarnason
              ... Well the fake code is removed after say test three or four. It keeps me focused on writing tests, instead of implementing what I my fantasy tells me will
              Message 6 of 22 , Dec 31, 2008
              • 0 Attachment
                2008/12/31 Brandon Olivares <programmer2188@...>:
                >
                >
                >> -----Original Message-----
                >> From: extremeprogramming@yahoogroups.com
                >> [mailto:extremeprogramming@yahoogroups.com] On Behalf Of Olof Bjarnason
                >> Sent: Wednesday, December 31, 2008 7:24 AM
                >> To: extremeprogramming@yahoogroups.com
                >> Subject: Re: [XP] TDD - Planning Ahead
                >>
                >> Take it literally.
                >>
                >> Given just one test "function returns 0 for empty lists" I implement
                >> the function like this:
                >>
                >> function F(List l) { return 0; }
                >>
                >> Given another test "function return 2 for list containing element with
                >> value 1" I change it to:
                >>
                >> function F(List l) { if(l.Length==0) return 0; else return 2 }
                >>
                >> I continue like this, as long as it is easier to "fake" than to
                >> implement something real.
                >>
                >> The smell to do something "real" is that is starts to get "hard" to
                >> fake.
                >>
                >
                > Wow, didn't know one could take it that literally. How does your code turn
                > out? I would be afraid of the code just being inefficient.

                Well the fake code is removed after say test three or four. It keeps
                me focused on writing tests, instead of implementing what I my fantasy
                tells me will be the right code in the future.

                So the end result is clean, efficient code. Probably more efficient
                and cleaner than if I had coded the "right" code after the first test.

                >
                > Technically, you could go on faking it indefinitely, but you know you mean
                > to actually do something else with it. For instance if I have a method that
                > needs to return a count of something, I could return the expected number,
                > but I know I really want the count, no matter what it is.

                Yes I could go on indefinately. But at test three or four, keeping on
                the "faking" will be harder than implementing the "real" code.

                So then it is easier to implement the real code - and I go on doing just that.

                When faking starts to make you "have to think" -- that is a true sign
                that it is time to write some real code! But just enough real code to
                make the tests so far pass.

                You see?

                >
                >
              • Brandon Olivares
                ... Very nice. Thanks a lot; that definitely helps. Brandon
                Message 7 of 22 , Dec 31, 2008
                • 0 Attachment
                  > -----Original Message-----
                  > From: extremeprogramming@yahoogroups.com
                  > [mailto:extremeprogramming@yahoogroups.com] On Behalf Of Olof Bjarnason
                  > Sent: Wednesday, December 31, 2008 11:12 AM
                  > To: extremeprogramming@yahoogroups.com
                  > Subject: Re: [XP] TDD - Planning Ahead
                  >
                  >
                  > Well the fake code is removed after say test three or four. It keeps
                  > me focused on writing tests, instead of implementing what I my fantasy
                  > tells me will be the right code in the future.
                  >
                  > So the end result is clean, efficient code. Probably more efficient
                  > and cleaner than if I had coded the "right" code after the first test.
                  >

                  Very nice. Thanks a lot; that definitely helps.

                  Brandon
                • Charlie Poole
                  Hi Brandon, ... I would never tell someone not to think and I don t believe any of our standard books on xp tell you that. Of course, there is a lot written
                  Message 8 of 22 , Dec 31, 2008
                  • 0 Attachment
                    Hi Brandon,

                    > I'm writing a class now that I'm really not sure how I'm
                    > going to implement certain parts. Of course, I'm writing each
                    > test before implementing it.
                    > I've read before about not thinking too far in the future,
                    > and only writing the code that makes the test pass. How
                    > literally do you take this? Is it wise to try to look in the
                    > future to find the best implementation of the class, or
                    > literally only write as much as is needed to make the test
                    > pass right now, even if it will be changed later?

                    I would never tell someone not to think and I don't believe
                    any of our standard books on xp tell you that. Of course,
                    there is a lot written that tells you not to *implement*
                    anything for the future, and I'm guessing that's what you
                    really mean.

                    But I wonder if you aren't missing something here. The
                    distinction between not thinking ahead and not implementing
                    ahead is not a trivial one. In fact, I would argue that it's
                    the tension between your ideas about where the application is
                    going and what you actually code that drives TDD.

                    So, yes, I think you should write only as much as it takes
                    to make the test pass right now and change it later if - and
                    this is the big if - your vision of the future turns out to
                    be right.

                    Because things don't always turn out the way you thought they
                    would. Sometimes, what seemed to be the best design when you
                    were writing your first test turns out to be a bad idea by
                    the time you get to the tenth. If that happens, you end up
                    having to remove stuff. On the other hand, if things turn
                    out the way you expected, you already know what to change
                    and typing it in takes very little time.

                    This part of TDD is not easy when you start. It requires
                    living with the tension between where you expect to go
                    and what you have so far permitted yourself to implement.
                    It requires holding several things in your head at once.
                    One of the roles of the tests is to help you by reminding
                    you with this, by constantly reminding you of what you
                    have done so far and what you need to do next.

                    Charlie
                  • Phlip
                    ... Try this: Plan out a class design the old-fashioned way, and implement it in a sandbox, using test-last. Then go back to the production code, and see if
                    Message 9 of 22 , Dec 31, 2008
                    • 0 Attachment
                      Brandon Olivares wrote:

                      > I'm writing a class now that I'm really not sure how I'm going to implement
                      > certain parts. Of course, I'm writing each test before implementing it.
                      > I've read before about not thinking too far in the future, and only writing
                      > the code that makes the test pass. How literally do you take this? Is it
                      > wise to try to look in the future to find the best implementation of the
                      > class, or literally only write as much as is needed to make the test pass
                      > right now, even if it will be changed later?

                      Try this: Plan out a class design the old-fashioned way, and implement it in a
                      sandbox, using test-last.

                      Then go back to the production code, and see if you can write tests which force
                      the planned design to emerge.

                      --
                      Phlip
                    • Dale Emery
                      Hi Brandon, Technically, you could go on faking it indefinitely, but you know you mean ... That s what makes the refactor step so important. As you write
                      Message 10 of 22 , Dec 31, 2008
                      • 0 Attachment
                        Hi Brandon,

                        Technically, you could go on faking it indefinitely, but you know you mean
                        > to actually do something else with it. For instance if I have a method that
                        > needs to return a count of something, I could return the expected number,
                        > but I know I really want the count, no matter what it is.


                        That's what makes the "refactor" step so important. As you write the code
                        to pass your second or third or fourth test, you will likely introduce some
                        repetition or pattern or awkwardness into the code. Once the code passes
                        the tests, you'll notice that smell and refactor the code to be simpler.

                        One trick I've learned is how to select the next test: Select one that
                        nudges the existing code toward a /little/ more ugliness. Then refactor the
                        ugliness out. With counts, I find that tests for zero, one, and many items
                        usually is enough to force just the right amount of ugliness, which in turn
                        forces the code toward its final form (loop, internally-stored count,
                        regular expression). That's three tests, which you can write and pass
                        within a few minutes.

                        Dale

                        --
                        Dale Emery, Consultant
                        Inspiring Leadership for Software People
                        Web: http://dhemery.com
                        Weblog: http://cwd.dhemery.com


                        [Non-text portions of this message have been removed]
                      • Dale Emery
                        Hi Phlip, Brandon, Try this: Plan out a class design the old-fashioned way, and implement it in ... I used a variation of that on my first TDD project. I was
                        Message 11 of 22 , Dec 31, 2008
                        • 0 Attachment
                          Hi Phlip, Brandon,

                          Try this: Plan out a class design the old-fashioned way, and implement it in
                          > a sandbox, using test-last.


                          I used a variation of that on my first TDD project. I was confident in my
                          ability to design well on paper. I'd sketch out a design on paper, then set
                          it aside and implement the feature by TDD. The first time I did that, I was
                          surprised to find that not only did the code differ from my design, but I
                          liked the TDDed code better than what I'd sketched. The second time, I was
                          surprised and slightly disconcerted. The third time, I was hooked on TDD.

                          These days, I sometimes sketch out a design ahead of coding, but only to
                          give me ideas for my next test. Then I set the design aside and proceed
                          with TDD.

                          I'm still confident in my ability to design well on paper. But now I
                          understand that there is great power in attending to smells and refactoring
                          them away, because each code smell is a violation of one of the two big
                          time-tested design principles of high cohesion and low coupling, each
                          refactoring improves the code with respect to one or both principles, and
                          attending to coupling and cohesion in the small (by refactoring smells)
                          incrementally improves the design in the large.

                          Dale

                          --
                          Dale Emery, Consultant
                          Inspiring Leadership for Software People
                          Web: http://dhemery.com
                          Weblog: http://cwd.dhemery.com


                          [Non-text portions of this message have been removed]
                        • Adam Sroka
                          ... Ditto all of the above. You have to know when you are close enough to the real answer that you can get there with one small step. That is the trick. It
                          Message 12 of 22 , Dec 31, 2008
                          • 0 Attachment
                            On Wed, Dec 31, 2008 at 12:07 PM, Dale Emery <dale@...> wrote:
                            > Hi Brandon,
                            >
                            > Technically, you could go on faking it indefinitely, but you know you mean
                            >> to actually do something else with it. For instance if I have a method
                            >> that
                            >> needs to return a count of something, I could return the expected number,
                            >> but I know I really want the count, no matter what it is.
                            >
                            > That's what makes the "refactor" step so important. As you write the code
                            > to pass your second or third or fourth test, you will likely introduce some
                            > repetition or pattern or awkwardness into the code. Once the code passes
                            > the tests, you'll notice that smell and refactor the code to be simpler.
                            >
                            > One trick I've learned is how to select the next test: Select one that
                            > nudges the existing code toward a /little/ more ugliness. Then refactor the
                            > ugliness out. With counts, I find that tests for zero, one, and many items
                            > usually is enough to force just the right amount of ugliness, which in turn
                            > forces the code toward its final form (loop, internally-stored count,
                            > regular expression). That's three tests, which you can write and pass
                            > within a few minutes.
                            >

                            Ditto all of the above.

                            You have to know when you are close enough to the "real" answer that
                            you can get there with one small step. That is the trick. It is true
                            that you could go on faking it for a long time. But, as you said the
                            goal is to get to the "real" thing. You just want to lower the
                            resistance enough that you can get there with a small, logical, easily
                            tested change. These are the "baby steps" that Kent Beck talks about.

                            BTW, a similar method has been described as "triangulation". I'm not
                            sure where the term originates, but Dave Astels used it in his book.
                            Basically, you write two tests that expect two different values from
                            the same code. When you write the second implementation to return the
                            second value you will have created duplication which you can refactor
                            out.

                            Another trick is to look for a value that wouldn't naturally come out
                            of the code and test for that in order to force yourself to get the
                            "real" value. This is the approach that I prefer when using mocks. For
                            example, if my initial test checks for zero (or null, nil, undef,
                            whatever your language returns by default) then I might mock something
                            to produce the value "5" and expect that answer in my test. Then I can
                            set my implementation to get it from the right place. You could argue
                            that it is simpler to just return the hardcoded value, but this is a
                            small enough step that I am comfortable.
                          • Brandon Olivares
                            Hi, Thanks so much. This all really helps. It is difficult, but I am really liking it so far. I don t know yet how this class will end up implementing the
                            Message 13 of 22 , Dec 31, 2008
                            • 0 Attachment
                              Hi,

                              Thanks so much. This all really helps.

                              It is difficult, but I am really liking it so far. I don't know yet how this
                              class will end up implementing the needed functionality, though. I just know
                              how it passes the tests so far. Quite interesting.

                              A quick off-topic question: what do you do about repetitive tests? Do you
                              refactor them, too? I find that many tests end up being repetitive.

                              Thanks,
                              Brandon

                              > -----Original Message-----
                              > From: extremeprogramming@yahoogroups.com
                              > [mailto:extremeprogramming@yahoogroups.com] On Behalf Of Adam Sroka
                              > Sent: Wednesday, December 31, 2008 4:08 PM
                              > To: extremeprogramming@yahoogroups.com
                              > Subject: Re: [XP] TDD - Planning Ahead
                              >
                              > On Wed, Dec 31, 2008 at 12:07 PM, Dale Emery <dale@...
                              > <mailto:dale%40dhemery.com> > wrote:
                              > > Hi Brandon,
                              > >
                              > > Technically, you could go on faking it indefinitely, but you know you
                              > mean
                              > >> to actually do something else with it. For instance if I have a
                              > method
                              > >> that
                              > >> needs to return a count of something, I could return the expected
                              > number,
                              > >> but I know I really want the count, no matter what it is.
                              > >
                              > > That's what makes the "refactor" step so important. As you write the
                              > code
                              > > to pass your second or third or fourth test, you will likely
                              > introduce some
                              > > repetition or pattern or awkwardness into the code. Once the code
                              > passes
                              > > the tests, you'll notice that smell and refactor the code to be
                              > simpler.
                              > >
                              > > One trick I've learned is how to select the next test: Select one
                              > that
                              > > nudges the existing code toward a /little/ more ugliness. Then
                              > refactor the
                              > > ugliness out. With counts, I find that tests for zero, one, and many
                              > items
                              > > usually is enough to force just the right amount of ugliness, which
                              > in turn
                              > > forces the code toward its final form (loop, internally-stored count,
                              > > regular expression). That's three tests, which you can write and pass
                              > > within a few minutes.
                              > >
                              >
                              > Ditto all of the above.
                              >
                              > You have to know when you are close enough to the "real" answer that
                              > you can get there with one small step. That is the trick. It is true
                              > that you could go on faking it for a long time. But, as you said the
                              > goal is to get to the "real" thing. You just want to lower the
                              > resistance enough that you can get there with a small, logical, easily
                              > tested change. These are the "baby steps" that Kent Beck talks about.
                              >
                              > BTW, a similar method has been described as "triangulation". I'm not
                              > sure where the term originates, but Dave Astels used it in his book.
                              > Basically, you write two tests that expect two different values from
                              > the same code. When you write the second implementation to return the
                              > second value you will have created duplication which you can refactor
                              > out.
                              >
                              > Another trick is to look for a value that wouldn't naturally come out
                              > of the code and test for that in order to force yourself to get the
                              > "real" value. This is the approach that I prefer when using mocks. For
                              > example, if my initial test checks for zero (or null, nil, undef,
                              > whatever your language returns by default) then I might mock something
                              > to produce the value "5" and expect that answer in my test. Then I can
                              > set my implementation to get it from the right place. You could argue
                              > that it is simpler to just return the hardcoded value, but this is a
                              > small enough step that I am comfortable.
                              >
                              >
                              >
                            • Adam Sroka
                              On Wed, Dec 31, 2008 at 1:34 PM, Brandon Olivares ... Yes, you absolutely can and should refactor tests. Just like the code that they test, tests should be
                              Message 14 of 22 , Dec 31, 2008
                              • 0 Attachment
                                On Wed, Dec 31, 2008 at 1:34 PM, Brandon Olivares
                                <programmer2188@...> wrote:
                                > Hi,
                                >
                                > Thanks so much. This all really helps.
                                >
                                > It is difficult, but I am really liking it so far. I don't know yet how this
                                > class will end up implementing the needed functionality, though. I just know
                                > how it passes the tests so far. Quite interesting.
                                >
                                > A quick off-topic question: what do you do about repetitive tests? Do you
                                > refactor them, too? I find that many tests end up being repetitive.
                                >

                                Yes, you absolutely can and should refactor tests. Just like the code
                                that they test, tests should be refactored when they are passing yet
                                there is unnecessary duplication. Obviously, after you refactor a test
                                it should still pass.
                              • Dale Emery
                                Hi Brandon, A quick off-topic question: what do you do about repetitive tests? Do you ... Yes, I factor common code into helper functions with expressive
                                Message 15 of 22 , Dec 31, 2008
                                • 0 Attachment
                                  Hi Brandon,

                                  A quick off-topic question: what do you do about repetitive tests? Do you
                                  > refactor them, too? I find that many tests end up being repetitive.


                                  Yes, I factor common code into helper functions with expressive names, so
                                  that each test reads more concisely and meaningfully. Sometimes I notice
                                  patterns about which tests use which helper functions, and that can nudge me
                                  to split or combine fixtures.

                                  My goal: Make the tests readable, understandable, and changeable. For some
                                  reason I tend to go less far in refactoring tests than I do in refactoring
                                  the working code, but I do put a good deal of attention to making my tests
                                  clean and readable.

                                  Dale

                                  --
                                  Dale Emery, Consultant
                                  Inspiring Leadership for Software People
                                  Web: http://dhemery.com
                                  Weblog: http://cwd.dhemery.com


                                  [Non-text portions of this message have been removed]
                                • Ron Jeffries
                                  Hello, Brandon. On Wednesday, December 31, 2008, at 6:36:29 AM, ... I think all the time. I code only what I need right now, in some simple and clear way. Ron
                                  Message 16 of 22 , Jan 1, 2009
                                  • 0 Attachment
                                    Hello, Brandon. On Wednesday, December 31, 2008, at 6:36:29 AM,
                                    you wrote:

                                    > I'm writing a class now that I'm really not sure how I'm going to implement
                                    > certain parts. Of course, I'm writing each test before implementing it.
                                    > I've read before about not thinking too far in the future, and only writing
                                    > the code that makes the test pass. How literally do you take this? Is it
                                    > wise to try to look in the future to find the best implementation of the
                                    > class, or literally only write as much as is needed to make the test pass
                                    > right now, even if it will be changed later?

                                    I think all the time. I code only what I need right now, in some
                                    simple and clear way.

                                    Ron Jeffries
                                    www.XProgramming.com
                                    www.xprogramming.com/blog
                                    The rules are ways of thinking, not ways to avoid thinking.
                                  • Arnaud Bailly
                                    Hello, One thing I found useful is to establish some sort of plan through a list of tests that I order and implement one at a time. Like all plans, it should
                                    Message 17 of 22 , Jan 1, 2009
                                    • 0 Attachment
                                      Hello,
                                      One thing I found useful is to establish some sort of plan through a
                                      list of tests that I order and implement one at a time. Like all plans,
                                      it should be following you, not followed by the letter: changing the
                                      order, removing unnecessary or duplicate tests, adding some more
                                      tests...

                                      And yes, you have to think all the time, because design and code is
                                      one and the same thing.

                                      Regards,
                                      --
                                      Arnaud Bailly, PhD
                                      OQube - Software Engineering

                                      web> http://www.oqube.com
                                    • Phlip
                                      ... Right: Then you can sort the list and do the items from easy to hard. Subsequent tests can reuse fixtures invented for the simpler tests. The goal is each
                                      Message 18 of 22 , Jan 1, 2009
                                      • 0 Attachment
                                        Arnaud Bailly wrote:

                                        > One thing I found useful is to establish some sort of plan through a
                                        > list of tests that I order and implement one at a time. Like all plans,
                                        > it should be following you, not followed by the letter: changing the
                                        > order, removing unnecessary or duplicate tests, adding some more
                                        > tests...

                                        Right: Then you can sort the list and do the items from easy to hard. Subsequent
                                        tests can reuse fixtures invented for the simpler tests.

                                        The goal is each test failure tells you the next valuable thing to do to the
                                        code, in the right order. So even within one test case you can write a missing
                                        method, then write a few assertions, listed in the order you ought to pass them
                                        as you build that method.

                                        --
                                        Phlip
                                      • Keith Ray
                                        If the tests have a lot of duplication testing an aspect of a class, that can mean that you should extract a class to represent that aspect. Now you have two
                                        Message 19 of 22 , Jan 1, 2009
                                        • 0 Attachment
                                          If the tests have a lot of duplication testing an aspect of a class,
                                          that can mean that you should extract a class to represent that
                                          aspect. Now you have two classes and I would move some of the tests to
                                          a test suite for that new class and remove duplication in them.

                                          Sent from my iPhone

                                          On Dec 31, 2008, at 1:34 PM, "Brandon Olivares" <programmer2188@...
                                          > wrote:

                                          > Hi,
                                          >
                                          > Thanks so much. This all really helps.
                                          >
                                          > It is difficult, but I am really liking it so far. I don't know yet
                                          > how this
                                          > class will end up implementing the needed functionality, though. I
                                          > just know
                                          > how it passes the tests so far. Quite interesting.
                                          >
                                          > A quick off-topic question: what do you do about repetitive tests?
                                          > Do you
                                          > refactor them, too? I find that many tests end up being repetitive.
                                          >
                                          > Thanks,
                                          > Brandon
                                          >
                                          >> -----Original Message-----
                                          >> From: extremeprogramming@yahoogroups.com
                                          >> [mailto:extremeprogramming@yahoogroups.com] On Behalf Of Adam Sroka
                                          >> Sent: Wednesday, December 31, 2008 4:08 PM
                                          >> To: extremeprogramming@yahoogroups.com
                                          >> Subject: Re: [XP] TDD - Planning Ahead
                                          >>
                                          >> On Wed, Dec 31, 2008 at 12:07 PM, Dale Emery <dale@...
                                          >> <mailto:dale%40dhemery.com> > wrote:
                                          >>> Hi Brandon,
                                          >>>
                                          >>> Technically, you could go on faking it indefinitely, but you know
                                          >>> you
                                          >> mean
                                          >>>> to actually do something else with it. For instance if I have a
                                          >> method
                                          >>>> that
                                          >>>> needs to return a count of something, I could return the expected
                                          >> number,
                                          >>>> but I know I really want the count, no matter what it is.
                                          >>>
                                          >>> That's what makes the "refactor" step so important. As you write the
                                          >> code
                                          >>> to pass your second or third or fourth test, you will likely
                                          >> introduce some
                                          >>> repetition or pattern or awkwardness into the code. Once the code
                                          >> passes
                                          >>> the tests, you'll notice that smell and refactor the code to be
                                          >> simpler.
                                          >>>
                                          >>> One trick I've learned is how to select the next test: Select one
                                          >> that
                                          >>> nudges the existing code toward a /little/ more ugliness. Then
                                          >> refactor the
                                          >>> ugliness out. With counts, I find that tests for zero, one, and many
                                          >> items
                                          >>> usually is enough to force just the right amount of ugliness, which
                                          >> in turn
                                          >>> forces the code toward its final form (loop, internally-stored
                                          >>> count,
                                          >>> regular expression). That's three tests, which you can write and
                                          >>> pass
                                          >>> within a few minutes.
                                          >>>
                                          >>
                                          >> Ditto all of the above.
                                          >>
                                          >> You have to know when you are close enough to the "real" answer that
                                          >> you can get there with one small step. That is the trick. It is true
                                          >> that you could go on faking it for a long time. But, as you said the
                                          >> goal is to get to the "real" thing. You just want to lower the
                                          >> resistance enough that you can get there with a small, logical,
                                          >> easily
                                          >> tested change. These are the "baby steps" that Kent Beck talks about.
                                          >>
                                          >> BTW, a similar method has been described as "triangulation". I'm not
                                          >> sure where the term originates, but Dave Astels used it in his book.
                                          >> Basically, you write two tests that expect two different values from
                                          >> the same code. When you write the second implementation to return the
                                          >> second value you will have created duplication which you can refactor
                                          >> out.
                                          >>
                                          >> Another trick is to look for a value that wouldn't naturally come out
                                          >> of the code and test for that in order to force yourself to get the
                                          >> "real" value. This is the approach that I prefer when using mocks.
                                          >> For
                                          >> example, if my initial test checks for zero (or null, nil, undef,
                                          >> whatever your language returns by default) then I might mock
                                          >> something
                                          >> to produce the value "5" and expect that answer in my test. Then I
                                          >> can
                                          >> set my implementation to get it from the right place. You could argue
                                          >> that it is simpler to just return the hardcoded value, but this is a
                                          >> small enough step that I am comfortable.
                                          >>
                                          >>
                                          >>
                                          >
                                          >
                                          > ------------------------------------
                                          >
                                          > To Post a message, send it to: extremeprogramming@...
                                          >
                                          > To Unsubscribe, send a blank message to: extremeprogramming-unsubscribe@...
                                          >
                                          > ad-free courtesy of objectmentor.comYahoo! Groups Links
                                          >
                                          >
                                          >
                                        • Brandon Olivares
                                          ... Can you explain a bit what you mean? I don t know if I see your point there. To me, testing has a lot of duplication. I mean you are testing all of the
                                          Message 20 of 22 , Jan 1, 2009
                                          • 0 Attachment
                                            > -----Original Message-----
                                            > From: extremeprogramming@yahoogroups.com
                                            > [mailto:extremeprogramming@yahoogroups.com] On Behalf Of Keith Ray
                                            > Sent: Thursday, January 01, 2009 2:02 PM
                                            > To: extremeprogramming@yahoogroups.com
                                            > Cc: <extremeprogramming@yahoogroups.com>
                                            > Subject: Re: [XP] TDD - Planning Ahead
                                            >
                                            > If the tests have a lot of duplication testing an aspect of a class,
                                            > that can mean that you should extract a class to represent that
                                            > aspect. Now you have two classes and I would move some of the tests to
                                            > a test suite for that new class and remove duplication in them.
                                            >

                                            Can you explain a bit what you mean? I don't know if I see your point there.
                                            To me, testing has a lot of duplication. I mean you are testing all of the
                                            fringe cases of a method, so you'll be calling each one quite a few times.

                                            Thanks,
                                            Brandon

                                            Brandon
                                          • Keith Ray
                                            I have an example of a large method in my article here: Pretend the large method in
                                            Message 21 of 22 , Jan 2, 2009
                                            • 0 Attachment
                                              I have an example of a large method in my article here:
                                              <http://www.stickyminds.com/BetterSoftware/magazine.asp?fn=cifea&id=75>

                                              Pretend the large method in Figure 1 was created by TDD with
                                              insufficient refactoring. There would be a large number of tests for
                                              that method, reflecting the large amount of behavior in that method.
                                              The article describes several extract methods that can be done. And
                                              points out some Move Method refactorings to correct a Feature Envy
                                              code smell -- moving some methods out of the nsAccessibleText class
                                              into the class nsISelectionController.

                                              If you were test-driving nsAccessibleText, and now fixing code smells,
                                              you might have created the class nsISelectionController just to move
                                              the methods into it. I would move some of those tests that drove the
                                              creation of the code that we did Move Method on into a test-suite for
                                              nsISelectionController.

                                              As the article continues, we observe that BackupOldSettings and
                                              RestoreOldSettings are being used to save and restore some data
                                              belonging to the class nsISelectionController, but the class doing
                                              this work is nsAccessibleText. This is an Inappropriate Intimacy code
                                              smell, and one way to fix it is to use the Memento design pattern.
                                              Again we have created a new class [possibly an "inner class"], and we
                                              can maybe move some tests from the original class test-suite to
                                              another one.

                                              And we observe that several methods have two parameters that always go
                                              together - aStartOffsetand and aEndOffset. Data Clump code smell. Move
                                              those into a new "Range" class and extract and move methods like
                                              "Length" into that class and again there could be an opportunity to
                                              not only remove duplication in the code, but also in tests that may
                                              have been testing that several methods computed length or other
                                              functionality that belongs in Range.

                                              The examples from this article came from un-tdd'ed legacy code with
                                              very few unit tests, but I have seen people new to TDD ignore the same
                                              code smells when test-driving a class. The code-smells were not just
                                              in the production code, but also in the extreme duplication of the
                                              test code, and the fixes were to remove duplication in both the
                                              production code (by extracting methods and classes) and the tests.

                                              Jay Flowers wrote a blog entry about TDD smells here
                                              <http://jayflowers.com/WordPress/?p=89>
                                              "Looking at this now I think I went to great lengths to make the
                                              test look simple, to cover up the complexity [...]"
                                              "So what grabs you by the nose and leads to tight coupling? I
                                              don't know yet. Maybe looking at motivations will help. I was
                                              motivated to perform this refactoring because [...] I think we can
                                              pull these smells out:
                                              * Slow Tests
                                              * Lengthy SetUp
                                              * Lengthy TearDown
                                              * Asynchronous Test
                                              * Party Crasher
                                              "Two of those smells have already been identified by Gerard and are
                                              documented in xUnit Patterns."

                                              On Thu, Jan 1, 2009 at 12:27 PM, Brandon Olivares
                                              <programmer2188@...> wrote:
                                              >
                                              >
                                              >> -----Original Message-----
                                              >> From: extremeprogramming@yahoogroups.com
                                              >> [mailto:extremeprogramming@yahoogroups.com] On Behalf Of Keith Ray
                                              >> Sent: Thursday, January 01, 2009 2:02 PM
                                              >> To: extremeprogramming@yahoogroups.com
                                              >> Cc: <extremeprogramming@yahoogroups.com>
                                              >> Subject: Re: [XP] TDD - Planning Ahead
                                              >>
                                              >> If the tests have a lot of duplication testing an aspect of a class,
                                              >> that can mean that you should extract a class to represent that
                                              >> aspect. Now you have two classes and I would move some of the tests to
                                              >> a test suite for that new class and remove duplication in them.
                                              >>
                                              >
                                              > Can you explain a bit what you mean? I don't know if I see your point there.
                                              > To me, testing has a lot of duplication. I mean you are testing all of the
                                              > fringe cases of a method, so you'll be calling each one quite a few times.
                                              >
                                              > Thanks,
                                              > Brandon
                                              >
                                              > Brandon
                                              >
                                              >
                                              > ------------------------------------
                                              >
                                              > To Post a message, send it to: extremeprogramming@...
                                              >
                                              > To Unsubscribe, send a blank message to: extremeprogramming-unsubscribe@...
                                              >
                                              > ad-free courtesy of objectmentor.comYahoo! Groups Links
                                              >
                                              >
                                              >
                                              >



                                              --
                                              C. Keith Ray, IXP Coach, Industrial Logic, Inc.
                                              http://industriallogic.com 866-540-8336 (toll free)
                                              Groove with our Agile Greatest Hits: http://www.industriallogic.com/elearning/
                                              http://agilesolutionspace.blogspot.com/
                                            • Brandon Olivares
                                              Keith, Thanks a lot for the links. The class I was having trouble with is just about finished, and the design is completely different than I had originally
                                              Message 22 of 22 , Jan 2, 2009
                                              • 0 Attachment
                                                Keith,

                                                Thanks a lot for the links.

                                                The class I was having trouble with is just about finished, and the design is completely different than I had originally planned, before I decided to try this approach. This design that has come out of it though is much simpler and cleaner than what I was thinking of. It's definitely something to get used to, but I like it.

                                                Brandon

                                                > -----Original Message-----
                                                > From: extremeprogramming@yahoogroups.com
                                                > [mailto:extremeprogramming@yahoogroups.com] On Behalf Of Keith Ray
                                                > Sent: Friday, January 02, 2009 11:27 AM
                                                > To: extremeprogramming@yahoogroups.com
                                                > Subject: Re: [XP] TDD - Planning Ahead
                                                >
                                                > I have an example of a large method in my article here:
                                                > <http://www.stickyminds.com/BetterSoftware/magazine.asp?fn=cifea&id=75
                                                > <http://www.stickyminds.com/BetterSoftware/magazine.asp?fn=cifea&id=75>
                                                > >
                                                >
                                                > Pretend the large method in Figure 1 was created by TDD with
                                                > insufficient refactoring. There would be a large number of tests for
                                                > that method, reflecting the large amount of behavior in that method.
                                                > The article describes several extract methods that can be done. And
                                                > points out some Move Method refactorings to correct a Feature Envy
                                                > code smell -- moving some methods out of the nsAccessibleText class
                                                > into the class nsISelectionController.
                                                >
                                                > If you were test-driving nsAccessibleText, and now fixing code smells,
                                                > you might have created the class nsISelectionController just to move
                                                > the methods into it. I would move some of those tests that drove the
                                                > creation of the code that we did Move Method on into a test-suite for
                                                > nsISelectionController.
                                                >
                                                > As the article continues, we observe that BackupOldSettings and
                                                > RestoreOldSettings are being used to save and restore some data
                                                > belonging to the class nsISelectionController, but the class doing
                                                > this work is nsAccessibleText. This is an Inappropriate Intimacy code
                                                > smell, and one way to fix it is to use the Memento design pattern.
                                                > Again we have created a new class [possibly an "inner class"], and we
                                                > can maybe move some tests from the original class test-suite to
                                                > another one.
                                                >
                                                > And we observe that several methods have two parameters that always go
                                                > together - aStartOffsetand and aEndOffset. Data Clump code smell. Move
                                                > those into a new "Range" class and extract and move methods like
                                                > "Length" into that class and again there could be an opportunity to
                                                > not only remove duplication in the code, but also in tests that may
                                                > have been testing that several methods computed length or other
                                                > functionality that belongs in Range.
                                                >
                                                > The examples from this article came from un-tdd'ed legacy code with
                                                > very few unit tests, but I have seen people new to TDD ignore the same
                                                > code smells when test-driving a class. The code-smells were not just
                                                > in the production code, but also in the extreme duplication of the
                                                > test code, and the fixes were to remove duplication in both the
                                                > production code (by extracting methods and classes) and the tests.
                                                >
                                                > Jay Flowers wrote a blog entry about TDD smells here
                                                > <http://jayflowers.com/WordPress/?p=89
                                                > <http://jayflowers.com/WordPress/?p=89> >
                                                > "Looking at this now I think I went to great lengths to make the
                                                > test look simple, to cover up the complexity [...]"
                                                > "So what grabs you by the nose and leads to tight coupling? I
                                                > don't know yet. Maybe looking at motivations will help. I was
                                                > motivated to perform this refactoring because [...] I think we can
                                                > pull these smells out:
                                                > * Slow Tests
                                                > * Lengthy SetUp
                                                > * Lengthy TearDown
                                                > * Asynchronous Test
                                                > * Party Crasher
                                                > "Two of those smells have already been identified by Gerard and are
                                                > documented in xUnit Patterns."
                                                >
                                                > On Thu, Jan 1, 2009 at 12:27 PM, Brandon Olivares
                                                > <programmer2188@... <mailto:programmer2188%40gmail.com> > wrote:
                                                > >
                                                > >
                                                > >> -----Original Message-----
                                                > >> From: extremeprogramming@yahoogroups.com
                                                > <mailto:extremeprogramming%40yahoogroups.com>
                                                > >> [mailto:extremeprogramming@yahoogroups.com
                                                > <mailto:extremeprogramming%40yahoogroups.com> ] On Behalf Of Keith Ray
                                                > >> Sent: Thursday, January 01, 2009 2:02 PM
                                                > >> To: extremeprogramming@yahoogroups.com
                                                > <mailto:extremeprogramming%40yahoogroups.com>
                                                > >> Cc: <extremeprogramming@yahoogroups.com
                                                > <mailto:extremeprogramming%40yahoogroups.com> >
                                                > >> Subject: Re: [XP] TDD - Planning Ahead
                                                > >>
                                                > >> If the tests have a lot of duplication testing an aspect of a class,
                                                > >> that can mean that you should extract a class to represent that
                                                > >> aspect. Now you have two classes and I would move some of the tests
                                                > to
                                                > >> a test suite for that new class and remove duplication in them.
                                                > >>
                                                > >
                                                > > Can you explain a bit what you mean? I don't know if I see your point
                                                > there.
                                                > > To me, testing has a lot of duplication. I mean you are testing all
                                                > of the
                                                > > fringe cases of a method, so you'll be calling each one quite a few
                                                > times.
                                                > >
                                                > > Thanks,
                                                > > Brandon
                                                > >
                                                > > Brandon
                                                > >
                                                > >
                                                > > ------------------------------------
                                                > >
                                                > > To Post a message, send it to: extremeprogramming@...
                                                > <mailto:extremeprogramming%40eGroups.com>
                                                > >
                                                > > To Unsubscribe, send a blank message to: extremeprogramming-
                                                > unsubscribe@... <mailto:extremeprogramming-
                                                > unsubscribe%40eGroups.com>
                                                > >
                                                > > ad-free courtesy of objectmentor.comYahoo! Groups Links
                                                > >
                                                > >
                                                > >
                                                > >
                                                >
                                                > --
                                                > C. Keith Ray, IXP Coach, Industrial Logic, Inc.
                                                > http://industriallogic.com <http://industriallogic.com> 866-540-8336
                                                > (toll free)
                                                > Groove with our Agile Greatest Hits:
                                                > http://www.industriallogic.com/elearning/
                                                > <http://www.industriallogic.com/elearning/>
                                                > http://agilesolutionspace.blogspot.com/
                                                > <http://agilesolutionspace.blogspot.com/>
                                                >
                                                >
                                                >
                                              Your message has been successfully submitted and would be delivered to recipients shortly.