XP is a collection of development practices that can if used in concert speed up application development in the face of changing requirements and most of the time requirements change. Some of the practices are there to cover for weaknesses in the other practices, for example refactoring is dangerous without detailed unit tests.
If you want to ignore most of the XP practices the best to adopt would be the automated unit tests. These are developer tests, not formal QA acceptance or regression tests. Things that should be tested here are that the stored procedures actully exist, that they run with typically data without catastrophic failures. It is best to think of these as a replacement for asserts.
(Personally I replace any assert that will stop program execution with an equivalent exception – this makes it far more friendly to a unit test.)
An assert will warn you that an error condition occours while a unit test demonstrates what happens when the error condition occours.
There is a problem with the typical gui unit test addins – they write one stub test per public or protected method. This creates lots of almost irrelevent tests. The best way to think of unit testing is in terms of testing buisness functionality. This allows unit tests to be used as documentation of buisness scenarios. Plus if you omit to reset your database in the teardown (and always reset the database in the setup) then you have the oppertunity to have a tested buisness scenario that can be used as the starting point for manual UI testing. This technique alone saves hours of debugging time – write a test to recreate the exact condition that you are looking for and if you go one line too far in the debugger and destroy the test condition it is usually a matter of seconds before you can recreate the exact data that you were using.
Automated Unit tests become especially valuable when you are working across multiple streams of development. The project I am currently working on has 4 current development streams (one pure development plus three live customer streams). Since these are slowly diverging (certain new features only get added to the later streams – fixes to those units in older streams cause divergence) a fix or enhancement may need to be implemented in several places.
Tests need to be focused (test one functional area) and atomic (failure of one test should not stop the system). It is fine (even preferable) to use parts of your system to setup tests for other areas.The test framework that I use has a set of Facades that abstract away parts of the system and uses them to simplify tests.
For example if your system delt with processing customer orders (these arrive as XML documents) you could write a Facade around the code that parses and stores the incoming document and use other classes to generate the data.
So the start of the test would be:
TOrderImporterFacade.ImportOrder( TSimpleOrder, 100, ‘FooBar’ );
This would use the class TSimpleOrder to create a order for 100 FooBar’s
You could then check the outstanding orders
CheckEquals(100, TStockFacade.OpenOrdersCount(), ‘Before Restocking’);
Use another Facade to perform the buiness functions.
And again peform the same check.
CheckEquals(100, TStockFacade.OpenOrdersCount(), ‘After Restocking’);
This technique is less fragile with respect to functional changes, the tests are far easier to read,
and it is very easy to add a new buiness scenario as an experiment.