Pergunta

OK, eu sei que já houve perguntas sobre começando com TDD..No entanto, acho que sei que o consenso geral é apenas faça , No entanto, parece que tenho os seguintes problemas para entrar no jogo:

  • Ao trabalhar com coleções, ainda testaremos a adição/remoção/inserção óbvia com sucesso, mesmo quando baseado em genéricos, etc., onde meio que "sabemos" que vai funcionar?
  • Alguns testes parecem levar uma eternidade para serem implementados.Por exemplo, ao trabalhar com saída de string, existe uma maneira "melhor" de fazer esse tipo de coisa?(por exemplo.teste o modelo de objeto antes de analisar, divida a análise em pequenas operações e teste lá). Na minha opinião, você deve sempre testar o "resultado final", mas isso pode variar muito e ser tedioso de configurar.
  • Não tenho uma estrutura de teste para usar (o trabalho não paga por ela), então posso "praticar" mais.Existem alguns bons que são gratuitos para uso comercial?(no momento estou usando o bom e velho Depurar.Assert :)
  • Provavelmente o maior..Às vezes eu não sei o que esperar NÃO acontecer..Quer dizer, você recebe luz verde, mas estou sempre preocupado com a possibilidade de perder um teste.Você se aprofunda para tentar quebrar o código ou deixa como está e espera que tudo caia mais tarde (o que custará mais).

Então, basicamente, o que estou procurando aqui não é um " apenas faça " mas mais " Eu fiz isso, tive problemas com isso, resolvi-os com isso "..O pessoal experiência :)

Foi útil?

Solução

Primeiro, é normal e normal sentir-se frustrado quando você começa a tentar usar o TDD em seu estilo de codificação.Só não desanime e desista, você precisará dar um tempo.É uma grande mudança de paradigma na forma como pensamos sobre a solução de um problema de código.Gosto de pensar nisso como quando mudamos da programação processual para a orientada a objetos.

Em segundo lugar, sinto que o desenvolvimento orientado a testes é, antes de tudo, uma atividade de design usada para detalhar o design de um componente, criando um teste que primeiro descreve a API que será exposta e como você consumirá sua funcionalidade.O teste ajudará a moldar o sistema em teste até que você seja capaz de encapsular funcionalidade suficiente para satisfazer quaisquer tarefas nas quais esteja trabalhando.

Tendo em mente o parágrafo acima, vejamos suas perguntas:

  1. Se eu estiver usando uma coleção em meu sistema em teste, configurarei uma expectativa para garantir que o código foi chamado para inserir o item e, em seguida, declarar a contagem da coleção.Não testo necessariamente o método Add na minha lista interna.Apenas me certifico de que ele foi chamado quando o método que adiciona o item for chamado.Eu faço isso adicionando uma estrutura de simulação à mistura, com minha estrutura de testes.
  2. Testar strings como saída pode ser entediante.Você não pode explicar todos os resultados.Você só pode testar o que espera com base na funcionalidade do sistema em teste.Você deve sempre dividir seus testes no menor elemento que está testando.O que significa que você terá muitos testes, mas testes pequenos e rápidos e que testam apenas o que deveriam, nada mais.
  3. Existem muitas estruturas de teste de código aberto para você escolher.Não vou discutir qual é o melhor.Basta encontrar um que você goste e começar a usá-lo.
  4. Tudo o que você pode fazer é configurar seus testes de acordo com o que você deseja que aconteça.Se surgir um cenário que introduza um bug em sua funcionalidade, pelo menos você terá um teste em torno da funcionalidade para adicionar esse cenário ao teste e, em seguida, alterar sua funcionalidade até que o teste seja aprovado.Uma maneira de descobrir onde podemos ter perdido um teste é usar Cobertura de código.

Apresentei a você o termo zombeteiro na resposta à primeira pergunta.Quando você introduz zombaria em seu arsenal para TDD, o teste fica muito mais fácil de abstrair as partes que não fazem parte do sistema em teste.Aqui estão alguns recursos sobre as estruturas de simulação disponíveis:

Uma forma de ajudar no uso do TDD, além de ler sobre o processo, é observar as pessoas fazendo isso.Eu recomendo assistir aos screencasts de JP Boodhoo no DNRTV.Confira:

OK, isso ajudará você a ver como os termos que apresentei são usados.Também apresentará outra ferramenta chamada Reafiador e como isso pode facilitar o processo TDD.Eu não poderia recomendar esta ferramenta o suficiente ao fazer TDD.Parece que você está aprendendo o processo e apenas encontrando alguns dos problemas que já foram resolvidos com o uso de outras ferramentas.

Acho que estaria cometendo uma injustiça com a comunidade se não atualizasse isso adicionando a nova série de Kent Beck no Desenvolvimento orientado a testes em programador pragmático.

Outras dicas

Da minha própria experiência:

  1. Teste apenas seu próprio código, não o código da estrutura subjacente.Portanto, se você estiver usando uma lista genérica, não há necessidade de testar Adicionar, Remover etc.

  2. Não há 2.Olhe para lá!Macacos!!!

  3. NUunidade é o caminho a seguir.

  4. Definitivamente, você não pode testar todos os resultados.Eu testo o que espero que aconteça e, em seguida, testo alguns casos extremos em que espero obter exceções ou respostas inválidas.Se um bug surgir por causa de algo que você esqueceu de testar, a primeira coisa que você deve fazer (antes de tentar consertar o bug) é escrever um teste para provar que o bug existe.

Minha opinião sobre isso é a seguinte:

  • +1 por não testar o código da estrutura, mas talvez você ainda precise testar classes derivadas de classes da estrutura.
  • Se alguma classe/método for difícil de testar, pode ser uma forte indicação de que algo está errado com o design.Tento seguir o princípio “1 aula – 1 responsabilidade, 1 método – 1 ação”.Dessa forma, você poderá testar métodos complexos com muito mais facilidade, fazendo isso em porções menores.
  • +1 para xUnit.Para Java você também pode considerar TesteNG.
  • TDD não é um evento único, é um processo.Portanto, não tente imaginar tudo desde o início, mas certifique-se de que cada bug encontrado no código seja realmente coberto pelo teste, uma vez descoberto.

Acho que a coisa mais importante (e na verdade um dos grandes resultados, de uma maneira um tanto recursiva) do TDD é o gerenciamento bem-sucedido de dependências.Você deve garantir que os módulos sejam testados isoladamente, sem necessidade de configuração elaborada.Por exemplo, se você estiver testando um componente que eventualmente envia um email, torne o remetente do email uma dependência para que você possa simulá-lo em seus testes.Isso leva a um segundo ponto: os mocks são seus amigos.Familiarize-se com as estruturas de simulação e o estilo de testes que elas promovem (comportamentais, em oposição aos clássicos baseados em estado) e as escolhas de design que elas incentivam (O "Diga, não pergunte" princípio).

Descobri que os princípios ilustrados no Três fichas para lembrar facilmente a essência do TDD é um bom guia.

De qualquer forma, para responder às suas perguntas

  1. Você não precisa testar algo que "sabe" que vai funcionar, a menos que você o tenha escrito.Você não escreveu genéricos, foi a Microsoft;)
  2. Se você precisa fazer muito em seu teste, talvez seu objeto/método também esteja fazendo muito.
  3. Download TestDriven.NET para iniciar imediatamente o teste de unidade no seu Visual Studio (exceto se for uma edição Express)
  4. Basta testar o coisa correta que vai acontecer.Você não precisar para testar tudo o que pode dar errado:você tem que esperar que seus testes falhem para isso.

Sério, apenas faça isso, cara.:)

