Catálogo de antipadrões de teste de unidade

203

anti-padrão : deve haver pelo menos dois elementos-chave presentes para distinguir formalmente um anti-padrão real de um simples mau hábito, má prática ou má idéia:

  • Algum padrão repetido de ação, processo ou estrutura que inicialmente parece ser benéfico, mas que em última análise produz mais más conseqüências do que resultados benéficos, e
  • Uma solução refatorada que está claramente documentada, comprovada na prática real e repetível.

Vote no anti-padrão TDD que você já viu "em estado selvagem" uma vez demais.
A postagem do blog de James Carr e a discussão relacionada no yahoogroup testdrivendevelopment

Se você encontrou um 'sem nome', poste-o também. Uma postagem por anti-padrão, por favor, para fazer valer os votos de alguma coisa.

Meu interesse é encontrar o subconjunto top-n para que eu possa discuti-los em uma lanchonete no futuro próximo.

Gishu
fonte
Aaron, você parece estar por toda parte :) :) Seria uma boa ideia adicionar as linhas de tag ou slogans como comentários para que possamos ter menos rolagem .. o que dizer?
Gishu 02/12/08
1
Isso está chegando muito bem .. obrigado rapazes n galões. Mantenha-os chegando .. um dos posts mais informativos do SO IMHO
Gishu 04/12/2008
2
+1 adoro esse tópico !!! E a maioria delas também é verdadeira e prevalece!
Chii
Bom tópico, por que esse wiki da comunidade?
Quibblesome 17/04
2
Porque é uma espécie de enquete - você não gostaria de colher representantes apenas porque você postou o tipo mais comum de anti-padrão;) #
308

Respostas:

70

Cidadãos de segunda classe - o código de teste não é tão refatorado quanto o código de produção, contendo muito código duplicado, dificultando a manutenção dos testes.

Ilja Preuß
fonte
67

The Free Ride / Piggyback - James Carr, Tim Ottinger
Em vez de escrever um novo método de caso de teste para testar outro / recurso / funcionalidade distinta , uma nova asserção (e suas ações correspondentes, por exemplo, executar etapas do AAA) é executada em um caso de teste existente .

Aaron Digulla
fonte
15
Sim, esse é o meu favorito. Eu faço isso o tempo todo. Oh ... espere ... você disse que isso era uma coisa ruim . :-)
guidoism
1
Não tenho tanta certeza de que isso seja um antipadrão. Todos os invariantes devem estar trueapós cada chamada possível do mutador. Portanto, você deve verificar se todas as invariantes estão trueapós cada combinação de dados do mutador e de entrada que você está testando. Mas você deseja reduzir a duplicação e garantir a verificação de todos os invariantes, incluindo aqueles que atualmente não causam falhas no teste. Então você coloca todos eles em uma checkInvariants()função de verificação e a usa em todos os testes. O código muda e outra invariante é adicionada. Você coloca isso na função também, é claro. Mas é um freerider.
Raedwald 27/01
2
@ Raedwald - Com o tempo, o nome do teste não corresponde mais a todas as coisas que ele testa. Além disso, você tem alguns problemas devido a testes entrelaçados; uma falha não indica a causa exata da falha. por exemplo, um exemplo canônico deste teste seria algo como Opaque Superset de todas as etapas da organização >> Agir >> Afirmar A >> Agir mais >> Afirmar B >> Agir mais >> Afirmar C. Agora, idealmente, se A e C são quebrado, você verá 2 falhas no teste. Com o teste acima, você veria apenas um, depois fixaria A e na próxima execução, diria que agora C está quebrado. agora imagine 5-6 testes distintos fundidos ..
Gishu 28/01
1
"o nome do teste não corresponde mais a todos os itens testados" Somente se o teste for nomeado para a condição posterior que estava originalmente presente. Se você nomear a combinação de nome do método, estado da configuração e dados de entrada (argumentos do método), não há problema.
Raedwald 28/01
"uma falha não indica a causa exata da falha" nenhuma falha de afirmação indica a causa de uma falha. Isso requer alguns detalhes dos detalhes da implementação: depuração para uma falha de regressão, seu conhecimento do estado de desenvolvimento de algum trabalho do TDD.
Raedwald 28/01
64

