Devo interromper intencionalmente a compilação quando um bug é encontrado na produção?

410

Parece-me razoável que, se um erro sério for encontrado na produção pelos usuários finais, um teste de unidade com falha deve ser adicionado para cobrir esse erro, interrompendo intencionalmente a construção até que o bug seja corrigido. Minha justificativa para isso é que a compilação deveria ter falhado o tempo todo , mas não se devia à cobertura inadequada de testes automatizados.

Vários de meus colegas discordaram dizendo que um teste de unidade com falha não deveria ser verificado. Concordo com esse ponto de vista em termos de práticas normais de TDD, mas acho que os erros de produção devem ser tratados de maneira diferente - afinal, por que você deseja permitir uma compilação para ter sucesso com defeitos conhecidos?

Alguém mais tem estratégias comprovadas para lidar com esse cenário? Entendo que a interrupção intencional da compilação pode ser perturbadora para outros membros da equipe, mas isso depende inteiramente de como você está usando filiais.

MattDavey
fonte
75
+1; uma pergunta muito provocativa. Eu posso ver ambos os lados.
Carl Manaster
28
Você usa o termo "a compilação" para incluir "os testes", o que não é um entendimento universal.
Jay Bazuzi
19
Se você está fazendo TDD, você escreveria o teste que falhou, corrija o código e faça o check-in . Assim, você evita uma compilação quebrada.
dietbuddha
7
Pela mesma lógica, você deve encerrar as instâncias ativas dos clientes até corrigir o problema. Não, você não deve interromper a construção. Deixe o desenvolvedor responsável pelo bug adicionar o teste de unidade e o código muda juntos. Não há necessidade de desligar todo o processo.
Thanos Papathanasiou

Respostas:

412

Nossa estratégia é:

Faça o check-in de um teste com falha, mas anote-o com @Ignore("fails because of Bug #1234").

Dessa forma, o teste está lá, mas a compilação não quebra.

É claro que você observa o teste ignorado no db do bug; portanto, ele @Ignoreé removido assim que o teste é corrigido. Isso também serve como uma verificação fácil para a correção de erros.

O ponto de interromper a construção de falhas nos testes não é de alguma forma colocar a equipe sob pressão - é alertá-los para um problema. Depois que o problema é identificado e arquivado no banco de dados de erros, não faz sentido que o teste seja executado para cada build - você sabe que ele falhará.

Obviamente, o bug ainda deve ser corrigido. Mas agendar a correção é uma decisão comercial e, portanto, não é realmente uma preocupação do desenvolvedor ... Para mim, uma vez que um bug é arquivado no banco de dados do bug, ele não é mais problema meu, até que o cliente / proprietário do produto me diga que deseja corrigi-lo .

sleske
fonte
150
+1 Acho que você acertou na cabeça com "agendar a correção é uma decisão de negócios" - como desenvolvedor, não é meu julgamento decidir se um bug quebra a compilação.
precisa saber é o seguinte
22
Eu acho que essa é uma solução muito sensata. Especialmente se o próximo cara a verificar algum código menor, de repente recebe um aviso de "falha no teste" e acha que é algo que ele fez.
Holger
14
"Para mim, uma vez que um bug é arquivado no banco de dados do bug, não é mais problema meu" ... +1
Jake Berger
20
@anon Exept na Toyota. Um funcionário da linha vê um defeito, depois puxa o cabo andon e toda a fábrica é interrompida, o gerenciamento é interrompido e a linha não é reiniciada até que o problema seja resolvido. Google Andon Cord. Não é um conceito novo. Veja: startuplessonslearned.com/2008/09/…
Christopher Mahan
4
@AndresJaanTack: É claro que isso dependerá da sua metodologia, mas em geral eu discordo. Pelo menos em um ambiente de negócios, o agendamento do trabalho é uma decisão de negócios - e isso inclui a correção de erros . Às vezes, um novo recurso (ou o lançamento em uma determinada data) pode ser mais valioso do que corrigir um bug (menor) - nesse caso, a correção do bug deve ser adiada. "Corrigir o erro agora" seria inapropriado nessa situação, porque atrasa um trabalho mais importante.
sleske
106

Por que você deseja permitir que uma compilação seja bem-sucedida com defeitos conhecidos?

Porque, às vezes, você tem restrições de tempo. Ou o bug é tão pequeno que não vale a pena adiar o envio do produto por alguns dias necessários para o teste de unidade e para corrigi-lo.

Além disso, qual é o objetivo de interromper a compilação intencionalmente toda vez que você encontrar um bug? Se você o encontrou, conserte-o (ou atribua-o à pessoa que o consertará), sem perturbar toda a equipe. Se você deseja se lembrar de corrigir um erro, marque-o como muito importante no seu sistema de rastreamento de erros.

