Qual o tamanho do meu projeto para que eu possa testá-lo? [fechadas]

86

Suponho que meu projeto seja dissociado o suficiente para permitir testes de unidade. Mas quão grande, exatamente, em termos de classes e funções meu projeto precisa ser para fazer com que os testes de unidade valham a pena?

Todos cometemos erros e ninguém é perfeito, mas eu me considero um programador decente para lidar com os erros de pequenos projetos. Ou o teste de unidade é uma necessidade difícil, independentemente do tamanho do seu projeto?

Lamin Sanneh
fonte
26
A grande suposição incorreta que você está fazendo é que o projeto é apenas para você e que é apenas por enquanto . E se você deixar por alguns meses, fizer outra coisa e depois voltar? Você terá a mesma confiança em ser um "programador decente" (que não tem nada a ver com o teste ou não)? E se alguém assumir o controle do seu projeto ...? Um ótimo blogueiro (infelizmente não está mais ativo) escreveu que você sempre deve "cuidar do leitor de código, não do escritor de código".
Amos M. Carpenter
6
Que tal isso (destinado ao C # .NET): int x = 3 * (1/3); qual é o valor armazenado em x após a conclusão da operação? Meu argumento é que até mesmo um código de linha pode exigir testes porque pode levar a um bug, porque você não sabe ou porque sabe, mas fez o código errado.
NoChance
2
@aaamos, acho que você perdeu o meu ponto. O fato de me fazerem essa pergunta por si só mostra que também considero atender o leitor de código.
Lamin Sanneh
13
Tendo feito as duas coisas, posso lhe dizer que é muito mais fácil escrever os testes à medida que você avança (ou seja, enquanto o projeto é pequeno) do que voltar e escrever testes de unidade mais tarde, quando sentir que o projeto encontrou algum resultado arbitrário " devemos escrever testes agora "condição.
Wonko the Sane
1
Você está fazendo a pergunta errada. Não importa o tamanho do projeto. A questão é: quanto você se importa se estiver correto? Se a correção é importante, os testes de unidade são uma maneira eficaz de melhorar a correção.
Mark E. Haase

Respostas:

206

Seu projeto já é grande o suficiente.

Na minha experiência, uma classe e uma função foram suficientes para considerar a necessidade de teste de unidade.

    class Simple {
        boolean reallySimple() {
            return true; // how do we make sure it doesn't change to false?
        }
    }


    class SimpleTest {
        void assertReallySimple() {
            // ensure reallySimple return value isn't changed unexpectedly
            UnitTestFramework.assertTrue(new Simple().reallySimple());
        }
    }
mosquito
fonte
24
Certamente você deve começar mais cedo, no ponto / 0 função 0 classe ... se você está seguindo TDD :)
Kaz Dragão
115
+1. Se você programar é grande o suficiente para ter bugs, é grande o suficiente para ter testes de unidade.
Jason Orendorff
9
@ JasonOrendorff: Estou zombando disso em um pôster e colocando-o no meu escritório. Brilhante.
precisa saber é o seguinte
Além disso, permite refatoração "segura".
Timo
7
Embora eu não discorde necessariamente do sentimento, se o seu código for realmente simples assim, você provavelmente poderá se dar bem com apenas afirmações em vez de testes de unidade completos.
Chuu 08/08/12
109

Eu nunca comprei a idéia "você deve testar tudo", embora certamente haja pessoas por aí (veja a resposta do mosquito !).

Para mim, os principais benefícios dos testes de unidade são:

  1. Ajudar a garantir que as mudanças não quebrem as coisas.
  2. Ajudando você a criar interfaces sensíveis para suas classes (uma vez que o força a ser um cliente para seu próprio código).
  3. Ajudando a documentar como seu código deve ser usado.

Basicamente, você precisa pesar o tempo que levará para escrever e manter testes contra esses fatores.

O número 1 é geralmente suficiente para valer a pena escrever testes. Na minha experiência,> 95% do código é modificado mais cedo ou mais tarde.