Caminho feliz

O teste permanece em caminhos felizes (ou seja, resultados esperados) sem testar limites e exceções.

Antipatterns JUnit

geoglifo
fonte
Causa: restrições de tempo exageradas ou preguiça flagrante. Solução refatorada: reserve algum tempo para escrever mais testes para se livrar dos falsos positivos. A última causa precisa de um chicote. :)
Spoike 15/12/08
59

O herói local

Um caso de teste que depende de algo específico para o ambiente de desenvolvimento em que foi gravado para ser executado. O resultado é que o teste passa nas caixas de desenvolvimento, mas falha quando alguém tenta executá-lo em outro lugar.

A dependência oculta

Intimamente relacionado ao herói local, um teste de unidade que exige que alguns dados existentes tenham sido preenchidos em algum lugar antes da execução do teste. Se esses dados não foram preenchidos, o teste falhará e deixará pouca indicação para o desenvolvedor o que ele queria, ou por quê ... forçando-os a vasculhar acres de código para descobrir de onde os dados que estavam usando deveriam vir.


Tristemente visto isso muitas vezes com .dlls antigas que dependem de arquivos .ini nebulosos e variados, que estão constantemente fora de sincronia em qualquer sistema de produção, e muito menos em sua máquina, sem uma consulta extensa com os três desenvolvedores responsáveis ​​por essas dlls. Suspiro.

annakata
fonte
Esse é um bom exemplo do acrônimo de desenvolvedor do WOMPC. "Funciona no meu PC!" (geralmente dito para obter testadores fora de suas costas.)
Joris Timmermans
58

Gangue das correntes

Alguns testes que devem ser executados em uma determinada ordem, ou seja, um teste altera o estado global do sistema (variáveis ​​globais, dados no banco de dados) e o (s) próximo (s) teste (s) dependem disso.

Você costuma ver isso nos testes do banco de dados. Em vez de fazer uma reversão teardown(), os testes confirmam suas alterações no banco de dados. Outra causa comum é que as alterações no estado global não são agrupadas em blocos try / finalmente, que são limpos se o teste falhar.

Aaron Digulla
fonte
este é simplesmente desagradável. Os testes devem ser independentes. Mas eu li sobre isso em vários lugares .. acho que o 'TDD popular' está bem bagunçado #
587
56

A
zombaria Às vezes, zombar pode ser bom e prático. Mas, às vezes, os desenvolvedores podem se perder e em seu esforço para zombar do que não está sendo testado. Nesse caso, um teste de unidade contém tantas zombarias, stubs e / ou falsificações que o sistema sob teste nem sequer está sendo testado, mas os dados retornados das zombarias são o que está sendo testado.

Fonte: publicação de James Carr.

Gishu
fonte
2
Acredito que a causa disso é que sua classe em teste tem muitas dependências. A alternativa refatorada é extrair o código que pode ser isolado.
Spoike
@Spoike; Se você estiver em uma arquitetura em camadas, isso realmente depende do papel da classe; algumas camadas tendem a ter mais dependências do que outras.
Krossenvold
Vi recentemente, em um blog respeitado, a criação de uma configuração de entidade simulada a ser retornada de um repositório simulado. WTF? Por que não instanciar uma entidade real em primeiro lugar. Eu mesmo, acabei de ser queimado por uma interface falsa, na qual minha implementação estava lançando NotImplementedExceptions por toda parte.
6116 Thomas Eyde
40

O Apanhador Silencioso - Kelly?
Um teste que passa se uma exceção é lançada. Mesmo que a exceção que realmente ocorre seja diferente da que o desenvolvedor pretendia.
Veja também: Apanhador Secreto

