Por que Cem Kaner considera um teste que não revela um bug como uma perda de tempo?


15

Que tal confirmar a funcionalidade em testes positivos, provar que está funcionando - devo dizer que é uma perda de tempo? Que tipo de conceito está por trás dessa citação?

Testes malsucedidos, ou seja, testes que não encontram erros, são perda de tempo.

Engenharia da Web: a disciplina de desenvolvimento sistemático de aplicativos da Web citando Cem Kaner .


2
Na verdade não. Kaner afirma que, em geral, o teste deve apenas encontrar defeitos.
John V

4
Essa é uma posição muito acadêmica. Kaner e Schrödinger precisam se sentar para tomar um café em algum momento.
Blrfl 22/03

2
O único problema da @Blrfl é que o Sr. Schrödinger está morto. Oh, espera ... um ...
ikmac

1
Essa declaração, sem contexto soa incrivelmente tola ...
Rig

1
"Confirmando a funcionalidade em testes positivos" - isso é fundamentalmente impossível. Você não pode provar algo correto, só pode provar errado.
Konrad Rudolph

Respostas:


37

Eu escrevi a maior parte do Testing Computer Software há mais de 25 anos. Desde então, apontei para várias partes do livro que considero desatualizadas ou simplesmente erradas. Consulte http://www.kaner.com/pdfs/TheOngoingRevolution.pdf

Você pode ver mais (visualizações atuais, mas sem indicadores explícitos de volta ao TCS) no meu site para o Curso de Teste de Software da Caixa Preta (vídeos e slides disponíveis gratuitamente), www.testingeducation.org/BBST

A cultura de teste naquela época era amplamente confirmatória.

Nos testes modernos, a abordagem dos testes de unidade é amplamente confirmatória - escrevemos grandes coleções de testes automatizados que simplesmente verificam se o software continua a funcionar como pretendido. Os testes servem como detectores de alterações - se algo em outras partes do código e esta parte agora apresentar problemas, ou se valores de dados que antes eram impossíveis no mundo real agora estão chegando ao aplicativo, os detectores de alterações são acionados, alertando o programador para um problema de manutenção.

