As respostas existentes são certamente boas, mas não vi ninguém abordar esse equívoco fundamental na pergunta:
a qualquer momento todos os testes de unidade devem passar
Não. Certamente, isso não será verdade. Enquanto desenvolvo software, o NCrunch costuma ser marrom (falha na compilação) ou vermelho (falha no teste).
Onde o NCrunch precisa ser verde (todos os testes sendo aprovados) é quando eu estou pronto para enviar uma confirmação ao servidor de controle de origem, porque nesse momento outros podem ter uma dependência do meu código.
Isso também alimenta o tópico de criação de novos testes: os testes devem afirmar a lógica e o comportamento do código. Condições de contorno, condições de falha etc. Quando escrevo novos testes, tento identificar esses "pontos de acesso" no código.
Os testes de unidade documentam como eu espero que meu código seja chamado - condições prévias, resultados esperados etc.
Se um teste for interrompido após uma alteração, preciso decidir se o código ou o teste está com erro.
Como uma observação lateral, o teste de unidade às vezes anda de mãos dadas com o Test Driven Development. Um dos princípios do TDD é que os testes quebrados são suas orientações. Quando um teste falha, você precisa corrigir o código para que o teste seja aprovado. Aqui está um exemplo concreto do início desta semana:
Antecedentes : escrevi e agora suporte uma biblioteca usada por nossos desenvolvedores que é usada para validar consultas Oracle. Tivemos testes que afirmavam que a consulta correspondia a algum valor esperado, o que tornava importante o caso (não está no Oracle) e aprovava alegremente consultas inválidas, desde que correspondessem completamente ao valor esperado.
Em vez disso, minha biblioteca analisa a consulta usando Antlr e uma sintaxe Oracle 12c e, em seguida, agrupa várias asserções na própria árvore de sintaxe. Coisas como, é válido (nenhum erro de análise foi gerado), todos os seus parâmetros são satisfeitos pela coleção de parâmetros, todas as colunas esperadas lidas pelo leitor de dados estão presentes na consulta, etc. Todos esses itens foram transferidos para produção em vários momentos.
Um dos meus colegas engenheiros me enviou uma consulta na segunda-feira que falhou (ou melhor, teve sucesso quando deveria ter falhado) no fim de semana. Minha biblioteca disse que a sintaxe estava correta, mas explodiu quando o servidor tentou executá-la. E quando ele olhou para a consulta, ficou óbvio o porquê:
UPDATE my_table(
SET column_1 = 'MyValue'
WHERE id_column = 123;
Carreguei o projeto e adicionei um teste de unidade que afirmava que essa consulta não deveria ser válida. Obviamente, o teste falhou.
Em seguida, depurei o teste que falhou, passei pelo código onde esperava que ele lançasse a exceção e descobri que o Antlr estava gerando um erro no ponto aberto, mas não da maneira que o código anterior esperava. Modifiquei o código, verifiquei que o teste agora estava verde (passando) e que nenhum outro havia quebrado no processo, confirmado e enviado por push.
Isso levou cerca de 20 minutos e, no processo, eu aprimorei significativamente a biblioteca, porque agora ela suportava toda uma gama de erros que anteriormente estava ignorando. Se eu não tivesse testes de unidade para a biblioteca, pesquisar e corrigir o problema poderia levar horas.