[Test]
[ExpectedException(typeof(Exception))]
public void ItShouldThrowDivideByZeroException()
{
   // some code that throws another exception yet passes the test
}
Gishu
fonte
Essa é complicada e perigosa (ou seja, faz você pensar que testou código que sempre explode toda vez que é executado). É por isso que tento ser específico sobre uma classe de exceção e sobre algo único na mensagem.
Joshua Cheek
34

O Inspetor
Um teste de unidade que viola o encapsulamento em um esforço para obter 100% de cobertura de código, mas sabe tanto sobre o que está acontecendo no objeto que qualquer tentativa de refatorar interromperá o teste existente e exigirá que qualquer alteração seja refletida na unidade teste.


'como testar minhas variáveis ​​de membro sem torná-las públicas ... apenas para teste de unidade?'

Gishu
fonte
2
Causa: Confiança absurda nos testes de caixa branca. Existem ferramentas para gerar esse tipo de teste como o Pex no .NET. Solução refatorada: teste o comportamento e, se realmente precisar verificar os valores-limite, deixe as ferramentas automatizadas gerarem o restante.
Spoike
1
Antes que Moq aparecesse, tive que abandonar estruturas de zombaria em favor da escrita manual de minhas zombarias. Era muito fácil vincular meus testes à implementação real, tornando quase impossível qualquer refatoração. Não sei dizer a diferença, além do Moq, raramente cometi esse tipo de erro.
6116 Thomas Eyde
34

Configuração excessiva - James Carr
Um teste que requer uma configuração enorme para iniciar o teste. Às vezes, várias centenas de linhas de código são usadas para preparar o ambiente para um teste, com vários objetos envolvidos, o que pode dificultar realmente a verificação do que é testado devido ao "ruído" de toda a instalação em andamento. (Src: publicação de James Carr )

Gishu
fonte
Entendo que a configuração excessiva do teste geralmente aponta para a) código mal estruturado ou b) zombaria insuficiente, correto?
precisa
Bem, cada situação pode ser diferente. Pode ser devido ao alto acoplamento. Mas geralmente é um caso de superespecificação, especificando (falsas expectativas) todo e qualquer colaborador no cenário - isso acopla o teste à implementação e os torna frágeis. Se a chamada para o colaborador for um detalhe incidental do teste, ela não deverá estar no teste. Isso também ajuda a manter o teste curto e legível.
Gishu
32

Sonda Anal

Um teste que precisa usar maneiras insanas, ilegais ou prejudiciais para executar sua tarefa, como: Ler campos privados usando setAccessible (true) do Java ou estender uma classe para acessar campos / métodos protegidos ou ter que colocar o teste em um determinado pacote para acessar empacotar campos / métodos globais.

Se você vir esse padrão, as classes em teste usarão muitos dados ocultos.

A diferença entre isso e o Inspetor é que a classe em teste tenta ocultar até o que você precisa testar. Portanto, seu objetivo não é atingir 100% de cobertura de teste, mas ser capaz de testar qualquer coisa. Pense em uma classe que possui apenas campos particulares, um run()método sem argumentos e sem getters. Não há como testar isso sem violar as regras.


Comentário de Michael Borgwardt: Este não é realmente um antipadrão de teste, é pragmatismo lidar com deficiências no código que está sendo testado. É claro que é melhor corrigir essas deficiências, mas isso pode não ser possível no caso de bibliotecas de terceiros.

Aaron Digulla: Eu meio que concordo. Talvez essa entrada seja realmente mais adequada para um wiki "JUnit HOWTO" e não para um antipadrão. Comentários?

