Quando é apropriado não realizar o teste de unidade?

138

Eu trabalho em uma pequena empresa como desenvolvedor solo. Sou o único desenvolvedor da empresa. Tenho vários projetos (relativamente) grandes que escrevi e mantenho regularmente, e nenhum deles tem testes para apoiá-los. Ao iniciar novos projetos, muitas vezes me pergunto se devo tentar uma abordagem de TDD. Parece uma boa ideia, mas sinceramente nunca posso justificar o trabalho extra envolvido.

Eu trabalho duro para ter uma visão de futuro em meu design. Sei que certamente um dia outro desenvolvedor precisará manter meu código ou, pelo menos, solucioná-lo. Eu mantenho as coisas o mais simples possível e comento e documento as coisas que seriam difíceis de entender. E o fato é que esses projetos não são tão grandes ou complicados que um desenvolvedor decente teria dificuldade em compreendê-los.

Muitos dos exemplos que eu já vi de testes chegam às minúcias, cobrindo todas as facetas do código. Como sou o único desenvolvedor e estou muito próximo do código em todo o projeto, é muito mais eficiente seguir um padrão de teste de gravação em seguida, manualmente. Também acho que os requisitos e os recursos mudam com frequência suficiente para que a manutenção de testes adicione uma quantidade considerável de atrito em um projeto. Tempo que de outra forma poderia ser gasto resolvendo as necessidades da empresa.

Então, acabo com a mesma conclusão a cada vez. O retorno do investimento é muito baixo.

Ocasionalmente, configurei alguns testes para garantir que escrevi um algoritmo corretamente, como calcular o número de anos que alguém está na empresa com base na data de contratação. Mas, do ponto de vista da cobertura de código, cobri cerca de 1% do meu código.

Na minha situação, você ainda encontraria uma maneira de tornar o teste de unidade uma prática regular ou estou justificado em evitar essa sobrecarga?

ATUALIZAÇÃO: Algumas coisas sobre a minha situação que deixei de fora: Meus projetos são todos aplicativos da Web. Para cobrir todo o meu código, eu teria que usar testes automatizados de interface do usuário, e essa é uma área em que ainda não vejo um grande benefício em relação aos testes manuais.

Ken Pespisa
fonte
11
Obrigado a todos. Estou aprendendo muito aqui. Algumas coisas que deixei de fora da minha situação: Meus projetos são todos aplicativos da Web. Para cobrir todo o meu código, eu teria que usar testes automatizados de interface do usuário, e essa é uma área em que ainda não vejo um grande benefício em relação aos testes manuais.
Ken Pespisa
11
Estamos obtendo grande sucesso na Transactis usando a ferramenta de teste de automação da Web da Telerik. Já temos dezenas de testes de navegador manuais anteriormente convertidos em automação. Os testes automatizados são MUITO MAIS rápidos e também são ótimos para destacar quaisquer problemas de desempenho que seu site possa ter.
John Kaster
2
Eu vi um projeto que tentou realizar testes automatizados no navegador de páginas da web completas. Até onde eu sei, ele não encontrou nenhuma das centenas de erros graves que encontramos através de testes manuais e custou uma quantidade enorme de tempo para desenvolver e manter. (Usando o Selenium conduzido por NUnit). Pior, alguns dos testes são interrompidos com frequência por problemas, devido a incompatibilidades do navegador e da estrutura de teste.
O'Rooney
11
Isso não é realmente uma resposta, apenas uma observação ... seu argumento contra o teste de unidade porque "os requisitos mudam com muita frequência" me lembra o argumento inverso que ouço onde trabalho: "nossos programas são tão estáticos, qual é o objetivo de testar quase nunca muda de qualquer maneira! " ;)
Bane
2
Os testes automatizados de interface do usuário do aplicativo da Web não são testes de unidade, são um animal totalmente diferente e eu não culpo você se você não quiser fazê-lo. Mas todo o seu código comercial deve estar no back-end, e é isso que você deve testar.
Nyamiou The Galeanthrope

Respostas:

84

Muitos dos exemplos que eu já vi de testes chegam às minúcias, cobrindo todas as facetas do código.

Assim? Você não precisa testar tudo . Apenas as coisas relevantes.

