Having recently discovered this method of development, I'm finding it a rather nice methodology. So, for my first project, I have a small DLL's worth of code (in C#.NET, for what it's worth), and I want to make a set of tests for this code, but I am a bit lost as to how and where to start.
I'm using NUnit, and VS 2008, any tips on what sort of classes to start with, what to write tests for, and any tips on generally how to go about moving code across to test based development would be greatly appreciated.
“Test-driven development” refers to a style of programming in which three activities are tightly interwoven: coding, testing (in the form of writing unit tests) and design (in the form of refactoring).
Refactoring happens in the TDD practice after you quickly implement the missing functionality and all tests in the test suite pass. The code after the first two steps might not be the production quality code.
See the book Working Effectively with Legacy Code by Michael Feathers.
In summary, it's a lot of work to refactor existing code into testable and tested code; Sometimes it's too much work to be practical. It depends on how large the codebase is, and how much the various classes and functions depend upon each other.
Refactoring without tests will introduce changes in behaviour (i.e. bugs). And purists will say it's not really refactoring because of the lack of tests to check that the behaviour doesn't change.
Rather than adding test across the board to your whole application at once, add tests when you work in an area of code. Most likely you'll have to return to these "hotspots" again.
Add tests from the bottom up: test little, independent classes and functions for correctness.
Add tests from the top down: Test whole subsystems as black boxes to see if their behaviour changes with changes in code. And so you can step through them to find out what's going on. This approach will probably get you the most benefit.
Don't be too concerned at first with what the "correct" behaviour is while you are adding tests, look to detect and avoid changes in behaviour. Large, untested systems often have internal behaviours that may seem incorrect, but that other parts of the system depend on.
Think about isolating dependencies such as database, filesystem, network, so that they can be swapped out for mock data providers during testing.
If the program doesn't have internal interfaces, lines which define the boundary between one subsystem/layer and another, then you may have to try to introduce these, and test at them.
Also, automatic mocking frameworks like Rhinomocks or Moq might help mock existing classes here. I haven't really found the need for them in code designed for testability.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With