Aaron Digulla
fonte
não é o mesmo que o inspetor?
Gishu
1
Hmm .. essa linha 'a classe em teste tenta ocultar até as coisas que você precisa testar' indica uma disputa de poder entre a classe e o teste. Se deveria ser testado .. deveria estar publicamente acessível de alguma maneira .. via comportamento / interface de classe .. isso cheira de alguma forma ao rompimento do encapsulamento #
584
2
npellow: Maven2 tem um plugin para isso, não tem?
Aaron Digulla 04/12/08
1
Este não é realmente um antipadrão de teste, é pragmatismo lidar com deficiências no código que está sendo testado. É claro que é melhor corrigir essas deficiências, mas isso pode não ser possível no caso de bibliotecas de terceiros.
Michael Borgwardt
1
IDK, deve ter algum tipo de efeito colateral. Eu testaria o efeito colateral. Não tendo certeza do que você quer dizer sobre o teste da API de terceiros, eu diria que você deve agrupar em seu próprio código que você pode testar se foi usado corretamente e testar a integração com esse código na API de terceiros. Não testaria em unidade o código de terceiros.
Joshua Cheek
26

O teste sem nome - Nick Pellow

O teste adicionado para reproduzir um erro específico no rastreador de erros e cujo autor acha que não garante um nome próprio. Em vez de aprimorar um teste que falta, é criado um novo teste chamado testForBUG123.

Dois anos depois, quando esse teste falhar, talvez seja necessário primeiro tentar encontrar o BUG-123 no rastreador de bugs para descobrir a intenção do teste.

npellow
fonte
7
Tão verdade. Tho que é um pouco mais útil do que um teste chamado "TestMethod"
NikolaiDante 3/08/08
8
a menos que as alterações BugTracker, e você solta a velha rastreador e seus identificadores de emissão ... então PROJECT-123 já não significa nada ....
Chii
25

O puxão lento

Um teste de unidade que é incrivelmente lento. Quando os desenvolvedores começam, eles têm tempo para ir ao banheiro, fumar um cigarro ou, pior ainda, iniciar o teste antes de voltarem para casa no final do dia. (Src: publicação de James Carr )

aka os testes que não serão executados com a frequência que deveriam

Gishu
fonte
Alguns testes são executados lentamente por sua própria natureza. Se você decidir não executá-los com a mesma frequência que os outros, verifique se eles executam pelo menos o mais rápido possível em um servidor de IC.
Chris Vest
Esta é uma pergunta óbvia, mas quais são as formas mais gerais de corrigir isso?
Topher Hunt
Isso inicialmente parece benéfico, não é?
Kev
1
@TopherHunt Normalmente, os testes são lentos porque têm alguma dependência cara (sistema de arquivos, banco de dados). O truque é analisar as dependências até que você veja o problema e, em seguida, empurre a dependência para cima da pilha de chamadas. Eu escrevi um estudo de caso em que meus alunos teve sua suíte de teste de unidade de 77 segundos para 0.01 segundos fixando suas dependências: github.com/JoshCheek/fast_tests
Joshua Cheek
20

A borboleta

Você precisa testar algo que contém dados que mudam o tempo todo, como uma estrutura que contém a data atual, e não há como fixar o resultado em um valor fixo. A parte feia é que você não se importa com esse valor. Isso apenas torna seu teste mais complicado sem agregar nenhum valor.

O bastão de sua asa pode causar um furacão do outro lado do mundo. - Edward Lorenz, O Efeito Borboleta

Aaron Digulla
fonte
Qual é o anti-padrão aqui: como é um teste como esse? Existe uma correção? Existe alguma vantagem discutível no código em teste para fatorar uma dependência como System.DateTime.Now, além de ter testes de unidade mais simples ou mais determinísticos?
Merlyn Morgan-Graham
1
Em Java, um exemplo seria chamar toString()um objeto que não sobrescreva o método. Isso fornecerá o ID do objeto que depende do endereço da memória. Ou toString()contém a chave primária do objeto e isso muda toda vez que você executa o teste. Existem três maneiras de corrigir isso: 1. Altere o código que você está testando, 2. usando o regexp para remover as partes variáveis ​​dos resultados do teste ou 3. use ferramentas poderosas para substituir os serviços do sistema e fazê-los retornar resultados previsíveis.
Aaron Digulla
A causa subjacente desse antipadrão é que o código em teste não se importa com o esforço necessário para testá-lo. Portanto, o capricho de um desenvolvedor é a asa da borboleta que causa problemas em outros lugares.
Aaron Digulla
19

