Resposta
Quanto mais perto você chegar de um aplicativo sem bugs, o mais caro fica. É como atingir 100% de cobertura de código: você gasta a mesma quantidade de tempo e dinheiro obtendo de 0% a 95%, de 95% a 99% e de 99% a 99,9%.
Você precisa desse 0,1% extra de cobertura de código ou qualidade? Provavelmente sim, se você estiver trabalhando em um produto de software que controla o sistema de resfriamento de um reator nuclear. Provavelmente não, se você estiver trabalhando em um aplicativo de negócios.
Além disso, fazer software de alta qualidade requer uma abordagem muito diferente . Você não pode simplesmente pedir a uma equipe de desenvolvedores que passaram a vida escrevendo aplicativos de negócios para criar um aplicativo quase sem bugs. Software de alta qualidade requer técnicas diferentes, como prova formal , algo que você certamente não deseja usar em um aplicativo de negócios, devido ao custo extremamente alto que representa.
Conforme expliquei em um dos meus artigos :
-
Os aplicativos de negócios não devem ter como alvo a qualidade necessária para softwares essenciais, porque se esses aplicativos de negócios falharem de vez em quando, simplesmente não ” Tenho visto bugs e tempo de inatividade em sites de provavelmente todas as grandes corporações, sendo a Amazon a única exceção. Esse tempo de inatividade e esses bugs são irritantes e talvez custem alguns milhares de dólares por mês à empresa, mas consertá-los seria muito mais caro.
-
O custo deve ser o foco principal, e deve ser estudado pragmaticamente. Vamos imaginar um bug que está afetando 5.000 clientes e é tão importante que esses clientes irão embora para sempre. Isso é importante? Sim? Pense mais. E se eu disser que cada um desses clientes está pagando $ 10 por ano e que vai custou quase US $ 100.000 para corrigir o bug? A correção de bugs agora parece muito menos interessante.
Agora, para responder especificamente às suas perguntas:
Por que os bugs são relatados mesmo depois de passar por tantos testes? É o nosso problema de requisitos? Nosso cliente não parece feliz com nada que oferecemos? estamos fazendo algo incorreto?
Muitas coisas podem dar errado. Por teste, você quer dizer teste automatizado real? Se não, esse é um grande problema para si mesmo. Os testadores entendem os requisitos? Você se comunica com o cliente regularmente – pelo menos uma vez por iteração, no máximo o representante do cliente pode ser acessado imediatamente no local por qualquer membro de sua equipe ? Suas iterações são curtas o suficiente? Os desenvolvedores estão testando seu próprio código?
De maneira semelhante ao artigo Eles escrevem as coisas certas no link acima, faça um relatório de bug e estude por que esse bug apareceu em primeiro lugar e por que foi esquecido por cada testador . Isso pode lhe dar algumas idéias sobre as lacunas no processo de sua equipe.
Um ponto importante a considerar: seu cliente está pagando por correções de bugs? Se não, ele pode ser encorajado a considerar várias coisas para ser um bug. Fazê-lo pagar pelo tempo que você gasta com os bugs reduzirá consideravelmente o número de relatórios de bugs.
Alguém desenvolveu algum aplicativo que foi totalmente livre de bugs? Qual é o processo? Por que não podemos implantar o aplicativo com pequenos bugs? Devemos ser perfeccionistas?
Eu. Eu escrevi um aplicativo para mim mesmo no último fim de semana e não encontrei nenhum bug até agora.
Bugs são bugs apenas quando são relatados. Então, em teoria, ter um aplicativo sem bugs é totalmente possível: se ele não for usado por ninguém, não haverá ninguém para relatar os bugs.
Agora, escrevendo um aplicativo em grande escala que combina perfeitamente com o especificação e está provado que está correto (veja a prova formal mencionada acima) é uma história diferente. Se este for um projeto vital, este deve ser seu objetivo (o que não significa que seu aplicativo estará livre de erros).
O cenário atual é o processo correto de desenvolvimento e teste? Se não, qual é uma maneira eficiente de desenvolvedores, testadores e cliente obterem o máximo benefício juntos?
-
Para se entenderem , eles devem se comunicar. Não é o que acontece na maioria das empresas que conheço. Na maioria das empresas, o gerente de projeto é o único que fala com o cliente (às vezes com um representante).Em seguida, ele compartilha (às vezes parcialmente) seu entendimento dos requisitos com desenvolvedores, designers de interação, arquitetos, DBAs e testadores.
É por isso que é essencial para o cliente (ou representante do cliente) ser acessível por qualquer pessoa da equipe (abordagem ágil) ou ter meios de comunicação formal que autorizem uma pessoa a se comunicar apenas com algumas outras pessoas em uma equipe e fazê-lo de forma que as informações possam ser compartilhadas com toda a equipe, garantindo que todos tenham as mesmas informações.
-
Existem muitos processos para fazer o desenvolvimento e os testes. Sem saber exatamente a empresa e a equipe, não há como determinar qual deles deve ser aplicado no seu caso. Considere contratar um consultor ou um gerente de projeto que seja habilidoso o suficiente.
Comentários
- +1. Antes mesmo de iniciar um projeto, você precisa ter uma compreensão do que é " bom o suficiente para lançamento " e construa de acordo.
- @JuliaHayward Não foi possível ' concordar mais. O jogo final aqui não é ' t zero defeitos – é produzir software funcional que agrega valor em tempo hábil.
Resposta
Nem todos os insetos são criados iguais, então você precisa separar o joio do trigo.
Expectativas
Muitos bugs são levantados simplesmente devido a uma deficiência no que o software faz e no que o usuário final espera. Essa expectativa vem de muitas áreas: uso de outro software, documentação incorreta, equipe de vendas excessivamente zelosa, como o software costumava funcionar, etc. etc.
Variação do escopo
Nem é preciso dizer que quanto mais você entregar, maior será o potencial para bugs. Muitos bugs são simplesmente gerados por causa de novos recursos. Você entrega X & Y, mas o cliente diz que, no verso disso, agora também deve fazer Z.
Entenda o domínio do problema
Muitos bugs acontecem pela simples razão de que o domínio do problema foi mal compreendido. Cada cliente tem suas próprias regras de negócios, jargões e formas de fazer as coisas. Muito disso não será documentado em lugar nenhum – estará apenas na cabeça das pessoas. Com a melhor boa vontade do mundo, você não pode esperar capturar tudo isso de uma só vez.
Então … o que fazer a respeito.
Testes de unidade automatizados
Muitos bugs são introduzidos como um efeito colateral inesperado de alguma alteração de código. Se você tiver testes de unidade automatizados, você pode evitar muitos desses problemas e produzir um código melhor desde o início.
Os testes são tão bons quanto os dados fornecidos – portanto, certifique-se de compreender totalmente o domínio do problema.
Cobertura de código
Isso anda de mãos dadas com o teste de unidade automatizado. Você deve certifique-se de que o máximo de código seja testado quanto possível.
Aprenda as lições
A loucura está fazendo a mesma coisa repetidamente e esperando resultados diferentes
Você entende as causas da última falha? Não é? Sério? Você pode ter parado o problema ocorrendo, mas qual era a verdadeira fonte raiz? Dados ruins? Erro do usuário? Corrupção do disco? Interrupção da rede?
Nada incomoda mais os clientes do que encontrar os mesmos problemas repetidamente sem progredir em alguma forma de resolução.
Resposta
Os defeitos existem desde o início do desenvolvimento de software. É difícil dizer a partir de sua pergunta até que ponto e com que gravidade os defeitos afetam a usabilidade ou funcionalidade.
Existem programas sem defeitos, mas praticamente qualquer sistema não trivial terá defeitos.
Você terá que decidir sobre algum tipo de priorização e provavelmente terá que fazer algum estudo da causa dos defeitos – onde eles foram introduzidos. Há muito o que discutir sobre essas coisas em um simples Q & Um post.
Livros inteiros foram escritos sobre análise causal e processo de correção para uma organização que tem problemas de qualidade.
Portanto, minha recomendação é: (sem uma ordem específica)
- Implementar um sistema de rastreamento de defeitos se você ainda não o encontrou
- Determinar uma maneira de classificar a gravidade dos defeitos
- Descubra por que você não está atendendo às expectativas do cliente (são os desenvolvedores, o controle de qualidade, o cliente, etc.)
- Aprenda sobre alguns exercícios como os “Cinco porquês” e faça investigações semelhantes em algumas das causas de seus defeitos.
Resposta
Depende de como você chama um aplicativo.
Se você quer dizer um programa interativo onde você precisa ter certeza de que o comportamento em tempo real é exatamente isso e tal em quaisquer circunstâncias, então é basicamente impossível provar que não há nenhum bug iniciar. Suponho que seria possível se você pudesse resolver o problema de parada , mas você não pode.
No entanto, se você se restringir a uma declaração de “tal e tal entrada acabará por produzir tal e tal estado final”, então suas chances de uma “prova livre de erros” são melhores, porque você pode usar invariantes . Isso, e apenas isso, permite que uma prova de correção seja dividida em subproblemas, cada um dos quais pode ser comprovado com relativa facilidade para funcionar corretamente em todas as circunstâncias do programa restante (embora você geralmente não possa “ser muito preciso sobre quanto tempo & de memória pode levar).
Essas técnicas são basicamente possíveis em qualquer linguagem de programação (embora algumas linguagens esotéricas como Malbolge tentem desfazer isso !), mas em todas as linguagens imperativas fica confuso muito rapidamente, porque você tem que controlar meticulosamente muitos estado implícito do programa. Em linguagens funcionais 1 , as provas tendem a parecer muito mais agradáveis ( linguagens puras ou o subconjunto puramente funcional de uma linguagem). Ainda assim, em particular com tipos dinâmicos, você precisará escrever muitos requisitos sobre quais entradas são permitidas. É claro que esse é um dos principais benefícios dos sistemas de tipo estático forte: os requisitos estão bem ali no código!
Bem, idealmente, isto é. Na prática, programas O “Caml ou mesmo Haskell tendem a conter funções não totais , isto é, funções que irão travar / travar / lançar para certas entradas, apesar do tipo correto 2 . Porque, embora essas linguagens tenham sistemas de tipos muito flexíveis, às vezes ainda não é viável usá-las para restringir algo totalmente.
Insira linguagens com tipos dependentes ! Eles podem “calcular” os tipos precisamente conforme necessário, então tudo que você definir pode ter exatamente a assinatura de tipo que prova tudo o que você precisa. E, de fato, as linguagens com tipos dependentes são principalmente ensinados como ambientes de prova . Infelizmente, acho que nenhum deles está realmente apto a escrever software de produção. Para aplicações práticas, acho que o mais próximo que você pode chegar da completamente à prova de bugs é escrever em Haskell com funções tão completas quanto possível. Isso deixa você bem perto da à prova de bugs – embora, novamente, apenas no que diz respeito à descrição funcional. Haskell “A maneira única de lidar com IO com mônadas também fornece algumas provas muito úteis, mas geralmente não diz nada sobre quanto tempo algo levará para Finalizar. Muito possivelmente, algo pode demorar um tempo exponencial em circunstâncias particulares – do POV do usuário, o que provavelmente seria um bug tão grave como se o programa travasse completamente.
1 Ou mais geralmente, linguagens descritivas . Não tenho muita experiência com linguagens lógicas, mas suponho que possam ser igualmente boas na prova Atenciosamente.
2 Se não for do tipo correto, o compilador nunca o permitirá nessas linguagens; isso já elimina muitos bugs. (E, graças à inferência de tipo de Hindley-Milner, na verdade torna os programas mais concisos também!)
Comentários
- " Se você quer dizer, um programa interativo onde você precisa ter certeza de que o comportamento em tempo real é exatamente tal e tal em qualquer circunstância, então ' é basicamente impossível provar que não há ' quaisquer bugs iniciar. Suponho que seria possível se você pudesse resolver o problema da parada, mas você pode ' t. ": Não tenho certeza se isso declaração está correta. É impossível verificar um programa arbitrário , mas e um programa que você escreveu de uma forma que permite tal verificação?
- Veja, por exemplo, cs.cmu.edu/~rwh/smlbook/book.pdf , no início da página 198: " Por fim, é importante observar que especificação, implementação e verificação andam de mãos dadas. É irrealista propor a verificação de que uma parte arbitrária de código satisfaz uma especificação arbitrária. Os resultados fundamentais da computabilidade e complexidade deixam claro que nunca teremos sucesso em tal empreendimento. Felizmente, também é totalmente artificial. Na prática, especificamos, codificamos e verificamos simultaneamente, com cada atividade informando a outra."
- @Giorgio: claro que você pode escrever alguns programas de uma forma que permita tal verificação , mas isso realmente o restringe bastante muito. Em um grande programa, você ' quase sempre precisará explorar a integridade de Turing em algum lugar. – Sim, na prática você especifica, codifica e " verifica " simultaneamente, mas essa verificação é frequentemente heurística suficiente (com base, por exemplo, em testes de unidade , não são provas reais).
- O que você quer dizer com " explorar a integridade de Turing "?
- " … mas essa verificação é frequentemente heurística suficiente (com base, por exemplo, em testes de unidade, não em provas reais) ": Não , se você ler as notas com atenção, fala sobre como provar a correção por meio de métodos formais (por exemplo, usando indução), não fala sobre testes de unidade. Veja também compcert.inria.fr/doc .