Como sou o único desenvolvedor e estou muito próximo do código em todo o projeto, é muito mais eficiente seguir um padrão de teste de gravação em seguida, manualmente.

Isso é realmente falso. Não é mais eficiente. É realmente apenas um hábito.

O que outros desenvolvedores individuais fazem é escrever um esboço ou estrutura de tópicos, escrever os casos de teste e preencher o esboço com o código final.

Isso é muito, muito eficiente.

Também acho que os requisitos e os recursos mudam com frequência suficiente para que a manutenção de testes adicione uma quantidade considerável de atrito em um projeto.

Isso é falso também. Os testes não são o problema. As alterações dos requisitos são o arrasto.

Você precisa corrigir os testes para refletir os requisitos. Sejam suas minúcias ou de alto nível; escrito primeiro ou escrito por último.

O código não é feito até que os testes passem. Essa é a verdade universal do software.

Você pode ter um teste de aceitação limitado "aqui está".

Ou você pode fazer alguns testes de unidade.

Ou você pode ter os dois.

Mas não importa o que você faça, sempre há um teste para demonstrar que o software funciona.

Sugiro que um pouco de formalidade e um bom conjunto de ferramentas de teste de unidade tornem esse teste muito mais útil.

S.Lott
fonte
8
Gosto da sua primeira declaração, para testar apenas as coisas relevantes. Em relação à eficiência do teste manual versus de unidade, não acredito que minha afirmação seja totalmente falsa, nem a sua é totalmente verdadeira. Parece que há um equilíbrio entre os testes automático e manual para obter a máxima eficiência.
Ken Pespisa
9
@ Pespisa Ken: Desculpe. Bebi o TDD Kool-Aid cerca de dois anos atrás (após 30 anos do último teste). Agora estou preso no teste primeiro. Isso me deixou muito, muito mais produtivo, porque tenho menos pensamento a fazer ao construir.
S.Lott
3
@ Ken Pespisa: Não. Há equilíbrio nas respostas. Se você perguntasse se é correto dividir por zero, você obteria respostas esmagadoras, inclinadas de uma maneira por um motivo. Se você perguntasse se sqrt(-1)deveria ser um número inteiro, obteria respostas esmagadoras, inclinadas para um lado. O saldo é em torno de "como" e "qual ordem". O fato é que você deve testar. Portanto, escreva os testes primeiro e verifique se eles funcionam.
S.Lott
21
Considere testar a unidade, a interface e não os detalhes da implementação. Teste os limites e casos de fronteira. Teste o código arriscado. Muito código é simples o suficiente para verificar por inspeção, embora inspecionar seu código seja mais propenso a erros do que inspecionar o código de outra pessoa. A primeira vez que os testes manuais podem ser mais eficientes, pela décima vez, os testes automatizados estão muito adiantados.
BillThor
10
"O código não é feito até que os testes passem" - Na verdade, IMO. O código inicia quando passa nos testes. O código não é feito até que ele esteja ativo por um ano ou dois e esteja sujeito a testes de estresse e testes de integração com uma base de usuários grande, ativa e impaciente. Esse é o único teste que realmente conta.
Vector
107

Imagine que você tivesse um conjunto de testes que poderia ser executado em um eyeblink e acenderia uma luz verde ou vermelha. Imagine que este conjunto de testes testou tudo ! Imagine que tudo o que você precisava fazer para executar o conjunto de testes era digitar ^ T. Que poder isso lhe daria?

Você poderia fazer uma alteração no código sem medo de quebrar alguma coisa? Você poderia adicionar um novo recurso sem medo de quebrar um recurso antigo? Você poderia limpar rapidamente o código confuso sem medo de causar danos?

Sim, você poderia fazer todas essas coisas! E o que aconteceria com o seu código ao longo do tempo? Ficaria cada vez mais limpo porque não haveria risco de limpá-lo.

Vamos imaginar que você tivesse uma pequena fada no ombro. Toda vez que você escrevia uma linha de código, a fada adicionava algo ao conjunto de testes que testava se essa linha de código fazia o que se pretendia fazer. Então, a cada par de segundos você poderia pressionar ^ T e ver que a última linha de código que você escreveu funcionava.