O teste de cintilação (fonte: Romilly Cocking)

Um teste que apenas falha ocasionalmente, não em horários específicos, e geralmente é devido às condições da corrida dentro do teste. Geralmente ocorre ao testar algo assíncrono, como JMS.

Possivelmente um super set para o antipadrão ' Wait and See ' e o antipadrão ' The Sleeper '.

A construção falhou, tudo bem, basta executar a construção novamente. - Desenvolvedor Anônimo

Stuart
fonte
@Stuart - um vídeo imperdível descrevendo isso como "Carro parado - Experimente agora!" videosift.com/video/… Esse padrão também pode ser chamado de "Try Now!", ou apenas - "The Flakey Test"
npellow 4/08/08
1
Certa vez, escrevi um teste para um PRGN que assegurava uma distribuição adequada. Ocasionalmente, falhava aleatoriamente. Vai saber. :-)
Chris Vest
1
Isso não seria um bom teste? Se um teste falhar, você precisará rastrear a origem do problema. Eu lutei com alguém sobre um teste que falhou entre 9 e meia-noite. Ele disse que era aleatório / intermitente. Eventualmente, foi atribuído a um bug que lida com fusos horários. Vai saber.
22430 Trenton
@ Christian Vest Hansen: você não pode semear?
Andrew Grimm
@trenton É apenas um bom teste se os desenvolvedores puderem se incomodar em localizá-lo, em vez de simplesmente ignorá-lo (com o qual eles podem se safar, pois passa a maior parte do tempo).
Will Sheppard
19

Espere e veja

Um teste que executa algum código de configuração e precisa "aguardar" uma quantidade específica de tempo antes de poder "ver" se o código em teste funcionou como esperado. Um testMethod que usa Thread.sleep () ou equivalente é certamente um teste "Aguarde e veja".

Normalmente, você pode ver isso se o teste estiver testando código que gera um evento externo ao sistema, como um email, uma solicitação http ou grava um arquivo no disco.

Esse teste também pode ser um Herói Local, pois falhará quando executado em uma caixa mais lenta ou em um servidor de IC sobrecarregado.

O anti-padrão Wait and See não deve ser confundido com The Sleeper .

npellow
fonte
Hmm .. bem, eu uso algo assim. de que outra forma eu seria capaz de testar o código multiencadeado?
Gishu 04/12/08
@ Gishu, você realmente deseja testar a unidade vários threads em execução simultaneamente? Tento apenas testar a unidade, independentemente do método run (), isoladamente. Uma maneira fácil de fazer isso é chamar run () - que bloqueará, em vez de start () do teste de unidade.
Npellow
O @Gishu usa CountDownLatches, Semáforos, Condições ou similares, para que os threads digam um ao outro quando podem passar para o próximo nível.
Chris Vest
Um exemplo: madcoderspeak.blogspot.com/2008/11/… Botão Brew evt. O observador está pesquisando a intervalos e gerando eventos alterados. Nesse caso, adiciono um atraso para que os threads de pesquisa tenham a chance de executar antes que o teste termine.
Gishu 04/12/08
Eu acho que o link dos desenhos animados está quebrado.
Andrew Grimm
17

Dispositivo
elétrico compartilhado de forma inadequada - Tim Ottinger Vários casos de teste no dispositivo de teste nem usam nem precisam de configuração / desmontagem. Em parte devido à inércia do desenvolvedor para criar um novo equipamento de teste ... é mais fácil adicionar mais um caso de teste à pilha

Gishu
fonte
1
Também pode ser que a classe em teste esteja tentando fazer muito.
Mike Two
16

O gigante