Arseni Mourzenko
fonte
Entendo o seu ponto de vista, e geralmente concordo - mas, neste caso, estamos falando de um bug sério que entrou em produção e foi encontrado pelos usuários finais: s
MattDavey
3
Veja o segundo parágrafo da minha resposta.
Arseni Mourzenko
8
Entendo, acho que o argumento está resumido no seu primeiro parágrafo - não cabe ao desenvolvedor julgar a seriedade do bug, ou se é um impedimento, é uma decisão para os negócios em geral.
precisa saber é o seguinte
4
A questão é qual é a prioridade desse bug? Pode ser um OMG FIX IT NOW, pode ser Sim, isso é chato, devemos corrigi-lo em algum momento, pode ser algo no meio. Mas nem todos os bugs atingem o mesmo local nesse espectro.
Zachary K
55

Os testes existem para garantir que você não (re) introduza problemas. A lista de testes com falha não substitui um sistema de rastreamento de bugs. Há alguma validade no POV de que os testes reprovados não são apenas indicação de bugs, eles também são uma indicação de falha no processo de desenvolvimento (do descuido à dependência mal identificada).

AProgrammer
fonte
20
"lista de testes de falha não é um substituto para um sistema de rastreamento de bugs" +1, também um ponto muito bom :)
MattDavey
1
Eu sugiro que os testes de unidade de regressão entrem na base de código como parte do bugfix, não antes.
Yrk
6
@ yarek: Os testes de regressão podem entrar na base de código a qualquer momento, eles só precisam ser ignorados até que o bug seja corrigido. Normalmente, desenvolvo-os ao diagnosticar o problema, porque eles podem funcionar como um auxiliar de depuração.
sleske
Este é um bom exemplo de por que "quebrar a compilação" se torna uma parte tóxica de um local de trabalho em que a CI passa a ser apenas "Desenvolvimento Responsável". Eu já participei de muitas reuniões em que o PHB começa a reclamar de "descuido" como se fosse por isso que a construção quebrou. Nesse ambiente, você dificilmente faria o check-in intencionalmente de algo que quebrou a compilação. Caso contrário, o PHB ficará chateado. Quebre a construção, use o cone da vergonha. Que prática ruim.
91112 Warren P
@ WarrenP, às vezes há outras questões, mas vamos ser claros, o descuido é a primeira razão pela qual a quebra de construção. Se você sabe que algo quebra a compilação, por que fazer check-in?
AProgrammer
23

"Quebrar a compilação" significa impedir que uma compilação seja concluída com êxito . Um teste com falha não faz isso. É uma indicação de que a construção possui defeitos conhecidos, o que é exatamente correto.

A maioria dos servidores de build controla o status dos testes ao longo do tempo e atribui uma classificação diferente a um teste que está falhando desde que foi adicionado versus uma regressão (teste que costumava passar e não faz mais) e também detecta a revisão na qual o regressão ocorreu.

Ben Voigt
fonte
12
Isso nem sempre é correto, geralmente as equipes consideram um teste com falha como uma compilação quebrada - na verdade, a maioria das equipes que eu vi ultimamente (é uma prática ágil típica). Na maioria das equipes ágeis, um teste que falha é o caso em que você interrompe a linha - a equipe inteira ataca o problema e o resolve. Suponho que eu possa considerar sua postagem como a resposta precisa ser baseada em suas práticas, caso em que é totalmente precisa.
Bill K
2
Eu sempre considero que um teste com falha significa que a compilação falhou.
John Saunders
@ JohnSaunders: Mas não é isso que significa. Como eu disse na minha resposta, significa "a construção possui defeitos conhecidos".
Ben Voigt
1
@ho disse que não havia testes? De onde você tira isso? Quero dizer que meu primeiro passo após encontrar o bug não é impedir o êxito da compilação, mas criar um relatório detalhado do bug. Quando o bug está sendo corrigido, primeiro deve haver um teste de unidade com falha.
John Saunders
1
Tenho um pequeno problema com a criação imediata de um teste com falha. Eu só não quero que ele faça check-in no conjunto de testes que serão executados na compilação. Eu também quero que o desenvolvedor que corrige o bug possa ignorar esse teste. Na maioria dos lugares em que trabalhei, as pessoas que criarem o relatório de erros não criarão testes de unidade.
John Saunders
16

Eu argumentaria que o teste com falha deveria ser adicionado, mas não explicitamente como "um teste com falha".

Como o @BenVoigt aponta em sua resposta , um teste que falha não necessariamente "quebra a compilação". Acho que a terminologia pode variar de equipe para equipe, mas o código ainda é compilado e o produto ainda pode ser enviado com um teste com falha.

O que você deve se perguntar nessa situação é:

O que os testes devem realizar?

Se os testes existem apenas para fazer com que todos se sintam bem com o código, adicionar um teste com falha apenas para fazer com que todos se sintam mal com o código não parece produtivo. Mas então, quão produtivos são os testes em primeiro lugar?

Minha afirmação é que os testes devem refletir os requisitos de negócios . Portanto, se foi encontrado um "bug" que indica que um requisito não foi atendido adequadamente, também é uma indicação de que os testes não refletem adequada ou totalmente os requisitos de negócios.

Esse é o bug a ser corrigido primeiro. Você não está "adicionando um teste que falhou". Você está corrigindo os testes para refletir melhor os requisitos de negócios. Se o código falhar na aprovação nesses testes, isso é bom. Isso significa que os testes estão fazendo seu trabalho.

A prioridade da fixação do código deve ser determinada pela empresa. Mas até que os testes sejam corrigidos, essa prioridade pode realmente ser determinada? A empresa deve estar armada com o conhecimento exatamente do que está falhando, como está falhando e por que está falhando para tomar suas decisões com prioridade. Os testes devem indicar isso.

Ter testes que não passam completamente não é uma coisa ruim. Ele cria um grande artefato de problemas conhecidos a serem priorizados e tratados de acordo. Ter testes que não são totalmente testados , no entanto, é um problema. Isso questiona o valor dos próprios testes.

Para dizer de outra maneira ... A compilação já está quebrada. Tudo o que você decide é se deve ou não chamar atenção para esse fato.

David
fonte
1
Sua afirmação está errada, os testes de unidade não necessariamente mapeiam diretamente os requisitos de negócios, enquanto os testes funcionais ou de ponta a ponta provavelmente o fazem, mas o OP estava falando sobre testes de unidade / TDD.
John Buchanan
@ JohnBuchanan: Quais são os testes para validar, se não que o software está fazendo o que deveria fazer? (Ou seja, ele atende aos requisitos.) Existem, como você afirma, outras formas de testes fora dos testes de unidade. Mas não vejo o valor nos testes de unidade que não validam que esse software atenda às necessidades dos negócios.
David
1
@ JohnBuchanan - ele não disse que "os testes são um reflexo dos requisitos de negócios", ele disse "DEVE SER". O que é verdade, mas discutível. Você está certo ao afirmar que esse nem sempre é o caso - algumas pessoas escrevem testes de unidade que não são mapeados para os requisitos de negócios - embora (na minha opinião) eles estejam errados ao fazê-lo. Se você quiser alegar que a afirmação de Davi está errada, você pode dizer algo sobre o motivo.
Dawood ibn Kareem
13

Em nossa equipe de automação de teste, verificamos os testes com falha, desde que eles falhem devido a um defeito no produto e não a um defeito no teste. Dessa forma, temos provas para a equipe de desenvolvimento de que, ei, eles a quebraram. Quebrar a construção é altamente desaprovado, mas isso não é o mesmo que fazer o check-in em testes perfeitamente compiláveis, mas com falha.

Yamikuronue
fonte
4
Penso que a ideia de @ MattDavey é excelente, e argumentei isso no passado. Eu sempre encontrei um muro de pedra de resistência - "você nunca deve quebrar a construção!". A ideia de que a compilação está quebrada nessa situação parece impossível para as pessoas entenderem. Infelizmente, esse é apenas mais um caso em que uma boa idéia (testes automáticos e construções limpas) se transformou em uma prática de culto à carga cujos adeptos conhecem a regra, mas não o motivo.
Tom Anderson
3
Uma idéia que eu tive foi que a equipe de controle de qualidade (se eles forem técnicos o suficiente para escrever testes) deve poder escrever testes com falha para verificar bugs e verificá-los. A obsessão dos desenvolvedores com a barra verde levaria a absolutamente priorizando a correção de bugs sobre a adição de recursos, que é a maneira correta de fazer o desenvolvimento.
Tom Anderson
Mas estes não devem ser testes de unidade que serão executados durante a compilação. Se o seu ambiente contiver um sistema de gerenciamento de teste para controle de qualidade (como o Microsoft Test Manager), certamente um ou mais casos de teste devem ser adicionados e vinculados ao bug, mas isso não impediria o êxito da compilação - seria simplesmente um teste caso que precisa passar antes que o bug seja considerado "Concluído".
John Saunders
7

Escrever um teste que você sabe que falhará até que o bug seja corrigido é uma boa idéia, é a base do TDD.

Quebrar a compilação é uma má ideia. Por quê? Porque isso significa que nada pode seguir em frente até que seja corrigido. Ele essencialmente bloqueia todos os outros aspectos do desenvolvimento.