vaughandroid
fonte
8
Concorde com isso - ao trabalhar em uma única loja de desenvolvedores, você precisa encontrar um equilíbrio entre a qualidade do software e testar tudo (o que pode levar muito tempo). Não se esqueça que toda vez que você faz uma mudança que você pode precisar modificar seus testes de unidade de terno
Matt Wilko
1
Você não deve testar tudo, mas deve testar qualquer comportamento exposto ao mundo exterior. Certamente há / há custos de manutenção nos testes e, como Kent Beck disse em alguma resposta do SO (acho que foi SO) - teste o suficiente para deixar você confiante de que seu código está correto.
Wayne Werner
10
Eu acrescentaria que, se você estiver executando apenas testes automatizados mínimos, os testes de unidade estarão no nível errado a ser atingido. Em vez disso, faça testes de integração / fumaça de alto nível que forçam alguns conjuntos de dados de ponta a ponta do aplicativo sem zombar de nada. Você deseja que esses testes exercitem o máximo possível da sua base de código e abranjam todos os casos de uso e caminhos de execução normais. Uma chance de 75% de saber que suas alterações quebraram algo, em algum lugar, no aplicativo é mais benéfica do que uma chance de 5% de saber que você quebrou SomeClass.OneOfTheHandfulOfTestedFunctions ().
Dan Neely
3
Acho que você perdeu um: "Garantir que o código funcione da maneira que deveria!"
BlueRaja - Danny Pflughoeft 8/08/12
3
@ BlueRaja-DannyPflughoeft: Na verdade, seria mais preciso dizer: "Garantir que o código seja aprovado nos testes de unidade que você escreveu!"
precisa saber é o seguinte
34

É simples: você não precisa de teste de unidade se descartar o programa depois de executá-lo uma vez.

Se isso lhe parecer excessivo, considere o que a alternativa significaria. Se houvesse algum tamanho abaixo do qual o teste de unidade não compensa, você teria que continuar julgando em sua mente: "Já atingi o tamanho mágico? Ainda devo começar a escrever testes?" Agora, os programadores são notoriamente ruins em prever o futuro e notoriamente ruins em julgar suas próprias habilidades. O código que parece claro para você agora se tornará incompreensível, mesmo para você, mesmo esperando um mês. Um projeto que você tenha certeza absoluta de que nunca será usado novamente e que você mantém apenas a chance remota de que talvez queira pesquisar como resolveu algo antes, será solicitado novamente e receberá solicitações de alteração.

Portanto, é muito provável que você julgue incorretamente se o teste é útil ou não e, quando você começa a precisar de testes, já não está 100% certo de qual é a semântica exata a ser testada. Como acredito que todos, exceto os programas pontuais e triviais, lucram com testes de unidade, considero o custo de gastar esforços em testes que nunca são executados novamente como insignificante contra os riscos de estender código não testado e mal compreendido.

Kilian Foth
fonte
22
Os programadores são notoriamente ruim em julgar sua própria habilidade de prever o futuro
SuperM
3
@superM Concordo com você. O programa "corra uma vez e jogue fora" que já escrevi durante minha curta carreira permaneceu, foi executado a cada poucos dias e tornou-se crítico para os negócios. Eu chamo isso de o "temporarmanent" aka o efeito temporário permanente .... suspiro
Jalayn
@Jalayn Não é a resposta simplesmente que se deve voltar e adicionar testes de unidade assim que essa percepção ocorrer?
Cornel Masson
@CornelMasson Você está absolutamente certo, esperar que muitas vezes é difícil convencer os gestores que "não está terminado ainda" porque os testes estão faltando :-)
Jalayn
@Jalayn: É verdade!
Cornel Masson
22

Algum tempo atrás, encontrei um bom post: Por que o teste de unidade acelera o desenvolvimento . Pode ajudá-lo a responder à pergunta.

... E se a base de código ... fosse fornecida com um conjunto substancial de testes de unidade. Um conjunto que diria: "se todos os testes forem bem-sucedidos, garanto que o código ainda faz o que deve fazer" e, se um teste falhar, mostra exatamente onde algum comportamento está quebrado. Isso é ótimo, eu poderia alterar o código para adicionar as coisas que eu quero sem vagar, se o código ainda fizer o que deveria, basta executar os ... testes e tenho fé. Este é um ótimo mundo para se trabalhar como engenheiro de software. Notei que podia avançar muito mais rápido ...

Eu tenho fé".

Essa é provavelmente a razão mais importante pela qual os testes de unidade aceleram o desenvolvimento em um contexto corporativo.

Posso confiar que tudo ainda funcionará se todos os testes forem aprovados. Se os testes falharem, eles apontarão exatamente onde está o problema ...

... você precisa ter uma alta cobertura de teste de unidade e bons testes de unidade . Quando essas condições são respeitadas, você se encontra em uma situação em que o esforço para adicionar novas funcionalidades é quase independente do tamanho do aplicativo e que, a longo prazo, acelerará o desenvolvimento .

Michael Feathers introduziu em um de seus livros duas maneiras de trabalhar com alterações no código:

  • edite e reze,
  • cobrir e modificar.

Não importa o tamanho da base de código.

Marcin Sanecki
fonte
18

De acordo com Kent Beck, em sua resposta à pergunta Stack Overflow, qual a profundidade dos seus testes de unidade? , você deve testar o código que tende a errar.