Não sou especialista em TDD, de forma alguma, mas aqui está minha opinião:

  • Se for completamente trivial (getters/setters etc.), não o teste, a menos que você não tenha confiança no código por algum motivo.
  • Se for um método bastante simples, mas não trivial, teste-o.O teste provavelmente é fácil de escrever de qualquer maneira.
  • Quando se trata do que esperar que não aconteça, eu diria que se um determinado problema potencial for de responsabilidade da classe que você está testando, você precisa testar se ela o trata corretamente.Se não for responsabilidade da classe atual, não teste.

As estruturas de teste xUnit geralmente são de uso gratuito, então se você é um cara .Net, dê uma olhada no NUnit, e se Java é sua praia, dê uma olhada no JUnit.

O conselho acima é bom, e se você quiser uma lista de frameworks gratuitos, não precisa procurar além do Lista de estruturas xUnit na Wikipédia.Espero que isto ajude :)

Na minha opinião (sua milhagem pode variar):

1- Se você não escreveu não teste.Se você escreveu e não tem um teste, ele não existe.

3- Como todo mundo disse, o xUnit é ótimo e gratuito.

2 e 4- Decidir exatamente o que testar é uma daquelas coisas sobre as quais você pode debater consigo mesmo para sempre.Tento traçar essa linha usando os princípios do projeto por contrato.Confira 'Construção de software orientada a objetos" ou "O programador pragmático" para obter detalhes sobre isso.

Mantenha os testes curtos, "atômicos".Teste a menor suposição em cada teste.Torne cada TestMethod independente, para testes de integração eu até crio um novo banco de dados para cada método.Se você precisar criar alguns dados para cada teste, use um método "Init".Use simulações para isolar a classe que você está testando de suas dependências.

Sempre penso "qual é a quantidade mínima de código que preciso escrever para provar que isso funciona em todos os casos?"

No último ano, fiquei cada vez mais convencido dos benefícios do TDD.As coisas que aprendi ao longo do caminho:1) a injeção de dependência é sua amiga.Não estou falando de inversão de containers e frameworks de controle para montar arquiteturas de plugins, apenas passando dependências para o construtor do objeto em teste.Isso gera enormes dividendos na testabilidade do seu código.2) Comecei com a paixão / fanatismo do convertido e peguei uma estrutura de simulação e comecei a usar simulações para tudo que pude.Isso levou a testes frágeis que exigiam muitas configurações dolorosas e falhavam assim que eu iniciava qualquer refatoração.Use o tipo correto de teste duplo.Falsificações onde você só precisa respeitar uma interface, stubs para alimentar dados de volta ao objeto em teste, zombaria apenas onde você se preocupa com a interação.3) O teste deve ser pequeno.Procure que uma afirmação ou interação seja testada em cada teste.Eu tento fazer isso e principalmente estou lá.Trata-se da robustez do código de teste e também da quantidade de complexidade em um teste quando você precisar revisá-lo mais tarde.

O maior problema que tive com o TDD foi trabalhar com uma especificação de um órgão de padronização e uma implementação de terceiros desse padrão que era o padrão de fato.Codifiquei muitos testes de unidade realmente legais ao pé da letra da especificação apenas para descobrir que a implementação do outro lado da cerca via o padrão mais como um documento consultivo.Eles jogaram bastante solto com isso.A única maneira de corrigir isso era testar a implementação e também os testes de unidade e refatorar os testes e o código conforme necessário.O verdadeiro problema era a minha crença de que, desde que eu tivesse código e testes unitários, tudo estaria bem.Não tão.Você precisa construir resultados reais e realizar testes funcionais ao mesmo tempo que faz testes de unidade.Pequenos benefícios durante todo o processo - nas mãos dos usuários ou partes interessadas.

Apenas como complemento, pensei em dizer que coloquei um postagem no blog o que penso sobre como começar a testar (seguindo esta discussão e minha própria pesquisa), pois pode ser útil para as pessoas que visualizam este tópico.

"TDD – Introdução ao desenvolvimento orientado a testes" - Recebi ótimos comentários até agora e realmente apreciaria mais o que vocês têm a oferecer.

Eu espero que isso ajude!:)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top