Exemplo 1
E se o seu aplicativo for grande, com muitos componentes? E se esses componentes forem trabalhados por outras equipes com seu próprio ciclo de lançamento? Difícil! Eles têm que esperar pela sua correção de bug!

Exemplo 2
E se o primeiro erro for difícil de corrigir e você encontrar outro erro com maior prioridade? Você também interrompe a construção do segundo bug? Agora você não pode construir até que ambos sejam corrigidos. Você criou uma dependência artificial.

Não há razão lógica para que a falha em um teste interrompa uma compilação. Essa é uma decisão que a equipe de desenvolvimento precisa tomar (talvez com discussão sobre gerenciamento) avaliando os prós e os contras de liberar uma compilação com erros conhecidos. Isso é muito comum no desenvolvimento de software, praticamente todos os principais softwares são lançados com pelo menos alguns problemas conhecidos.

Qwerky
fonte
5

Depende do papel que os testes devem desempenhar e de como seus resultados afetam o sistema / processo de construção adotado. Meu entendimento de interromper a compilação é o mesmo de Ben e, ao mesmo tempo, não devemos verificar conscientemente o código que quebra os testes existentes. Se esses testes vierem "mais tarde", pode ser "bom" ignorá-los apenas para torná-los menos desnecessariamente perturbadores para os outros, mas acho essa prática de ignorar testes com falha (para que pareçam passar) bastante perturbadora (especialmente para testes de unidade), a menos que haja uma maneira de indicar esses testes como vermelho ou verde.

prusswan
fonte
"a menos que exista uma maneira de indicar esses testes como nem vermelho nem verde" Apenas para constar: a maioria das estruturas de teste de unidade distingue os testes vermelho, verde e ignorado. Pelo menos JUnit e TestNG fazem (eles relatam "xx test, x falhou, x ignorado").
sleske
@sleske que seria o ideal, eu só quero ter certeza de que as falhas ignorando não ligam automaticamente em um sucesso
prusswan
Não existem construções AMARELAS? (Vermelho / Verde / Amarelo) em Hudson / Jenkins, Cruise Control e todos os outros figurões?
91112 Warren P
P @Warren ele funciona quando as pessoas ignoram os testes corretamente, mas alguns ignorar testes, tornando-verde
prusswan
5

Depende do bug, é claro, mas geralmente se algo der errado e não for identificado durante o teste manual ou automatizado, isso implica que há uma lacuna na sua cobertura. Definitivamente, eu incentivaria descobrir a causa raiz e colocar um caso de teste de unidade em cima do problema.

Se for um problema de produção planejado para uma correção hot de uma filial de manutenção, você também precisará garantir que a correção funcione na linha principal e que um desenvolvedor não possa erroneamente eliminar a correção com uma resolução de conflito de mesclagem excessivamente zelosa .

Além disso, dependendo da sua política de lançamento, a presença de testes de unidade atualizados recentemente pode ajudar a confirmar que um desenvolvedor realmente corrigiu o problema, em vez de apenas alterá-lo [(o problema ou os testes?)], Embora isso dependa de ter codificado o requisitos corretos nos novos testes de unidade.

Keith Brings
fonte
5

Um problema ao adicionar um teste de falha na construção é que sua equipe pode ter o hábito de ignorar testes de falha porque espera que a construção falhe. Depende do seu sistema de construção, mas se um teste com falha nem sempre significa "algo acabou de quebrar", é fácil prestar menos atenção às falhas nos testes.

Você não quer ajudar sua equipe a entrar nessa mentalidade.

Portanto, concordo com o sleske que você deve adicionar o teste, mas marque-o como 'ignorado' para fins de criação automática, até que o bug seja corrigido.

Wilka
fonte
1
Seu software de teste deve informar quando algo foi quebrado recentemente, em comparação com um teste que falhou antes.
precisa
4

Embora eu ache que você deva, de alguma forma, fazer o check-in do bug como teste, para que, quando você o conserte, não ocorra novamente e, de alguma forma, priorize-o, acho que é melhor não quebrar a compilação (/ os testes) . O motivo é que as confirmações subsequentes de construção ficarão ocultas atrás do teste quebrado. Portanto, ao verificar um teste quebrado para esse bug, você exige que toda a equipe reserve seu trabalho de lado para corrigi-lo. Se isso não acontecer, você poderá acabar com os commits que não são rastreáveis ​​como tal.

Portanto, eu diria que é melhor enviá-lo como um teste pendente e fazer da sua equipe uma prioridade não ter testes pendentes.

markijbema
fonte
4

Outra opção é verificar o teste com falha em uma ramificação separada no seu sistema de controle de origem. Dependendo de suas práticas, isso pode ser viável ou não. Às vezes, abrimos uma nova ramificação para o trabalho em andamento, como corrigir um erro que não é trivial.

Ola Eldøy
fonte