Quanto de depuração você acha que faria?

Se isso soa como fantasia, você está certo. Mas a realidade não é muito diferente. Substitua o eyeblink por alguns segundos, e a fada pela disciplina TDD, e você conseguirá.

Digamos que você esteja voltando para um sistema que você construiu há um ano e que esqueceu como criar um dos objetos centrais. Existem testes que criam esse objeto de todas as formas possíveis. Você pode ler esses testes e movimentar sua memória. Precisa chamar uma API? Existem testes que chamam essa API de todas as formas possíveis. Esses testes são pequenos documentos , escritos em um idioma que você entende. Eles são completamente inequívocos. Eles são tão formais que executam. E eles não podem ficar fora de sincronia com o aplicativo!

Não vale o investimento? Só podes estar a brincar comigo! Como alguém pode NÃO querer esse conjunto de testes? Faça um favor a si mesmo e pare de discutir sobre bobagens. Aprenda a fazer bem o TDD e observe quanto mais rápido você vai e quanto mais limpo é o seu código.

Tio Bob.
fonte
28
Uau, o tio Bob? É ótimo ter seus pensamentos aqui. Concordo com você sobre os benefícios do TDD, não há realmente nenhum argumento a ser tido lá. A questão é sobre o investimento de tempo e o ROI. Não é bobo para mim considerar essas coisas. Imagine que um projeto levará 50% mais tempo para terminar com TDD do que sem, e a fada me diz que me economizará apenas 10% do tempo em testes manuais durante a vida útil do projeto. Isso pode parecer uma fantasia, mas eu vejo isso como totalmente plausível em certos projetos.
Ken Pespisa
11
@Ken "Imagine que um projeto levará 50% mais tempo para terminar com TDD do que sem". Isso soa exatamente como fantasia para mim. De fato, parece que você acabou de descobrir esse ponto no momento, sem um pingo de evidência para apoiá-lo.
Rein Henrichs
18
@ Rein Henrichs - Claro que inventei o número, era uma afirmação hipotética. Estou afirmando que o TDD acrescenta uma quantidade significativa de tempo a um projeto e tenho que considerar se vou receber algo de valor igual ou melhor em troca. Você não precisa me convencer dos valores do TDD, estou convencido. Mas não é uma panacéia.
Ken Pespisa
11
@ Rein, qual é exatamente a "evidência disponível?" Por favor elabore.
Ken Pespisa
22
@Uncle Bob "Substitua o eyeblink por alguns segundos": você está brincando, é claro. O TDD é uma boa ferramenta, mas é necessário testar apenas as partes relevantes, caso contrário você gasta mais tempo mantendo os testes do que realizando qualquer desenvolvimento sério. Isso é especialmente verdadeiro quando os requisitos estão mudando muito rapidamente: você está constantemente escrevendo e descartando testes para classes que mudam o tempo todo. Não estou dizendo que o TDD seja ruim, ele deve ser usado com sensatez e não aplicado mecanicamente, como você sugere.
Giorgio
34

O erro que você está cometendo é que você vê os testes como um investimento de tempo sem retorno imediato. Não necessariamente funciona assim.

Em primeiro lugar, escrever testes realmente o enfoca no que essa parte do seu código precisa fazer.

Em segundo lugar, executá-los revela erros que, de outra forma, surgiriam nos testes.

Em terceiro lugar, executá-los às vezes mostra bugs que, de outra forma, não apareceriam nos testes e, em seguida, realmente te mordiam na produção.

Em quarto lugar, se você acertar um bug em um sistema em execução e criar um teste de unidade para ele, não poderá reintroduzir esse bug posteriormente. Isso pode ser uma grande ajuda. Erros reintroduzidos são comuns e muito irritantes.

Em quinto lugar, se você precisar entregar o código a outra pessoa, uma suíte de testes facilitará sua vida. Além disso, se você ignorou um projeto e o retornou depois de alguns anos, não estará mais tão perto dele e será útil para você também.

Minha experiência sempre foi que, ao longo do desenvolvimento de um projeto, ter testes de unidade decentes sempre tornou o processo mais rápido e mais confiável.

glenatron
fonte
2
@Ken, suítes de teste são especificações em um formato executável.
32