Eu acho que a mentalidade confirmatória é apropriada para testes unitários, mas imagine um mundo em que todos os testes do sistema foram confirmatórios (para pessoas que fazem uma distinção, interprete "testes de integração do sistema" e "testes de aceitação", conforme incluído nos meus comentários sobre o sistema O objetivo do teste era confirmar que o programa atendia às especificações e a abordagem dominante era criar um zilhão (ou pelo menos algumas centenas) de testes de regressão no nível do sistema que mapeou partes da especificação para os comportamentos do programa. (Acho que a confirmação de especificação de comportamento é útil, mas acho que é uma pequena parte de um objetivo maior.)

Ainda existem grupos de teste que operam dessa maneira, mas essa não é mais a visão dominante. Naquela época, era. Escrevi enfaticamente e desenhei contrastes nítidos para destacar pessoas que estavam constantemente sendo treinadas nessa mentalidade. Hoje, alguns dos contrastes acentuados (incluindo o citado aqui) estão desatualizados. Eles são mal interpretados como ataques a visões erradas.

A meu ver, o teste de software é um processo empírico para aprender informações relacionadas à qualidade sobre um produto ou serviço de software.

Um teste deve ser projetado para revelar informações úteis.

Naquela época, a propósito, ninguém falava sobre o teste como um método para revelar "informações". Naquela época, o teste era para (alguma versão de ...) encontrar bugs ou para (alguma versão de ...) verificar (verificar) o programa em relação às especificações. Eu não acho que a afirmação de que os testes são para revelar informações úteis entrou no vocabulário dos testes até este século.

Imagine testes de classificação em termos do valor das informações. Um teste que provavelmente nos ensinará algo que não sabemos sobre o software teria um valor muito alto para as informações. Um teste que provavelmente confirmará algo que já esperamos e que já foi demonstrado muitas vezes antes, teria um valor baixo de informações. Uma maneira de priorizar testes é executar testes de maior valor de informação antes de testes de menor valor de informação.

Se eu simplificasse demais essa priorização para atrair a atenção de um programador, gerente de projetos ou gerente de processos que não tem noção do teste de software, eu diria "UM TESTE QUE NÃO É PROJETADO PARA REVELAR UM ERRO É UMA PERDA DE TEMPO . " Não é uma tradução perfeita, mas para os leitores que não conseguem ou não entenderão nenhuma sutileza ou qualificação, é o mais próximo possível.

Naquela época, e vejo novamente aqui, algumas das pessoas que não entendem o teste responderiam que um teste projetado para encontrar casos de esquina é uma perda de tempo em comparação com um teste do uso principal de uma função principal. Eles não entendem duas coisas. Primeiro, quando os testadores encontram tempo para verificar os valores-limite, os principais usos das principais funções já foram exercidos várias vezes. (Sim, existem exceções, e a maioria dos grupos de testes prestará muita atenção a essas exceções.) Segundo, o motivo para testar com valores extremos é que o programa tem maior probabilidade de falhar com valores extremos. Se não falhar ao extremo, você testa outra coisa. Esta é uma regra eficiente. Por outro lado, se falhar em um valor extremo, o testador poderá parar e relatar um erro ou o testador poderá solucionar problemas ainda mais, para ver se o programa falha da mesma maneira em valores mais normais. Quem faz essa solução de problemas (o testador ou o programador) é uma questão de cultura corporativa. Algumas empresas planejam o tempo do testador para isso, outras planejam os programadores e outras esperam que os programadores corrijam erros de maiúsculas ou minúsculas, sejam eles generalizáveis ​​ou não, para que a solução de problemas não seja relevante. O mal-entendido comum - que os testadores estão perdendo tempo (em vez de maximizar a eficiência) testando valores extremos é outro motivo pelo qual "Um teste que não foi projetado para revelar um bug é uma perda de tempo" é uma mensagem apropriada para os testadores. É um contraponto ao incentivo de alguns programadores para (com efeito) nunca executar testes que possam desafiar o programa. A mensagem é simplificada demais, mas a discussão inteira é simplificada demais.

A propósito, "valor da informação" não pode ser o único sistema de priorização. Não é minha regra quando eu desenho suítes de teste de unidade. Não é minha regra quando eu designo testes de verificação de compilação (também conhecidos como verificações de sanidade). Nos dois casos, estou mais interessado nos tipos de cobertura do que no poder dos testes individuais. Existem outros casos (por exemplo, testes automatizados de alto volume que são baratos de configurar, executar e monitorar) em que o poder de testes individuais é simplesmente irrelevante para o meu projeto. Tenho certeza que você pode pensar em exemplos adicionais.

Mas, como regra geral, se eu pudesse declarar apenas uma regra (por exemplo, falar com um executivo cuja cabeça explode se ele tentar processar mais de uma frase), seria que um teste de baixo valor de informação é geralmente uma perda de tempo.


4
+1 por reservar um tempo para responder a uma pergunta da qual você é a fonte autorizada, além de validar meu uso do termo "Testes de verificação de compilação", para o qual tantas pessoas me acham engraçado de usar ... É sempre bom ver as pessoas de sua estatura tendo tempo para ajudar as pessoas por aqui
Jimmy Hoffa

1
Eric G: Eu acho que se você reler, verá Cem declarar que, como parte dos leitores, entender que sua visão sobre o assunto evoluiu ao longo do tempo. Ou você pode simplesmente continuar e ignorar sutileza e qualificações, parafraseando Cem. (E eu levo "qualificações" não como as suas credenciais, mas como exceções.)
Jim Holmes

Sua citação me lembra algo que observei sobre a ciência: não se pode provar (ou mesmo apoiar significativamente) uma teoria científica, realizando experimentos que se espera que produzam resultados consistentes com a teoria; a maneira de apoiar uma teoria é fazer um esforço genuíno para realizar experimentos com dispositivos que não a sustentem, mas sendo incapaz de fazê-lo.
Supercat

@ supercat, você pode apoiar uma teoria com um teste para algo consistente com a teoria, se o teste não lhe tivesse ocorrido antes da teoria (por exemplo, mostrar a aceleração de um objeto caindo no vácuo é como você calcularia que seria) diz mais do que mostrar que cai). Os testes de casos extremos são análogos; Eu poderia esperar que o software se comportasse corretamente ao lidar com valores extremos, mas ele dá mais confiança na qualidade de ver isso acontecer do que repetir os valores de entrada que ele provavelmente viu durante o desenvolvimento, além de ter maior probabilidade de encontrar um bug.
Jon Hanna

@ JonHanna: Meu fraseado foi ruim: o problema não é expectativa, mas esforço. Não se pode provar uma teoria tentando encontrar testes nos quais ela passará; é preciso fazer um esforço genuíno para encontrar testes que falhariam se inválidos.
Supercat

11

A idéia é, de acordo com Kaner, "como o tempo se esgota antes dos casos de teste, é essencial usar o tempo disponível da maneira mais eficiente possível".

O conceito por trás da citação que você pergunta é apresentado e explicado em detalhes no artigo Testing Computer Software de Cem Kaner , Jack Falk, Hung Quoc Nguyen, no capítulo "OS OBJETIVOS E LIMITES DO TESTE":

Então, por que testar?