Um teste de unidade que, embora esteja testando validamente o objeto em teste, pode abranger milhares de linhas e conter muitos casos de teste. Isso pode ser um indicador de que o sistema em teste é um objeto de Deus (post de James Carr).

Um sinal claro para este é um teste que abrange mais de algumas linhas de código. Freqüentemente, o teste é tão complicado que começa a conter erros de comportamento próprio ou escamoso.

Gishu
fonte
15

Acredito nisso quando vejo algumas GUIs intermitentes
Uma obsessão / fixação doentia em testar o aplicativo por meio da GUI 'exatamente como um usuário real'

Testar regras de negócios por meio da GUI é uma forma terrível de acoplamento. Se você escrever milhares de testes através da GUI e depois alterar sua GUI, milhares de testes serão interrompidos.
Em vez disso, teste apenas as coisas da GUI através da GUI e associe a GUI a um sistema fictício, em vez do sistema real, quando você executar esses testes. Teste as regras de negócios por meio de uma API que não envolve a GUI. - Bob Martin

"Você deve entender que ver é acreditar, mas também saber que acreditar é ver." - Denis Waitley

Gishu
fonte
1
Se você achou que as GUIs intermitentes estavam erradas, vi alguém que escreveu um teste do jUnit que iniciou a GUI e precisava da interação do usuário para continuar. Pendurou o resto da suíte de testes. Tanta coisa para automação de teste!
Spoike
Discordo. Os testes das interfaces gráficas são difíceis, mas também são uma fonte de erros. Não testá-los é apenas preguiçoso.
Ray
3
o ponto aqui é que você não deve testar as GUIs, mas sim que não deve testar apenas através da GUI. Você pode executar testes 'decapitados' sem a GUI. Mantenha a GUI o mais fina possível - use uma variedade de MVP - você poderá se safar sem testá-la. Se você achar que há bugs aparecendo na camada fina da GUI o tempo todo, cubra-a com testes ... mas na maioria das vezes, acho que não vale a pena o esforço. Os erros de 'fiação' da GUI geralmente são mais fáceis de corrigir ... #
309
@Spoike: os testes manuais guiados não são ruins, nem o jUnit (ou qualquer outra estrutura de teste de unidade) para conduzir testes automatizados que não são testes de unidade. Você simplesmente não deve colocá-los no mesmo projeto, nem tratá-los como testes de unidade (por exemplo, executar constantemente ou após cada compilação).
Merlyn Morgan-Graham
1
@ MerlynMorgan-Graham, eu concordo e não quis dizer que você não deve testar a GUI. A convicção dos membros da equipe de que não havia problema em misturar testes manuais guiados com automáticos, estava me perturbando. Descobri mais tarde que era uma excelente maneira de fazer com que todos os que não estão acostumados ao TDD parassem de usá-lo. Acho que misturar testes funcionais (que são voláteis) com testes de unidade (que deveriam ser estáveis) é ruim se você deseja seguir o processo TDD.
Spoike
14

O dorminhoco, também conhecido como Monte Vesúvio - Nick Pellow

Um teste destinado a FAIL em alguma hora e data específica no futuro. Isso geralmente é causado pela verificação incorreta dos limites ao testar o código que usa um objeto Data ou Calendário. Às vezes, o teste pode falhar se for executado em um horário muito específico do dia, como meia-noite.

'O dorminhoco' não deve ser confundido com o antipadrão ' Esperar e ver '.

Esse código será substituído muito antes do ano 2000 - Muitos desenvolvedores em 1960

npellow
fonte
Eu prefiro chamar isso de Vulcão inativo :) .. mas eu sei do que você está falando .. por exemplo, uma data escolhida como uma data futura para um teste no momento da redação deste documento se tornará uma data presente / passada quando essa data passa .. quebrando o teste. Você poderia postar um exemplo .. apenas para ilustrar isso.
Gishu 04/12/08
@Gishu - +1. Eu estava pensando o mesmo, mas não conseguia decidir entre os dois. Eu atualizei o título para tornar isso um pouco mais claro;) #
04
11

