On Nov 29, 3:33 am, "Emanuele D'Arrigo" <[EMAIL PROTECTED]> wrote: > On Nov 29, 12:35 am, Fuzzyman <[EMAIL PROTECTED]> wrote: > > > Your experiences are one of the reasons that writing the tests *first* > > can be so helpful. You think about the *behaviour* you want from your > > units and you test for that behaviour - *then* you write the code > > until the tests pass. > > Thank you Michael, you are perfectly right in reminding me this. At > this particular point in time I'm not yet architecturally foresighted > enough to be able to do that. While I was writing the design documents > I did write the list of methods each object would have needed and from > that description theoretically I could have made the tests first. In > practice, while eventually writing the code for those methods, I've > come to realize that there was a large amount of variance between what > I -thought- I needed and what I -actually- needed. So, had I written > the test before, I would have had to rewrite them again. That been > said, I agree that writing the tests before must be my goal. I hope > that as my experience increases I'll be able to know beforehand the > behaviors I need from each method/object/module of my applications. > One step at the time I'll get there... =) >
Personally I find writing the tests an invaluable part of the design process. It works best if you do it 'top-down'. i.e. You have a written feature specification (a user story) - you turn this into an executable specification in the form of a functional test. Next to mid level unit tests and downwards - so your tests become your design documents (and the way you think about design), but better than a document they are executable. So just like code conveys intent so do the tests (it is important that tests are readable). For the situation where you don't really know what the API should look like, Extreme Programming (of which TDD is part) includes a practise called spiking. I wrote a bit about that here: http://www.voidspace.org.uk/python/weblog/arch_d7_2007_11_03.shtml#e867 Mocking can help reduce the number of code paths you need to test for necessarily complex code. Say you have a method that looks something like: def method(self): if conditional: # do stuff else: # do other stuff # then do more stuff You may be able to refactor this to look more like the following def method(self): if conditional: self.method2() else: self.method3() self.method4() You can then write unit tests that *only* tests methods 2 - 4 on their own. That code is then tested. You can then test method by mocking out methods 2 - 4 on the instance and only need to test that they are called in the right conditions and with the right arguments (and you can mock out the return values to test that method handles them correctly). Mocking in Python is very easy, but there are plenty of mock libraries to make it even easier. My personal favourite (naturally) is my own: http://www.voidspace.org.uk/python/mock.html All the best, Michael -- http://www.ironpythoninaction.com/ > Manu -- http://mail.python.org/mailman/listinfo/python-list