I took a class last Saturday on Test-Driven Development (TDD)- an all day affair sponsored by the local dotnet user group. I enjoyed it very much and learned a few things, but perhaps not as much as I hoped. It was supposed to be very hands on. The room was full of geeks, perhaps 100 of us, nearly all with laptops, simultaneously typing away. At least for the morning anyway. I was not unschooled in test-driven development and in fact, I've read quite a bit, but I have not written tests before I start coding very often. This is of course a central tenet of test-driven development. You don't do design or much design. The design evolves as a result of the development and testing you do. The design in a sense is done during development of the tests. You come up with the perfect API in a test for code that is unwritten. In other words, if you want to write an application that calculates the time until retirement, you would figure out the API you would like to use in a test to verify correctness. So if you want days until retirement as a result, you might envision a very elegant API that gives you this results. It might be something like:
Person p = new Person();
p.Birthday = "7/12/1942";
int daysToRetire = p.DaysToRetirement();
Your test would then do some sort of Assert to verify that this calculated result is correct. I actually find this aspect of inventing the perfect API to be quite useful and one that I really believe has merit. It helps drive clean code.
The other aspect of TDD that I like is the idea that you elevate the importance of testing to the beginning of a project. This also has a lot going for it. It also keeps your code in a working state. You don't go off the rails for very long. You test often and if there are problems, you fix them right away. I do believe this will result in higher productivity in the long run. It may not seem so when you are doing it, but it will shave off time at the end when you are trying to figure out why something doesn't work.
Now if you've been reading what I've had to say about code generation, you may end up wondering like I am, how this all fits together - or does it? I do not believe TDD and code generation work that well together. You derive your design with TDD. In Code Generation, you start out with a working model that you then use to generate code. You must have a debugged design in CodeGen before you generate code. If you d0n't, you can generate a lot of buggy code, which is the wrong direction to go. We want clean code (generated quickly) that works - that is our goal.
So perhaps you can should use TDD in the development of your templates.
I see code generation in being useful in generating tests, and in fact I've used it this way. I've taken XML data sets that contain known inputs and outputs and created unit tests this way. It's a great use for it, but it is not TDD by definition. In TDD, you write a test, you make it fail, then you make it pass. This shows that the test itself is bug-free. Then you write the code implementation and now make the test pass. At this point, you have something very useful. You have a test that you can run very quickly to ensure code that you've now written still works - and continues to work as that test is run over and over and over again as development proceeds.
I am making an earnest effort to workout the best practices to create software, in particular software that solves engineering problems. I am amazed at the varied approaches in development software and it sure looks to me like there is a lot of confusion out there. I talk to a lot of developers and we all share some common goals. I believe this is best distilled down to quality and productivity. We want to develop great products quickly and many say you can't do that. I disagree with that idea. I believe it is possible to create quality products quickly and I also believe the best methodologies will get you there. The think I like about Code Generation is you can get quality code quickly. You can have an awesome, well-tested model and generate volumes of code with a single click.
In traditional Quality Engineering, there was an idea at one time that quality cost money. It took a Japanese effort that reinvented the automobile industry to change that idea once and for all. A man named Taguchi believe that cost and quality are related, except his viewpoint was that low quality was very costly. I believe the same is true in software and six-sigma efforts are now infiltrating the software industry as well.
As you can tell from my ramblings I am not taking a huge stand here. This is in part due to the fact that I really haven't used TDD as it was originally conceived. However, I do not believe it is one or the other. I think if you are working in a domain that you don't understand that well, it may have merit to derive the design through TDD. But if you are a seasoned developer, familiar with architecture, design patterns, etc., TDD may not be the best approach. You may already have a great head start and TDD would just slow you down. If you know the design and have the code generation templates, well you not only have a great start, you are really well down the road.
But so far, the best things I've gotten from TDD so far are:
- Write tests in the beginning
- Test frequently
- Invent the API upfront as part of your design
Points one and two can be used regardless of whether you are a big design upfront guy or a TDD guy. I also think the idea of inventing your own ideal API can be used very effectively in design and it will help you get clean code that works.
Comments