Se normalmente não cometo algum tipo de erro (como definir as variáveis ​​erradas em um construtor), não testo.

Mansuro
fonte
4
Bom ponto, e isso implica que a pergunta do OP está errada; se testar não tem nada a ver com o tamanho do projeto. Uma base de código de 5 linhas pode precisar de testes, e um método de 1 linha em uma base de código grande pode não ser necessário (embora outras coisas nessa base de código o façam).
Nathan Long
Isso pode funcionar para pequenos projetos nos quais você está trabalhando sozinho, mas para um projeto que é feito para o trabalho (onde você não controla quem trabalhará no futuro) ou qualquer coisa que possa ser de código aberto, você precisa para testar tudo. E você precisa para começar imediatamente, porque depois será "muito difícil de aterrar todo o código que já está escrito"
xaxxon
@xaxxon: Kent, na verdade, fala sobre isso na mesma resposta a que Mansuro se referiu, dizendo: "Ao codificar em uma equipe, modifico minha estratégia para testar cuidadosamente o código que, coletivamente, tendemos a errar".
henko
Não, isso ainda é incrivelmente míope. Você não pode saber quem trabalhará no código no futuro. Esse é o tipo de mentalidade que afeta os desenvolvedores juniores.
Xaxxon
5

Os testes de unidade são implementados para economizar tempo e melhorar:

  • rastreamento de bugs
  • refatoração e / ou reescrita de código
  • teste de integração
  • teste de regressão, etc.

É necessário escrever testes de unidade para partes relativamente complexas do programa.

Se você tiver certeza de que escrever testes de unidade agora não economizará seu tempo no futuro, poderá ignorá-lo. No entanto, você nunca sabe, e pessoalmente não consigo pensar em um caso em que seja mais barato (em termos de tempo, dinheiro e nervos) não escrever testes de unidade, mas fazer todos os testes manualmente.

superM
fonte
Geralmente uma boa resposta, então +1. No entanto, acho que seu ponto final perde o fato de que você ainda deseja / precisará testar manualmente seus testes de unidade!
precisa saber é o seguinte
@Baqueta, talvez eu não soou clara, mas eu não queria dizer que os testes de unidade substituir completamente o teste manual
SuperM
4

"Devo fazer o teste de unidade" geralmente pode ser respondido respondendo à seguinte pergunta: "É importante que essa função funcione corretamente e é importante que eu saiba quando ela pára de funcionar?"

Claro, é muito mais complicado que isso, mas é uma boa maneira de começar. Eventualmente, você também avaliará se o código já está sendo testado em virtude de ser usado em outra função ou se o seu tempo seria melhor gasto em outra função etc.

Bryan Oakley
fonte
4

A menos que você escreva um código sem testá-lo, você sempre incorre no custo do teste.

A diferença entre ter testes de unidade e não tê-los é a diferença entre o custo de escrever o teste e o custo de executá-lo em comparação com o custo do teste manualmente.

Se o custo de escrever um teste de unidade for de 2 minutos e o custo de executar o teste de unidade for praticamente 0, mas o custo de testar manualmente o código for de 1 minuto, você será prejudicado ao executar o teste duas vezes.


Por muitos anos, fiquei com a má compreensão de que não tinha tempo suficiente para escrever testes de unidade para o meu código. Quando escrevi testes, eles estavam inchados, coisas pesadas que só me incentivaram a pensar que só deveria escrever testes de unidade quando soubesse que eram necessários.

Recentemente, fui encorajado a usar o Test Driven Development e achei uma revelação completa. Agora estou firmemente convencido de que não tenho tempo para não escrever testes de unidade .

Na minha experiência, desenvolvendo com testes em mente, você acaba com interfaces mais limpas, classes e módulos mais focados e, geralmente, mais código SOLID testável.

Toda vez que trabalho com código legado que não possui testes de unidade e preciso testar algo manualmente, fico pensando "isso seria muito mais rápido se esse código já tivesse testes de unidade". Toda vez que tenho que tentar adicionar a funcionalidade de teste de unidade ao código com alto acoplamento, fico pensando "isso seria muito mais fácil se tivesse sido escrito de maneira desacoplada".


Versão TL; DR :

Escreva um teste quando o custo de escrevê-lo, mais o custo de executá-lo quantas vezes for necessário, for menor do que o custo de testá-lo manualmente quantas vezes for necessário.

Lembre-se, porém, de que, se você usar o TDD, é provável que o custo de escrever testes diminua à medida que você melhora e, a menos que o código seja absolutamente trivial, você provavelmente acabará executando os testes com mais frequência do que espera.

Mark Booth
fonte
3

Teste assim que observar que as regressões acontecem ou temem causar algumas com suas edições e sem perceber.

