Outras pessoas corrigem bugs quando os veem ou esperam até que ocorram falhas / perda de dados / pessoas morrem antes de corrigi-lo?
Exemplo 1
Customer customer = null;
...
customer.Save();
O código está claramente errado, e não há como contornar - ele está chamando um método em uma referência nula. Acontece que não trava porque Save
não acessa nenhum dado da instância; então é como chamar uma função estática. Mas qualquer pequena alteração em qualquer lugar pode causar repentinamente código quebrado que não falha: começar a falhar.
Mas também não é inconcebível que a correção do código:
Customer customer = null;
...
customer = new Customer();
try
...
customer.Save();
...
finally
customer.Free();
end;
pode apresentar uma falha; um não descoberto através de testes de unidade com cobertura completa e teste manual do usuário.
Exemplo 2
float speed = 0.5 * ((G * mass1 * mass2) / R) * Pow(time, 2);
As pessoas saberem física vai reconhecer que é suposto ser de R 2 no denominador.
O código está errado, está absolutamente errado. E superestimar a velocidade fará com que os retro-foguetes disparem muito cedo, matando todos os ocupantes da espaçonave.
Mas também é possível, talvez, superestimar a velocidade, mascarando outro problema: os airbags não podem ser acionados enquanto o ônibus espacial se move muito rápido. Se repentinamente corrigirmos o código:
float speed = 0.5 * ((G * mass1 * mass2) / Pow(R, 2)) * Pow(time, 2);
Agora a velocidade é precisa e, de repente, os airbags estão sendo acionados quando não deveriam.
Exemplo 3
Aqui está um exemplo que eu tive recentemente, verificando se uma string contém caracteres inválidos:
if (StrPos(Address, "PO BOX") >= 0)
{
//Do something
}
E se houver um erro no Do something
ramo? Corrigindo o código obviamente incorreto:
if (StrPos("PO BOX", Address) >= 0)
{
//Do something
}
Corrige o código, mas introduz um erro.
A meu ver, existem duas possibilidades:
- corrigir o código e ser responsabilizado por quebrá-lo
- aguarde o código travar e seja responsabilizado por ter um bug
O que você faz politicamente?
Exemplo 4 - Bug do mundo real de hoje
Estou construindo um objeto, mas chamando o construtor errado:
Customer customer = new Customer();
Acontece que o construtor "sem parâmetros" é na verdade um construtor parametrizado mais adiante na cadeia de herança:
public Customer(SomeObjectThatNobodyShouldBeUsingDirectly thingy = null)
public Customer(InjectedDependancy depends)
Chamar isso é um erro, pois ignora todos os construtores subseqüentes.
Eu poderia alterar a linhagem do objeto para não expor um construtor tão perigoso, mas agora tenho que alterar o código para:
Customer customer = new Customer(depends);
Mas não posso garantir que essa mudança não vá quebrar nada. Como no meu Exemplo 1 acima, talvez alguém, em algum lugar, de alguma forma, sob algumas condições esotéricas, dependa que o construído Customer
seja inválido e cheio de lixo.
Talvez o Customer
objeto, agora que ele esteja corretamente construído, permita a execução de algum código que nunca funcionou anteriormente, e agora eu possa travar.
Não posso apostar na vida da sua esposa.
E posso testar daqui até terça-feira, não posso jurar pela vida de sua filha que não introduzi uma regressão.
Eu:
- Corrigir o código e ser responsabilizado por quebrá-lo? ou
- Deixe o bug e seja responsabilizado quando o cliente o encontrar?
fonte
Respostas:
Isso depende muito da situação, do bug, do cliente e da empresa. Há sempre uma troca a considerar entre corrigir a implementação e potencialmente introduzir novos bugs.
Se eu desse uma orientação geral para determinar o que fazer, acho que seria algo assim:
Lembre-se, isso só se aplica quando você está perto de um lançamento. Se você estiver no modo de desenvolvimento completo, basta registrar o defeito para que ele possa ser rastreado, corrigido e finalizado. Se for algo que demora mais do que, digamos, meia hora para consertar e verificar, eu procuraria o líder / gerente da equipe e veria se o defeito deve ou não se encaixar no ciclo de lançamento atual ou agendado para mais tarde.
fonte
Os clientes sempre encontrarão bugs . Nunca há erros ocultos dos clientes. No final, os erros que você apresentar sempre voltarão para você. Não consertá-los é simplesmente uma má prática profissional. Profissionais não fazem isso.
Quando os clientes encontram bugs, a empresa parece ruim, não um desenvolvedor individual. Isso é muito pior para a empresa, então é o seu caso para fazer a alteração. Se você realmente não tiver certeza de fazer essa alteração com medo de introduzir outros erros, converse com um desenvolvedor mais sênior, com o líder técnico do projeto ou com quem estiver em posição de tomar uma decisão sobre essa alteração e, posteriormente, lidar com as consequências.
fonte
Corrigir o erro
Somos profissionais aqui. Se você encontrar um caminho com falha no código que causará uma falha ou comportamento incorreto, será necessário corrigi-lo. Dependendo dos procedimentos de sua equipe, você provavelmente precisará registrar um defeito, talvez escrever um teste de regressão e verificar a correção no momento certo do ciclo de envio. Se for um bug de baixa prioridade, verificar a correção perto do início de um marco é sempre um bom momento, porque se você fizer uma regressão, não afetará o ciclo de lançamento do marco.
Não confunda isso com refatoração ou aprimoramentos de desempenho que não estão relacionados a um bug de desempenho.
Um sistema de controle de fonte distribuído onde você pode manter um repositório separado de 'pequenas correções de bugs' e depois mesclar facilmente no início de um marco é uma grande ajuda aqui.
fonte
O que o cliente diria?
Aqui está como eu imagino isso acontecendo:
Sim. Corrija o erro. Você salvará o cliente de uma experiência agravante e poderá corrigi-lo antes que se torne uma emergência.
E se você acha que sua correção pode realmente causar uma falha, ainda não a encontrou.
fonte
Todos os exemplos que você deu parecem ter um encadeamento comum. Você parece querer corrigir um erro que não entende completamente. Eu digo isso porque você observa a possibilidade de consequências indesejadas em cada uma delas.
Eu diria que provavelmente é um grande erro e, como Ben Laurie escreve , não corrige um bug que você não entende . Neste exemplo famoso, a equipe do Debian quebrou a criptografia do OpenSSL para Debian e derivados como o Ubuntu quando seguiu os resultados de uma ferramenta de análise.
Se você acredita que há um defeito observando o código, certifique-se de reproduzir o defeito da maneira que o cliente possa ver. Se você não pode, por que não gastar seus recursos consertando outra coisa?
fonte
Comece a reduzir sua dívida técnica o mais rápido possível .
Seus exemplos definitivamente parecem código legado , com muita dívida técnica e sinto que há medo de mudar (BTW, isso não é uma crítica ou um julgamento). Toda a sua equipe precisa reconhecer que você tem essa dívida técnica (para que você não seja o único culpado por isso) e, em seguida, pode decidir como vai lidar com isso.
No Exemplo 1, se
Save()
não acessar nenhum dado da instância, quais dados do cliente são salvos exatamente? Comece consertando e testando isso.No Exemplo 2, é fácil cobrir a calculadora de velocidade com testes e garantir que ela calcule o resultado correto em todos os principais exemplos.
No exemplo 3, há o risco de trazer o código morto de volta à vida. Esse código deve ser eliminado por completo? Qual é a intenção da condição booleana nesse caso? É para garantir que a sequência não contenha caracteres inválidos? Ou para garantir que tenha "PO BOX"? Quanto mais cedo você começar a abordar essas questões, melhor.
Depois de corrigir vários desses problemas, faça uma espécie de retrospectiva / post mortem com sua equipe. É importante aprender com a experiência para poder reduzir sua taxa de injeção de defeitos no futuro.
fonte
Você já tem boas respostas. Vou apenas acrescentar algo sobre a questão de ter medo de que algo trava.
Primeiro, na situação ideal, o software é modular, é arquitetado corretamente e há uma boa separação de preocupações. Nesse caso, é muito improvável que as alterações feitas quebrem qualquer coisa, pois você controlará todo o código relacionado e não haverá surpresas ocultas.
Infelizmente, a situação ideal é fictícia. Independentemente da extensão em que o acoplamento esteja frouxo, haverá acoplamento e, portanto, a possibilidade de quebrar outra coisa.
A solução para isso é dupla:
Tornar o código bem estruturado não é feito reescrevendo o código inteiro em um novo design de arquitetura. Em vez disso, a refatoração guiada por testes é sua amiga aqui. Nesta etapa, você não altera a funcionalidade.
O segundo passo é que você conserta o bug.
Alguns pontos são relevantes:
Já são mais do que alguns pontos, então acho que vou parar por aqui.
fonte
Você primeiro precisa considerar a definição de um bug:
Parece que você está focado no número 1, onde o número 2 é o melhor lugar para se sentar. Certamente, nós programadores queremos que nosso código esteja correto (nº 1), mas as pessoas nos pagam para que ele funcione (nº 2).
O que você pode ou não fazer com a base de código que pode acidentalmente introduzir novos bugs é irrelevante para a visão nº 2 do software atual. No entanto, o nº 1 é importante para você ou para o programador de manutenção a seguir. Às vezes é difícil decidir, mas quando o segundo e o primeiro estão em conflito, você precisa saber que o segundo é claramente mais importante.
fonte
Nem. Existe uma terceira maneira: encontre uma maneira de provar que "o código problemático" está realmente causando problemas do ponto de vista comercial. Confirme o que encontrou com BA / QA ou pelo menos com seu gerente. Em seguida, planeje a correção quando todos estiverem cientes do problema.
Existem outros cenários possíveis além de um bug válido nos casos mencionados:
Nos dois casos acima, se eu sou gerente, não quero que os desenvolvedores usem seu julgamento e corrijam o "erro". A correção do erro no local pode ajudar na maior parte do tempo, mas quando ocorre um erro, pode causar mais problemas do que sua boa intenção.
fonte
Você corrige o erro, inicia os testes de unidade e, quando obtêm êxito, verifica sua correção.
(Ou, se seus testes de unidade levarem muito tempo, verifique sua correção primeiro e aguarde se a ferramenta de CI envia um email a você porque sua confirmação quebrou alguma coisa.)
fonte
Corrija-os se forem erros de falha / perda de dados. O envio de um programa com um bug conhecido de perda de dados é absolutamente malicioso e indesculpável.
Se o bug for estético ou não crítico (pode ser evitado), ele deve ser documentado e uma solução alternativa deve ser fornecida. Idealmente, ele deve ser corrigido, mas às vezes é muito caro corrigi-lo para a versão atual.
Observe como todo projeto de software maior tem uma seção 'Problemas conhecidos' no Leia-me, que geralmente lista exatamente isso: Bugs conhecidos.
Conhecer Bugs e NÃO comunicá-los é IMHO aceitável apenas para bugs realmente menores / cosméticos.
fonte
Corrija e faça o teste. Se você decidir manter os bugs conhecidos apenas porque tem medo de encontrar mais bugs, seu programa se tornará um campo minado de bombas-relógio tão rápidas que se tornará irreparável mais cedo do que você pensa.
Como você é o mestre e o código é o subordinado, talvez você não tenha medo de alterá-lo quando perceber que está errado. O medo do código ("pode retaliar quebrando em outro lugar") é simplesmente inaceitável.
fonte
Se houver claramente um triturador, ou algo errado , você deve corrigi-lo. Se houver uma ambiguidade na especificação, ou seja, se você estiver pensando "bem, o cliente pode esperar isso, mas parece que pode ser um bug" ou um problema na especificação, como "fomos solicitados a fazer isso" mas é péssimo ", então você precisa descobrir o que fazer. Jogar o código por cima do muro e aguardar o feedback do cliente é ruim - você pode perguntar a um gerente de produto se possui um ou pedir ao cliente antes de implantar o produto.
Lembre-se de que "conhecemos esse problema e o corrigiremos em uma versão futura" é sinônimo de "conhecemos esse problema, mas não nos importamos com você o suficiente para evitar que você lide com ele".
fonte
O curso de ação correto não é ignorar o bug, nem "consertá-lo" no local; pelas mesmas razões que você identificou na sua pergunta.
Eu acho que você deve tentar entender o código primeiro. Se o código que você está vendo tem alguma idade e ninguém percebeu o "bug" ainda, provavelmente há uma razão para isso. Tente encontrar esse motivo. Aqui está o que eu gostaria de analisar antes de tomar uma decisão:
Histórico : use o software de controle de versão para responder às perguntas: Quem tocou no código? O que eles mudaram? E com quais mensagens de confirmação eles fizeram check-in? Você pode deduzir um motivo pelo qual o código parece?
Uso : Qual código usa o código defeituoso? E como? O código está morto? Existe outro código que se baseia no comportamento defeituoso?
Autor : Se você não conseguir chegar rapidamente a uma conclusão usando as informações acima, pergunte ao autor do código (pelo menos se isso for possível) por que o código tem a aparência que ele tem. Normalmente, você receberá um "Oups, isso deve ser corrigido!" ou um "Não! Não mude !!! É necessário assim!" Imediatamente.
fonte