O pessoal da JUnit (estrutura de teste da unidade Java) tem uma filosofia de que, se for muito simples de testar, não teste . Eu recomendo a leitura das Perguntas frequentes sobre as práticas recomendadas , pois é bastante pragmático.

TDD é um processo diferente de escrever seu software. A premissa básica por trás do teste de unidade é que você passará menos tempo no depurador percorrendo o código e descobrirá mais rapidamente se a alteração do código acidentalmente interrompe outra coisa no sistema. Isso se encaixa no TDD. O ciclo TDD é assim:

  1. Escreva um teste
  2. Assista a falha (prove que você tem algo a fazer)
  3. Escreva exatamente o que é necessário para fazer o teste passar - não mais.
  4. Assista passar (yay!)
  5. Refatorar (melhorar)
  6. Lave, enxágue e repita

O que é menos óbvio sobre a aplicação do TDD é que ele altera a maneira como seu código de gravação . Ao se forçar a pensar em como testar / validar se o código está funcionando, você está escrevendo um código testável. E como estamos falando de testes de unidade, isso geralmente significa que seu código se torna mais modular. Para mim, o código modular e testável é uma grande vitória antecipadamente.

Agora, você precisa testar coisas como propriedades de C #? Imagine uma propriedade definida assim:

bool IsWorthTesting {get; set;}

A resposta seria "não", não vale a pena testar, porque neste momento você está testando o recurso de idioma. Apenas confie que o pessoal da plataforma C # acertou. Além disso, se falhasse, o que você poderia fazer para corrigi-lo?

Além disso, você descobrirá que existem certas partes do seu código que serão muito difíceis de serem testadas corretamente. Isso significa que não faça isso, mas certifique-se de testar o código que usa / é usado pelo problema complicado:

  • Exceções verificadas que só podem ocorrer se uma instalação falhar. Java tem uma tonelada deles. Você é obrigado a gravar um bloco catch ou declarar a exceção verificada, mesmo que não haja nenhuma maneira de falhar sem invadir os arquivos instalados.
  • Interfaces de usuário. Encontrar o controle sob teste e invocar os eventos certos para simular as ações de um usuário são muito problemáticos e, em alguns casos, impossíveis. No entanto, se você usar o padrão Model / View / Controller, poderá garantir que o modelo e os controladores sejam testados e deixar a parte da visualização em teste manual.
  • Interações cliente / servidor. Isso não é mais um teste de unidade e agora é um teste de integração . Escreva todas as partes necessárias para enviar e receber mensagens pelo cabo, mas na verdade não o passe. Uma boa abordagem é reduzir a responsabilidade do código que realmente fala por fio às comunicações brutas. No código do teste de unidade, faça uma simulação do objeto de comunicação para garantir que os serviços estejam funcionando conforme o esperado.

Acredite ou não, o TDD o ajudará a cair em um ritmo sustentável de desenvolvimento. Não é por causa da mágica, mas sim porque você tem um ciclo de feedback apertado e é capaz de detectar erros realmente burros rapidamente. O custo para corrigir esses erros é essencialmente constante (pelo menos o suficiente para fins de planejamento), porque os pequenos erros nunca se tornam grandes erros. Compare isso com a natureza explosiva dos sprints de purga de depuração / depuração de código.

Berin Loritsch
fonte
24

Você precisa equilibrar o custo do teste com o custo dos bugs.

Escrever um teste de unidade de 10 linhas para uma função que abre um arquivo, onde a falha é "arquivo não encontrado", é inútil.

Uma função que faz algo complexo para uma estrutura de dados complexa - então obviamente sim.

A parte complicada é intermediária. Mas lembre-se de que o valor real dos testes de unidade não está testando a função específica, está testando as interações complicadas entre eles. Portanto, um teste de unidade que detecta que uma alteração em um bit de código quebra alguma função em um módulo diferente a 1000 linhas de distância vale o seu peso no café.

Martin Beckett
fonte
23

Testar é jogar.

Criar um teste é uma aposta de que o custo dos bugs em uma unidade que ocorre e não os captura com esse teste (agora e durante todas as futuras revisões de código) é maior que o custo do desenvolvimento do teste. Esses custos de desenvolvimento de testes incluem itens como folha de pagamento para engenharia de teste, tempo de colocação no mercado, custos de oportunidade perdidos por não codificar outras coisas e etc.