Kindle que o medo, deixe crescer para um tamanho adequado: quanto mais cedo você testar, melhor.

Observação: dependendo da sua função no projeto, os testes de unidade podem não ser o único tipo de teste que você deseja escrever.

Todo mundo está obcecado por testes de unidade , por causa das más práticas de teste convencionais no passado; mas se você nunca testou antes, realmente deveria se concentrar nos testes em geral , apenas os testes de unidade não resolverão os problemas do mundo.

ZJR
fonte
1
Vejo você apontar, mas a unidade não é o ponto de partida básico para os programadores de inicialização. E também você poderia elaborar mais sobre o que você quer dizer com "testes em geral". Obrigado.
Lamin Sanneh
1
Existem pelo menos dois outros tipos de teste - teste de integração e testes de aceitação. Os testes de unidade abrangem uma unidade específica (por exemplo, é suposto que esta função desta classe afete o Fizz). Você zomba / stub de todos os outros lugares em que essa classe interage, passando dados falsos. Ao fazer testes de integração, você combina duas (ou mais) classes para garantir que suas aulas sigam juntas da maneira que você acha que deveriam. Eventualmente, você cria testes suficientes para realizar testes de ponta a ponta de todo o sistema, às vezes conhecidos como "testes de fumaça".
Wayne Werner
Há também testes de regressão para todo o tribunal. Os testes de regressão geralmente são maiores que o teste de unidade, podem levar um dia para serem construídos, podem implicar acesso a dados de teste e ambientes de teste especiais. Na verdade, os testes de unidade são uma versão menor, mais elegante e mais sustentável dos testes de regressão (à moda antiga).
ZJR
1

Acredito que não é o tamanho do projeto, mas o tipo de projeto que decide se deve usar o teste ou não.

Se você estiver trabalhando em uma prova de conceito ou em algum outro projeto em que o objetivo é aprender com a codificação, o teste não será necessário. Se o projeto é para ser usado, talvez até enviado para produção, ele deve ser testado.

Uma citação do "Código Limpo" de Robert C. Martin : "Se é trivial escrever, é trivial testar", então não há desculpa para pular o teste para programas curtos e triviais.

Eivind Eidheim Elseth
fonte
0

Realmente não é uma questão de tamanho - é o que você faz com ele (e quantos anos tem). Se eu estiver pensando em aprender como uma tecnologia funciona e planeja jogar fora isso (chamamos isso de um pico no Scrum), vou apenas codificar sem fazer muitos testes. Se você está planejando desenvolvê-lo ainda mais (mesmo que esteja apenas pensando), você deve escrever testes em torno do código. TDD é uma técnica de design, mesmo antes de ser uma técnica de teste. Você deseja ter uma imagem clara do que deseja que o código faça antes de se envolver nos detalhes da execução. Eu também NÃOrecomendamos tentar escrever testes de unidade extensivos em torno de grandes quantidades de código legado. Tente identificar as partes que são complexas (que possuem uma alta complexidade ciclomática / código de espaguete) e as partes que falham com frequência (geralmente serão as mesmas). Como outros sugeriram, eu iria ler o livro de Kent Beck sobre TDD e definitivamente leria o livro de Michael Feather. O que eles não cobrem muito é o aspecto político de escrever testes de unidade em torno do código. Muitos desenvolvedores odeiam ter que alterar seu código para torná-lo testável, e muitos desenvolvedores não sentem a necessidade de testar o código. É algo em que temos que trabalhar como profissão. É necessário que qualquer outra disciplina de engenharia prove (geralmente matematicamente) que seu trabalho atendeu às especificações. Nós deveríamos fazer o mesmo.

John Dahle
fonte
-1

Vincular um Projetos a limites de classes ou funcionalidade e, em seguida, julgar se isso é adequado para teste de unidade pode estar errado. Existem inúmeros benefícios no teste de unidade de um aplicativo, mas a verdadeira beleza começa quando você precisa manter um aplicativo ou trabalhar em ambiente distribuído. Então a escolha vem aqui. Mesmo uma pequena alteração no seu código pode causar desastres.
Eu sugeriria não apenas 'Teste de unidade', mas também recomendaria verificar sua cobertura de código, garantindo que o máximo de seu código seja coberto pelo Teste de unidade. O limite para a cobertura do código não deve ser inferior a 95% e a meta deve estar em torno de 100% . Você pode procurar ferramentas para rastrear sua cobertura de código e gerar um relatório.
O Visual Studio fornece dados de cobertura -http://msdn.microsoft.com/en-us/library/ms182496(v=vs.80).aspx
Além disso, você pode usar NCover ou dotCover.

Niks
fonte