Our strategy is:
Check in a failing test, but annotate it with
@Ignore("fails because of Bug #1234").
That way, the test is there, but the build does not break.
Of course you note the ignored test in the bug db, so the
@Ignore is removed once the test is fixed. This also serves as an easy check for the bug fix.
The point of breaking the build on failing tests is not to somehow put the team under pressure – it’s to alert them to a problem. Once the problem is identified and filed in the bug DB, there’s no point in having the test run for every build – you know that it will fail.
Of course, the bug should still be fixed. But scheduling the fix is a business decision, and thus not really the dev’s concern… To me, once a bug is filed in the bug DB, it’s no longer my problem, until the customer/product owner tells me they want it fixed.
Why would you want to allow a build to succeed with known defects?
Because sometimes, you have time constraints. Or the bug is so minor that it isn’t really worth delaying the shipment of the product for a few days needed to unit test and fix it.
Also, what’s the point in breaking the build intentionally every time you find a bug? If you found it, fix it (or assign it to the person who will fix it), without disturbing your whole team. If you want to remember to fix a bug, then you need to mark it as very important in your bug tracking system.
Tests are there to ensure that you don’t (re-)introduce problems. The list of failing tests isn’t a substitute for a bug tracking system. There is some validity in the POV that failing tests aren’t only indication of bugs, they are also an indication of development process failure (from carelessness to badly identified dependency).