Over the Easter holiday I read Test Driven Development with Microsoft .NET. Overall I really enjoyed the book. It provides a solid overview of how to handle some advanced TDD tasks that many other books gloss over.
The book begins with an introduction to test driven development. The authors clearly have a lot of experience (they wrote NUNit) and do a solid job of explaining why TDD can be an extremely valuable design tool. After introducing TDD the authors provide a quick overview of Refactoring by stepping through a sample application. Throughout the book the authors present semi-real life examples to make their point. The authors don't present and implement things in an idealistic way as some other books do, instead they refactor and test as they would a real application.
The chapter that I was looking forward to reading the most was TDD with ADO.NET. Many other TDD books gloss over how to use TDD when a database is involved. Additionally many TDD proponents believe that TDD should not involve the database. The authors present a Media Library example to demonstrate how to use TDD with ADO.NET. The architecture of the sample application is based on datasets. To test the ADO.NET code the examples compare the data retrieved from the database in a dataset with the in memory dataset containing the expected values. Although the examples do offer some very good insights into ways in which developers can use TDD with ADO.NET I was hoping for more. I would have loved to see some more examples including some other architectures based on custom business objects and a domain model. Even so, I got a lot out of the chapter. If nothing else it was good to see that the way I was implementing my tests wasn't totally off base.
The books goes onto cover topics such as TDD with web services, Implementing Customer Tests (with FIT), Transactions, and more. Overall the books offers a lot of valuable information to those getting started with TDD.
As I was reading the book I took notes on my HP 4350. The notes can be found below:
Intro/Overview of TDD
- Never write a line of code without a failing test.
- Eliminate Duplication
- Write a test list 15-20 Minutes per 4hr task
- Test list verifies requirements and Describes completion criteria
- Red/green/refactor
- Focus on what the class does not how it's implemented
Refactoring
- Refactoring improves structure of existing code
- Refactoring makes longterm software ownership less painful
- Need up to date tests before refactoring
- Tests provide safety nets for refactoring
TDD with ado.net
- Typed dataset for populating test database
- Leave relationships off typed dataset to increase testability off individual entities, other tests will verify relationships
- Ideally only one test should fail because of a problem. However this is not always possible when testing db apps, it should remain a goal.
- Dataset based examples not as valuable as custom object examples.
- Tests for entities, relationships and utilities.
- Naming of test classes with Fixture, test method names not testdox'able.
- Organize tests by use, in separate assembly.
- Very useful to have suite of tests that can test/validate db schema and let us know when a change causes problems
TDD with web services
- Write tests to minimize the dependencies
- Want failing test to pinpoint the problem in code
- Isolation reduces debugging
- error checking in stub.code should only be done if the cost outweighs the benefit
- Write dto using schema and xsd.exe
- Map dataset to dto via 'assembler'
- Test in isolation and then introduce database
- Database fixture inherits from implementation fixture
Customer tests
- Allow client to define requirements in an easy to use format/language
- Automated to facilitate feedback
- Fit
- If fit tests require code changes to adapter class what is the real benefit over NUNit?
- Write customer tests first
Transactions
- Use transaction to rollback db to pre test state
- Transaction manager on thread, classes that hit db check if they should join existing transaction or create their own. Done via command pattern.
- Adapters to convert xsd.exe classes into bindable objects
- Separate web code as much as possible to increase testability of the code.