test.ical.ly | getting the web by the balls

Nov/10

24

[Question] How can you develop test driven when you don’t know where you’re going in the first place?

I’ve got this one question puzzling me for quite some time now and I got to get it off my chest.

An just to make sure there are no misunderstandings: I am not about to question TDD!

I am merely asking for help to find my way to do it properly..

So what is Test Driven Development?

Well it comes down to this:

  • You write a test first and then implement until it no longer fails.
  • You do this in a circle and start over and over again until all requirements are represented by a test which passes.
  • There is an inner and an outer circle. The outer circle is a functional test and the inner is a unit test.

This sounds simple enough assuming that there is a clear vision of where to go.

But how often do you find yourself in a position where you are not only responsible for implementing a requirement but also for its specification?

Just recently I worked on a symfony plugin called gjPositionsPlugin and the only requirement was:

Users should be able to place page elements and contents on a page in one easy to use tool.

So I started building that tool and during the time I refactored a lot. And with refactoring I mean redesigning. The result (or its current state) is completely different from what I started with.

I started with a simple module which grew into a complictaed module which became incredibly complex which I refactored into form classes which grew completely out of proportion which I then realised could be simplified by creating doctrine behaviours which brought me to the idea to create an admin theme which gave me the opportunity to move a lot of its complexity towards the jquery site, … well, you get the idea.

This one very abstract requirement still applies but the details were not clear in the beginning. In fact it was the process of coding that led me to the specific requirements.

And I can not for the life of me imagine how I could’ve done all that with writing tests beforehand.

Also I keep thinking about all those tests I would have binned along the way. How much time would I have spent on writing tests that would not survive until the end?

I am sure this situation and those questions present themselves to most of you who tried TDD. How did you go pass that? What’s the trick?

· · · · · · ·



  • http://mrclay.org/ Steve Clay

    Good point. There’s definitely a difference between development with a clear spec and brainstorming in code to find a smart design without explicit goals. “Proper” TDD would produce a huge amount of drag to the latter process.

    I feel that considering how I’d unit test code while I write it makes the biggest difference, whether or not the tests come to exist. Once you grok DI/TDD well enough, writing highly testable code almost comes naturally.

  • http://christof.damian.net/ Christof

    For most of my project I tend to write the code first and test later. I like brainstorming and designing in code instead of paper and write a lot of code that will later be discarded. Writing tests at the same time would get in the way of my flow.
    This is especially true for code which has any kind of GUI, because that tends to be horrible to test anyway.
    But this goes the other way too: when I write code with complex algorithms or data models which tends to be in models or libraries, then I will write the test first because there is no other way to really know if it is working. It also forces you into writing even cleaner APIs.

  • Crafty_Shadow

    In all honesty, vanilla TDD is not meant for GUI (selenium) or functional, it works good for unit tests.
    And even then, it isn’t really the best option. What I have found to work reasonably well for me is to first outline the API – just shape the classes, their methods, parameters and return values with, say, PHPDoc and envision how the whole thing “ticks”. Then I can start writing my tests and implementation. I get both the pleasure of developing the structure in code (or is it pseudo-code at that stage?) plus the robustness of the test->fail->code->pass methodology.

    Best of both worlds?

  • http://devfactor.blogspot.com Richard

    I don’t think TDD should be applied to agile projects at all. It can be done but will it be effective? I don’t think so.

  • http://www.glatter-gotz.com Henning Glatter-Gotz

    The process you described in your post sounds a lot like prototyping or R&D to me and I would agree with Steve, that TDD would maybe get in the way of your progress.
    So, while TDD might not work well here, I think unit testing itself still has its value and place and can actually speed up your process when applied to only specific areas.
    In situations like this, when you end up with a working prototype which you arrived at through many iterations, chances are you want to revisit your design anyway because you now have a really good grasp of the problem and might want to implement it differently and will have less churn on that last iteration.
    The danger with this is that the working prototype goes into production because there is no time for another iteration.

    When I have been in similar situations, I have simply implemented unit tests at the end and only in the areas that made me most uncomfortable. This should not be too hard since you write your code with testing in mind anyway.
    While this is not great, it is (my) reality.

    Great subject matter!! Thanks!

  • http://devfactor.blogspot.com Richard

    IMHO Henning’s solution is the best one in a situation where project is evolving rapidly and rewriting tests would only consume precious time. Testing the most crucial parts of the code should be enough in most cases.

  • http://test.ical.ly Christian

    @all thanks for the discussion so far! at least now I know that I am not the only one who has problems with the combination of TDD and prototyping. :)
    I also agree with Henning that unit tests should in this case be added afterwards where the most uncomfortable areas take precedence.

  • http://www.zalas.eu Kuba

    @Christian, you’re for sure not alone with this kind of problems. Here are my three cents.

    In case I’m not sure about the architecture or feature I’d start with a prototype.

    Prototype is created to verify the approach or requirements. It should never reach the production. As soon as it fulfills its purpose it has to be deleted. Prototype is created quickly and it can be the most awful code ever created. It doesn’t really matter as it’s gonna be deleted anyway.

    After building a prototype you should know enough to start writing a production code with nice and clean test driven approach.

  • http://test.ical.ly Christian

    @Kuba Interesting approach! Thanks for sharing.
    It’s just hard to find the right spot to stop prototyping and start with the real implementation in the real world. But that is probably a grey area. ;)

  • Matthias

    IMHO you are talking too much about “code”. In your case I would say you need a concept first. It’s a better approach to close the IDE and open the mockup editor first and draw some use cases. This way you can get a much better idea what code you need to write.

  • http://test.ical.ly Christian

    @Matthias for anything UI related I agree completely but for low level things like caching or the like this will not be possible. This was in fact the case with sfImageTransformExtraPlugin which has no UI at all.

<<

>>

Theme Design by devolux.nh2.me