Como qualquer aposta, às vezes você ganha, às vezes perde.

Em algum momento, o software atrasado, com muito menos erros, ganha com as coisas rápidas, mas com erros, que chegam ao mercado primeiro. Às vezes o oposto. Você precisa examinar as estatísticas em seu campo específico e quanto a gerência deseja jogar.

Alguns tipos de bugs podem ser tão improváveis ​​de serem executados ou eliminados de qualquer teste de sanidade inicial, que não valem estatisticamente o tempo necessário para criar testes específicos adicionais. Mas, às vezes, o custo de um bug é tão grande (médico, nuclear etc.) que uma empresa deve fazer uma aposta perdida (semelhante à compra de seguro). Muitos aplicativos não têm um custo de falha tão alto e, portanto, não precisam de uma cobertura de seguro antieconômica mais alta. Outros fazem.

hotpaw2
fonte
3
Boa resposta. Um dos poucos que realmente responde à minha pergunta original. Submergi-me no mundo dos testes desde que escrevi este post (eu gosto disso.) Preciso entendê-lo mais antes de poder realmente saber quando usá-lo (ou não). Por muitas razões expostas aqui, eu preferiria usá-lo o tempo todo. Mas, em última análise, dependerá de quanto mais rápido eu chegar, porque no final é uma aposta do meu tempo, que está sob o controle da minha empresa / cliente, e geralmente eles se concentram nos cantos inferiores do triângulo do projeto: en. wikipedia.org/wiki/Project_triangle
Ken Pespisa
10

Meu conselho é testar apenas o código que você deseja que funcione corretamente.

Não teste o código que você deseja que seja um buggy e cause problemas para você no futuro.

Nick Hodges
fonte
9
Me lembra o ditado que meu dentista tem: Você não precisa usar fio dental com todos os dentes, apenas os que deseja manter.
Ken Pespisa
Confesso que foi isso que me fez pensar nisso. ;-)
Nick Hodges
8

Muitas vezes me pergunto se devo tentar uma abordagem TDD. Parece uma boa ideia, mas sinceramente nunca posso justificar o trabalho extra envolvido.

TDD e teste de unidade não são a mesma coisa.

Você pode escrever código e adicionar testes de unidade posteriormente. Isso não é TDD e é muito trabalho extra.

TDD é a prática de codificação em um loop de luz vermelha. Luz verde. Refatorar iterações.

Isso significa escrever testes para o código que ainda não existe, assistir os testes falharem, corrigir o código para fazer com que os testes funcionem e depois tornar o código "correto". Isso geralmente economiza seu trabalho

Uma das vantagens do TDD é que ele reduz a necessidade de pensar em curiosidades. Coisas como erros pontuais desaparecem. Você não precisa procurar na documentação da API para descobrir se a lista retornada começa em 0 ou 1, basta fazê-lo.

Paul Butcher
fonte
Você poderia explicar como desaparecem os erros de um por um? Você está dizendo que pode obter mais rapidamente sua resposta sobre se o índice de uma matriz é baseado em zero ou baseado em testes através de testes do que pesquisando na documentação? Parece improvável para mim - eu sou muito rápido no Google :)
Ken Pespisa
11
Na verdade, escrever TDDs é uma excelente maneira de explorar uma API (incluindo uma base de código herdada, para fins de documentação da funcionalidade).
Frank Shearar 08/04
É também muito útil se que API nunca muda ... de repente você tem alguns testes falhando :-)
bitsoflogic
@ Ken Pespisa, é definitivamente mais rápido - escreva o código com base se você acha que é 0 ou 1, execute-o, corrija-o se necessário. Na maioria das vezes, você estará certo e teria deixado de procurar, se estiver errado, em 10 segundos.
Paul Butcher
Benefício muito interessante. Eu meio que gosto disso.
Ken Pespisa
3

Eu trabalhei em um sistema onde testamos quase tudo. As execuções notáveis ​​dos testes foram o código de saída PDF e XLS.

