[From PhlIp on the XpMailingList]
When bugs are noticed he captures them in a test.
This advice is mission-critical, but the XP list implies it, not screams it. We should have a megabuck ad campaign to tell everyone to do this.
TestDrivenDevelopment works by only changing the code if you can write such a test as forces the change. If you have a bug, write a new case in your ProgrammerTests that reproduces the bug, and fails because of it.
Make sure the test is as narrow as possible. Don't call the function 10 layers up from the function where the bug begins. Call that function itself.
When the test fails due to the bug, squash it.
Observe that writing the test should characterize the bug so thoroughly that squashing it becomes a mere formality. Expect instant success when you squash.
If not, hit Undo until the code's just like it was before the squash attempt, and review your situation.
The goal is: One test fails - Squash - All tests pass. Any other sequence isn't narrow and incremental enough.
A good answer to unresolved questions on NoBugDatabase. This also allows ArguingThroughUnitTests.
If there should be no bug database, how about a TaskDatabase? -- GuillermoSchwarz
Also related to DefectTrackingPatterns