Você não consegue encontrar todos os erros. Você não pode provar que o programa está correto e não deseja. É caro, frustrante e não ganha nenhum concurso de popularidade. Então, por que se preocupar em testar?

O objetivo de testar um programa é encontrar problemas nele

Encontrar problemas é o núcleo do seu trabalho. Você deve encontrar o maior número possível; quanto mais sério o problema, melhor.

Como você ficará sem tempo antes dos casos de teste, é essencial usar o tempo disponível da maneira mais eficiente possível. Os capítulos 7,8,12 e 13 consideram as prioridades em detalhes. O princípio orientador pode ser colocado simplesmente:


Um teste que revela um problema é um sucesso. Um teste que não revelou um problema foi uma perda de tempo.


Considere a seguinte analogia, de Myers (1979). Suponha que algo esteja errado com você. Você vai ao médico. Ele deve executar testes, descobrir o que há de errado e recomendar ações corretivas. Ele executa teste após teste após teste. No final de tudo, ele não consegue encontrar nada errado. Ele é um grande testador ou um diagnosticador incompetente? Se você está realmente doente, ele é incompetente, e todos esses testes caros foram uma perda de tempo, dinheiro e esforço. No software, você é o diagnosticador. O programa é o paciente (seguramente) doente ...


Veja, o ponto acima é que você deve priorizar seus testes com sabedoria. Espera-se que o teste leve um tempo limitado e é impossível testar tudo no tempo determinado.

Imagine que você passou um dia (semana, mês) executando testes, não encontra bugs e deixa alguns bugs passarem porque você não teve tempo de executar um teste que o revelasse. Se isso acontecer, você não pode simplesmente dizer "não é minha culpa porque eu estava ocupado executando outros testes" para justificar essa falha - se você diz, ainda será responsabilizado.

Você perdeu tempo executando testes que não revelavam erros e, por causa disso, perdeu um teste que encontraria um erro.

(No caso, se você quer saber, acidentes como acima são geralmente inevitável, não importa o quanto tente, e há são maneiras de lidar com estes, mas que seria mais um tópico para uma outra questão ... e, provavelmente, um ajuste melhor para SQA. SE.)


12
Essa resposta representa corretamente sua posição, mas vale ressaltar que muitas pessoas pensam que sua posição está errada. Dada a escolha entre um teste que demonstra a função mais importante no aplicativo funciona corretamente (teste de aceitação, se você preferir) e um teste que encontra um bug trivial (alinhamento de um pixel) em um canto raramente usado do aplicativo, eu saber qual eu escolheria no meu tempo limitado. E para a analogia do médico: se eu vou fazer um check-in em vez de responder aos sintomas, confirmar o coração é bom, os pulmões são bons etc. etc é um bom resultado. Tão aí.
Kate Gregory

@KateGregory Concordo, penso o mesmo. I persoanlly encontrar seu erro opinião, testamos principalmente para reunir informações ..
John V

2
@KateGregory concorda - não acho correto rotular qualquer teste aprovado como um desperdício total. No entanto, acho que um ponto que ele ressalta é atemporal : se o bug passar pelos testes de lançamento, o controle de qualidade precisaria de algo mais do que "ah, mas estávamos ocupados executando outros testes" para protegê-los. Eu já passei por isso como um testador de mim mesmo no passado, e ver isso em torno de agora que eu sou um desenvolvedor, e eu não acho que isso nunca desvanece-se vai longe
mosquito

4

Bem, eu não sei o Sr. Caner, mas IMHO

testes que não potencialmente encontram erros

são uma perda de tempo. Isso inclui a situação em que você já possui alguns testes (não importa se eles são automáticos ou apenas em uma lista de verificação) e você adiciona novos testes que validam essencialmente os mesmos casos que você já possui. Portanto, seus novos testes não encontrarão mais erros do que os existentes.

Essa situação pode acontecer, por exemplo, se você apenas passar por uma lista de aleatoriamente - eu poderia dizer também "sem cérebro" (me perdoe essa palavra) - escolher casos de teste em seu programa, sem pensar se eles verificam novos casos extremos, novas equivalências classes de seus dados de entrada ou se eles aumentam a cobertura do código em relação aos testes já escritos.


-1

Na minha opinião, esta citação refere-se a testes muito gerais ou não confiáveis.

Se você faz um teste para uma função que valida e-mails e, no teste, fornece apenas e-mails válidos, esse teste é completamente inútil. Você precisaria testar esta função para "qualquer" sequência de caracteres possível, e-mails inválidos, e-mails muito longos, caracteres unicode (á ....).

Se você codificar um teste que verifica apenas se name@dom.com retorna true e name @ com retorna false, esse teste é o mesmo de nenhum teste.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.