Por quê? Fomos capazes de testar as partes que coletaram os dados e construímos o modelo usado para criar a saída. Também fomos capazes de testar as partes que descobriram quais partes do modelo iriam para os arquivos PDF. Não foi possível testar se o PDF parecia bom porque isso era totalmente subjetivo. Não foi possível testar se todas as partes de um PDF eram legíveis para um usuário comum, porque isso também era subjetivo. Ou se a escolha entre gráficos de barras e de pizza estava correta para o conjunto de dados.

Se a saída for subjetiva, há poucos testes de unidade, você pode fazer o que vale o esforço.

sal
fonte
Na verdade, esse tipo de teste é provavelmente "teste de integração". E sim, o teste de integração é muito mais difícil que o teste de unidade, e uma razão é que, às vezes, as regras para o que é "correto" são muito complicadas ou até subjetivas.
sleske
2

Para muitas coisas, um 'teste de gravação e depois manualmente' não leva mais tempo do que escrever alguns testes. A economia de tempo advém da capacidade de executar novamente esses testes a qualquer momento.

Pense nisso: Se você tem alguma cobertura recurso decente com seus testes (não confundir com cobertura de código), e vamos dizer que você tem 10 características - clicar em um botão significa que você tem cerca de, 10 yous fazendo re-seus testes ... enquanto você se senta e bebe seu café.

Você também não precisa testar as minúcias. Você pode escrever testes de integração que abrangem seus recursos, se você não quiser obter detalhes minuciosos ... IMO, alguns testes de unidade são detalhados demais testando o idioma e a plataforma, e não o código.

TL; DR Nunca é realmente apropriado porque os benefícios são bons demais.

Steven Evers
fonte
2

Duas respostas muito boas que encontrei estão aqui:

  1. Quando fazer o teste de unidade versus teste manual
  2. O que não testar quando se trata de Teste de Unidade?

As justificativas para evitar a sobrecarga percebida:

  • Economia imediata de tempo / custo para sua empresa
  • Potencial economia de tempo / custo na solução de problemas / manutenção / extensão a longo prazo, mesmo depois que você se for.

Você não gostaria de deixar um ótimo produto do seu lado como prova da qualidade do seu trabalho? Falando em termos egoístas, não é melhor para você o que você faz?

Aditya P
fonte
11
Boa pergunta no final. Tenho orgulho do meu trabalho, absolutamente, e meus aplicativos funcionam muito bem (se posso ser tão ousado). Mas você está certo - eles podem ser ainda melhores com o suporte de alguns testes. Penso que a minha opinião aqui é tentar encaixar o maior número possível de testes possíveis dentro do tempo que tenho para trabalhar no projeto e sem ficar muito obcecado com a cobertura do código.
Ken Pespisa
1

Desenvolvedores profissionais escrevem testes de unidade porque, a longo prazo, economizam tempo. Você testará seu código mais cedo ou mais tarde e, se não o fizer, seus usuários, e se precisar corrigir bugs mais tarde, eles serão mais difíceis de corrigir e terão mais efeitos negativos.

Se você está escrevendo código sem testes e não possui bugs, tudo bem. Não acredito que você possa escrever um sistema não trivial com zero bugs, portanto, presumo que você o esteja testando de uma maneira ou de outra.

Os testes de unidade também são cruciais para evitar regressões quando você modifica ou refatora o código mais antigo. Eles não provam que sua alteração não quebrou o código antigo, mas lhe dão muita confiança (desde que sejam aprovados :))

Não voltaria a escrever um lote inteiro de testes para o código que você já enviou, mas da próxima vez que precisar modificar um recurso, sugiro que tente escrever testes para esse módulo ou classe, obtenha uma cobertura de até 70% + antes de aplicar as alterações. Veja se isso ajuda você.

Se você tentar e honestamente dizer que não ajudou, é justo o suficiente, mas acho que existem evidências suficientes da indústria de que elas ajudam a fazer com que valha a pena ao testar a abordagem.

Steve
fonte
Gosto de pensar em impedir regressões e adicionar confiança. Essas são exatamente as razões pelas quais eu gostaria de adicionar testes.
Ken Pespisa
1

Parece que a maioria das respostas é pró-TDD, mesmo que a pergunta não estivesse sendo feita sobre TDD, mas sobre testes de unidade em geral.