A árvore morta

Um teste no qual um stub foi criado, mas o teste não foi realmente escrito.

Na verdade, eu vi isso em nosso código de produção:

class TD_SomeClass {
  public void testAdd() {
    assertEquals(1+1, 2);
  }
}

Eu nem sei o que pensar sobre isso.

Reverendo Gonzo
fonte
8
:) - também conhecido como Backdoor de conformidade de processos.
Gishu 11/11/2009
1
Tivemos um exemplo disso recentemente em um teste e método em teste que foram refatorados repetidamente. Após algumas iterações, o teste tornou-se uma chamada para o método em teste. E como o método agora retornou nulo, não havia nenhuma afirmação a ser afirmada. Então, basicamente, o teste estava apenas garantindo que o método não causasse uma exceção. Não importava se realmente fazia algo útil ou correto. Encontrei-o na revisão de código e perguntei: "Então ... o que estamos testando aqui?"
Marvo
11

hoje ficou pouco com isso:

Piso úmido :
o teste cria dados que são mantidos em algum lugar, mas o teste não é limpo quando concluído. Isso faz com que os testes (o mesmo teste ou possivelmente outros testes) falhem nas execuções de teste subsequentes .

No nosso caso, o teste deixou um arquivo no diretório "temp", com permissões do usuário que executou o teste pela primeira vez. Quando um usuário diferente tentou testar na mesma máquina: boom. Nos comentários no site de James Carr, Joakim Ohlrogge se referiu a isso como o "Sloppy Worker", e foi parte da inspiração para "Generous Leftovers". Gosto mais do meu nome (menos ofensivo, mais familiar).

Zac Thompson
fonte
Você pode usar a regra de pasta temporária do junit para evitar pisos molhados.
DaveFar
Isso se refere a um anti-padrão de integração contínua. No IC, todo desenvolvedor deve ter seu próprio espaço de trabalho e recursos, e a máquina de compilação também deve ser seu próprio ambiente. Então você evitar coisas como problemas de permissão (ou talvez você acaba escondendo-os para que eles só aparecem na produção.)
Marvo
11

The Cuckoo - Frank Carver
Um teste de unidade que fica em um caso de teste com vários outros e desfruta do mesmo processo de instalação (potencialmente demorado) que os outros testes no caso de teste, mas descarta alguns ou todos os artefatos da instalação e cria o seu próprio.
Sintoma avançado de: dispositivo elétrico compartilhado inadequadamente

Gishu
fonte
10

The Secret Catcher - Frank Carver
Um teste que, à primeira vista, parece não estar sendo testado, devido à ausência de afirmações. Mas "O diabo está nos detalhes" .. o teste realmente depende de uma exceção a ser lançada e espera que a estrutura de teste capture a exceção e a relate ao usuário como uma falha.

[Test]
public void ShouldNotThrow()
{
   DoSomethingThatShouldNotThrowAnException();
}
Gishu
fonte
2
Na verdade, esse pode ser um teste válido, especialmente como um teste de regressão.
Ilja Preuß
desculpe novamente confundi isso com o apanhador silencioso ... os testes de unidade devem indicar claramente a intenção sobre o que está sendo testado, em vez de dizer 'isso deve funcionar' .. (+1 tp algo é melhor que nada. país)
Gishu 03/12/08
1
Nesse tipo de teste, pelo menos estou capturando Exception e atribuindo-o a uma variável. Então eu afirmo que não é nulo.
Thomas Eyde
4
Algumas estruturas têm uma Assert.DoesNotThrow(SomeDelegateType act)asserção de estilo que pode ser usada especificamente em casos como este. Acho isso menos nojento do que ter um caso de teste que é bem-sucedido quando um construtor retorna não nulo, mas falha quando o construtor lança. Um construtor nunca retornará nulo. (Nota: só se aplica às línguas em que um construtor é garantida para retornar não-null)
Merlyn Morgan-Graham
10

