"Copy and Paste Programming" - the TDD way.

Setting the scene...
You are building your second large TDD project for a new client.  Some of the requirements are almost identical to the last TDD project.  Management is aware of this and expects some form of code reuse to occur that will save budget and time.  The functionality required is separated well in the code and design but is still tied to the business tier in deployment and cannot be easily isolated in binary form.

Options tried to date:

  1. Copy and paste all tests and production code of interest.  Then tweak the code till everything runs green.  Run ... 15 tests fail ... tweak ... run ... 14 tests fail ... etc. 
    Pros: Simple to copy
    Cons:  Very negative process - lots and lots of failures - start doing anything to make it pass.  Feels like the haphazard development of old.  You can easily miss a requirement or add something unnecessary.  Test quality tends to be low and tests are poorly understood.  Takes a long time to get to green.
  2. Copy and paste one test, fail, paste production code, pass.  Repeat and stir.
    Pros:  Simple process.
    Cons: Test order might not match original development and therefore may not flow with available functionality.  Difficult to isolate relevant production code each time.  Process does not always flow logically.
  3. Start from scratch!  Write a test, fail, add code, pass, refactor.  Check old tests for ideas and check old production code for implementation when stumped.  Learn from the old, improve with the new.
    Pros: Our beloved TDD process with all the benefits of the process.  Gives an opportunity to review the old code while flowing through the new.  Feels quicker and has a definite sense of moving forward.
    Cons: Should be slower and could suffer from "reinventing the wheel".

Discussion
The biggest benefit of TDD is the process.  Reusing past successes while deviating from the TDD process appears to be counter productive since the process *is* the benefit.  It helps to keep the pair moving forward and helps them to stay focused.  The copy and paste techniques quickly returned to the hack it without a technique ways of old.  Worse still, they did not bring the confidence of the red/green cycle.

(Better separation of the logic into deployable units may have made the process easier but would have involved more setup and deployment work for the initial client.)

Conclusion
This was a surprising exercise and did not produce the results that one would probably expect.  Perhaps "copy and paste" reuse in TDD is like trying to eat the elephant all at once?  (HowDoYouEatAnElephant)

Have you had similar experiences?  How did you tackle them?  What would you do differently?

2 Comments

  • I would only port over a contained unit, such as a class or set of classes, and bring over all the tests (which should be green either immediately or with a few simple code changes). If there were too many differences in requirements, bringing the code over and tweaking would waste any benefits.



    And the benefits aren't in the code anyway, they are in the knowledge you gained while programming them. I would bet that the second time a pair, or even a single developer, implemented similar requirements that the process would go much more quickly even IF all the code was rewritten.



    I can't remember where I read the following, but it was accurate. Say you write a small program in 2 days that you don't check into source code control (gasp!). If you have to rewrite it, is it going to take you all 2 days? Probably not, you can remember the end code, and you don't have to repeat all those dead-ends you checked out, the little bug that took you 2 hours to figure out, etc. Maybe it only takes 1 day this time. Is that still reuse? I would say yes! YMMV. :)

  • The functionality we are trying to bring over is tied between login authentication, account management and second factor (security token) authentication. I kept feeling that there was perhaps a better way we could have isolated our class functionality to make your "class by class" suggestion easier. Maybe our classes do too much and should be separated more?



    Thanks for the ideas! I agree that working through a problem once before still fosters "reuse" but it is hard to explain to a client.

Comments have been disabled for this content.