Não existe uma regra completamente objetiva por trás do que fazer o teste de unidade ou não. Mas há algumas vezes em que parece que muitos programadores não fazem teste de unidade:

  1. Métodos particulares

Dependendo da sua filosofia de POO, você pode criar métodos privados para dissociar rotinas complexas de seus métodos públicos. Geralmente, os métodos públicos devem ser chamados em muitos lugares diferentes e usados ​​com freqüência, e os métodos privados são realmente chamados apenas por um ou dois métodos públicos em uma classe ou módulo para algo muito específico. Geralmente é suficiente escrever testes de unidade para métodos públicos, mas não os métodos privados subjacentes que fazem parte da mágica acontecer. Se algo der errado com um método privado, seus testes de unidade de método público devem ser bons o suficiente para detectar esses problemas.

  1. O que você já sabe que deve funcionar (ou testado por outra pessoa)

Muitos programadores novos contrariam isso quando aprendem a testar pela primeira vez e pensam que precisam testar todas as linhas que estão sendo executadas. Se você estiver usando uma biblioteca externa e sua funcionalidade for bem testada e documentada por seus autores, geralmente não faz sentido testar a funcionalidade específica em testes de unidade. Por exemplo, alguém pode escrever um teste para garantir que seu modelo ActiveRecord persista o valor correto de um atributo com um retorno de chamada "before_save" no banco de dados, mesmo que esse comportamento já tenha sido exaustivamente testado no Rails. O (s) método (s) que o retorno de chamada está chamando, talvez, mas não o próprio comportamento do retorno de chamada. Quaisquer problemas subjacentes às bibliotecas importadas seriam melhor revelados através de testes de aceitação, em vez de testes de unidade.

Ambos podem ser aplicados, esteja você fazendo TDD ou não.

Ravenstine
fonte
0

Ken, eu e muitos outros desenvolvedores por aí chegamos à mesma conclusão que você várias vezes ao longo de nossas carreiras.

A verdade que acredito que você encontrará (como muitas outras) é que o investimento inicial em escrever testes para o seu aplicativo pode parecer assustador, mas se for bem escrito e direcionado para as partes corretas do seu código, eles podem realmente economizar uma tonelada de tempo.

Meu grande problema foi com as estruturas de teste disponíveis. Eu realmente nunca senti que eles eram o que eu estava procurando, então apenas criei minha própria solução muito simples. Isso realmente ajudou a me trazer para o "lado negro" dos testes de regressão. Compartilharei um pseudo trecho básico do que fiz aqui e espero que você encontre uma solução que funcione para você.

public interface ITest {
    public string Name {
        get;
    }
    public string Description {
        get;
    }
    public List<ITest> SubTests {
        get;
    }
    public TestResult Execute();
}

public class TestResult {
    public bool Succesful {
        get;
        set;
    }

    public string ResultMessage {
        get;
        set;
    }

    private Dictionary<ITest, TestResult> subTestResults = new Dictionary<ITest, TestResult>();
    public Dictionary<ITest, TestResult> SubTestResults {
        get {
            return subTestResults;
        }
        set {
            subTestResults = value;
        }
    }
}

A única parte complicada depois disso é descobrir qual o nível de granularidade que você acha que é o melhor "retorno do investimento" para qualquer projeto que esteja realizando.

Construir um catálogo de endereços obviamente exigirá muito menos testes do que um mecanismo de pesquisa empresarial, mas os fundamentos realmente não mudam.

Boa sorte!

Adam Carstensen
fonte
Acho que com o tempo vou descobrir qual é o melhor nível de granularidade. É bom ouvir de outras pessoas que estão criando regularmente testes que abordam isso de forma sensata e não que escrevam roboticamente testes para todos os resultados possíveis. Minha primeira introdução aos testes foi nesse tipo de nível em que tudo deve ser testado. De fato, todo o conceito de TDD parece seguir esse mantra.
Ken Pespisa
Acho que você pode se beneficiar do uso de um Framework como o SubSpec (inspirado no BDD), para que você possa obter o isolamento de Assert ("SubTest") enquanto compartilha a configuração de contexto.
91711 Johannes