O vândalo ambiental

Um teste de 'unidade' que, para vários 'requisitos', começa a se espalhar em seu ambiente, usando e configurando variáveis ​​/ portas de ambiente. A execução de dois desses testes simultaneamente causará exceções 'porta indisponível' etc.

Esses testes serão intermitentes e deixarão os desenvolvedores dizendo coisas como 'apenas execute novamente'.

Uma solução que eu vi é selecionar aleatoriamente um número de porta a ser usado. Isso reduz a possibilidade de um conflito, mas claramente não resolve o problema. Portanto, se você puder, sempre simule o código para que ele não aloque o recurso não compartilhável.

gcrain
fonte
@gcrain .. os testes devem ser determinísticos. Na IMO, uma abordagem melhor seria usar uma porta 'bem conhecida na equipe' para testar e limpar antes e depois do teste corretamente, de modo que esteja sempre disponível ... #
314
1
@ gishu - o problema não é que não existem métodos setup () e teardown () para lidar com o uso dessas portas. o problema é, por exemplo, a execução de um servidor de CI, e múltiplas versões do teste executados ao mesmo tempo, tentar usar os mesmos números de porta, hardcoded-in-the-teste
gcrain
10

O Teste de Turing

Um caso de teste gerado automaticamente por alguma ferramenta cara que possui muitas, muitas declarações coletadas da classe em teste usando uma análise de fluxo de dados muito inteligente pela metade. Lulls desenvolvedores em um falso senso de confiança de que seu código é bem testado, absolvendo-os da responsabilidade de projetar e manter testes de alta qualidade. Se a máquina pode escrever os testes para você, por que não pode puxar o dedo e escrever o aplicativo em si!

Olá estúpido. - O computador mais inteligente do mundo para o novo aprendiz (de uma história em quadrinhos antiga da Amiga).

bhumphreys
fonte
10

O teste de poste de quarenta pés

Com medo de se aproximarem demais da classe que estão tentando testar, esses testes agem à distância, separados por inúmeras camadas de abstração e milhares de linhas de código da lógica que estão verificando. Como tal, são extremamente frágeis e suscetíveis a todos os tipos de efeitos colaterais que ocorrem na jornada épica de e para a classe de interesse.

bhumphreys
fonte
9

Sósia

Para testar algo, você precisa copiar partes do código em teste para uma nova classe com o mesmo nome e pacote e usar a magia do caminho de classe ou um carregador de classes personalizado para garantir que seja visível primeiro (para que sua cópia seja escolhida acima).

Esse padrão indica uma quantidade não saudável de dependências ocultas que você não pode controlar em um teste.

Eu olhei para o rosto dele ... meu rosto! Era como um espelho, mas fez meu sangue congelar.

Aaron Digulla
fonte
7

The Mother Hen - Frank Carver
Uma configuração comum que faz muito mais do que os casos de teste reais precisam. Por exemplo, a criação de todos os tipos de estruturas de dados complexas preenchidas com valores aparentemente importantes e únicos quando os testes apenas afirmam a presença ou ausência de algo.
Sintoma avançado de: dispositivo elétrico compartilhado inadequadamente

Não sei o que faz ... estou adicionando mesmo assim, só por precaução.- Desenvolvedor Anônimo

Gishu
fonte
7

O Teste Tudo

Não acredito que isso não tenha sido mencionado até agora, mas os testes não devem quebrar o Princípio da Responsabilidade Única .

Eu já me deparei com isso tantas vezes, os testes que quebram essa regra são, por definição, um pesadelo para manter.

thegreendroid
fonte
6

Lançador de linha

À primeira vista, os testes abrangem tudo e as ferramentas de cobertura de código confirmam 100%, mas, na realidade, os testes apenas atingem o código sem nenhuma análise de saída.

código de cobertura vs alcançável

Ruslan Dzhabbarov
fonte