Friday, May 4, 2012

Dead-simple introduction to TDD (Test driven development)


Even though there are plenty introductions to TDD (even in PHP, my primary programming language now), I'm feeling a bit stuck about it.



My friend introduced me TDD a while ago, but I wasn't actually able to understand it - what's the point in writing tests to everything first - even the simplest tasks - when in the end, it looks it's more efficient to test only if something doesn't work, although it might be much harder to locate the bug (this could be solved through VCS, no?).



So is there any introduction, with dead-simple examples and arguments behind "pros"?



Something like "yeah, it's better, because you have better design - look at this example..."



Also, it would be nice if this simple examples were in php (should be possible) or in as3 (idk...).



Thanks.



EDIT: I understand that you create "test" and then the function, that should pass the test. But how you say to language, what results should it have? To me it looks that you do some function... debug it (the same way as you debug in no test driven dev.) and call it test and do it again... Or?



EDIT 2: Oh... Also, is this applicable to MVC approach? Or rather, CodeIgniter Newbie MVC? :D



EDIT 3: Read a bunch of posted and googled advices, plans, ways and tutorials. I am still not entirely into TDD - I mostly have pretty good visualisation and I think (hope?) I write pretty maintable code, so i still see it as an extra work...


Source: Tips4all

5 comments:

  1. One of the reasons why this is an effective means to develop is not just writing tests for new code, but those tests remain and are run against existing code, and thus form a regression test.

    That means that as your project develops, people take it over or contribute, and it changes, the tests continue to determine whether your code is still running as expected.

    The code that you've written that is sufficiently simple not to have to test may well expand and become more complex over time (to take care of edge cases, new requirements etc.). If you're still running your tests (and you should be -via continuous integration or other means) they'll confirm that however much refactoring you do, the code still works as it did on day 1.

    ReplyDelete
  2. I found the tutorial on Simpletest (PHP) to be really useful. It was 'the TDD launchpad' for me.

    See: http://www.simpletest.org/en/start-testing.html

    I'd:


    Set aside a couple of hours
    Get a crude simpletest script working
    Open your mind - forget your current dev habits and ways of working for a brief time
    ...and just go with the flow - following the instructions and ALL the tutorials, all the way to the end, on the simpletest.org site


    Then - in the near future


    Start adopting the practices - but gradually. Don't try and do it all at once.
    Set up a test folder to sit with one of your projects and start adding a few test cases


    If you start doing the steps above now. By this time tomorrow you will definitely fully understand why TDD is so handy.

    UPDATE: A note about "1. Set aside a couple of hours" - this is probably the hardest thing to do. Because:


    If you are putting out feelers to consider the benefits of TDD testing - its probably a symptom that:


    Your dev work is taking a long time.
    Which means you have no spare time to set aside to learn about TDD.
    Which means your dev work is taking a long time.
    Which means you have no spare time to set aside to learn about TDD.
    ....etc

    ReplyDelete
  3. Like most methodologies, you have to live it to understand what it's about, its limitations and its advantages. I recently had to write a client server application and after reading Kent Beck's seminal book (TDD by example) on the subject decided to try to use the methodology. I have a question regarding this which was commented on quite well by a lot of people over here but here is my summary.

    Cons


    It takes much longer. Atleast for me.
    It requires a lot of restructuring. This might be an advantage but there are pieces of code which I feel are convoluted just because I need to test pieces separately.
    You can get carried away with writing too many tests.
    You focus on the trees instead of the forest and have to actively guard yourself from losing focus.


    Pros


    No fear of rewriting pieces. This is probably the best part since I have a programatically verifiable specification of my requirements and it's easy to check after a coding session.
    Modularity. My functions are small, classes are well contained and modules are manageable. You do require some skill to avoid ravioli code though.
    Documentation. The tests and their names give me a good chance to structure the docs properly.
    Rethinking structure. Having to test each layer properly forces me to make solid decisions about what the pieces are and how they communicate. This led to much neater design and a much more understandable terminology.


    I'd recommend the book. It's a good read and what will give you the real deal on the methodology. It's not panacea (contrary to what the agile fanatics might say). You can't automatically not worry about the hard decisions just because you're doing TDD. It might seem a little unnatural since you have to think of tests upfront but that's just teething trouble. I'd stay away from "Dead simple" intros you find on the web because they probably miss out on important details.



    Update based on comment:
    Apropos, coming up with smart designs up front and changing them as you go along, that's how I worked till I tried this. The main differences were that the structure I came up with was smarter than usual since I had continuous refinable feedback (eg. you can't test this, it's too monolithic-break it down, these two things are conceptually separate - see how the tests are mashed up etc.) and that the 'dev' steps I took were small enough to throw away without the guilt of 'wasting time' creeping on me. Basically, the 'dev' stage was more systematic and I had verifiable ways to saying what I'd done (tests either pass or fail).

    ReplyDelete
  4. The point of writing the unit test first is that by doing this you are writing the specification of your software which seems very natural to do before writing the software itself. How will a given function respond to a given input? If you later decide to change the implementation you won't have to manually retest the whole application.

    ReplyDelete
  5. I personally find the article on wikipedia to be a pretty good introduction.

    ReplyDelete