Pergunta

Embora eu tenha escrito testes de unidade para a maioria do código que eu fiz, eu só recentemente tenho em minhas mãos uma cópia do TDD por exemplo por Kent Beck.Eu sempre me arrependi de certas decisões de design que eu fiz desde que impedia o aplicativo que está sendo 'testada'.Eu li o livro e, enquanto alguns parece estranho, eu senti que eu poderia gerir e decidiu experimentá-lo no meu projeto atual, que é basicamente um sistema cliente/servidor, onde as duas partes se comunicam via.USB.Um sobre o gadget e o outro no host.O aplicativo é em Python.

Eu comecei e muito em breve ficou preso em uma confusão de revisões e pequenos testes que mais tarde eu percebi que realmente não testar nada.Eu joguei fora a maioria deles e agora tem um aplicativo de trabalho para que os testes têm todos os coagulado em apenas 2.

Com base na minha experiência, eu tenho algumas perguntas que gostaria de perguntar.Ganhei algumas informações a partir de Novo TDD:Existem aplicativos de exemplo com testes para mostrar como fazer TDD? mas tenho algumas perguntas específicas que gostaria de respostas para discussão no.

  1. Kent Beck usa uma lista que ele acrescenta e ataca de partir para guiar o processo de desenvolvimento.Como fazer uma lista como essa?Inicialmente, eu tinha alguns itens como "servidor deve iniciar", "servidor deve anular-se o canal não está disponível", etc.mas eles se envolveram e, finalmente, agora, é apenas algo como "cliente deve ser capaz de conectar-se ao servidor" (que integrou a inicialização do servidor, etc.).
  2. Como você lida com regrava?Eu inicialmente selecionado um half duplex sistema baseado em pipes nomeados para que eu pudesse desenvolver a lógica de aplicativo no meu computador e, em seguida, adicionar o USB da parte de comunicação.Ela mudou-se para tornar-se um soquete com base em coisa e, em seguida, mudou-se de utilizar os ' raw sockets usando o Python SocketServer módulo.Cada vez que as coisas mudaram, eu achei que eu tinha que reescrever uma grande parte dos testes que era irritante.Eu percebi que os testes seriam um pouco invariável guia durante meu desenvolvimento.Eles apenas senti mais código para manipular.
  3. Eu precisava de um cliente e um servidor para se comunicar através do canal para testar ambos os lados.Eu poderia zombar de um dos lados para testar as outras, mas, em seguida, todo o canal não seria testado e eu me preocupo que eu tinha a perder.Isso prejudicou todo vermelho/verde/refatorar ritmo.Isso é apenas falta de experiência ou estou fazendo algo errado?
  4. O "Fake it till you make it" me deixou com um monte de bagunça código que mais tarde eu passei um monte de tempo para refatorar e limpar.Esta é a maneira como as coisas funcionam?
  5. No final da sessão, agora eu tenho o meu cliente e o servidor em execução, com cerca de 3 ou 4 testes de unidade.Ele me levou cerca de uma semana para fazê-lo.Eu acho que eu poderia ter feito isso em um dia, se eu estivesse usando os testes de unidade após a forma de código.Eu não consigo ver o ganho.

Eu estou olhando para comentários e conselhos de pessoas que implementaram grandes não trivial projetos totalmente (ou quase totalmente), utilizando esta metodologia.Faz sentido para mim seguir o caminho depois de Eu tenho algo que já está sendo executado e deseja adicionar um novo recurso, mas fazê-lo a partir do zero parece cansativo e não vale a pena o esforço.

P. S.:Por favor, deixe-me saber se isso deve ser comunidade wiki e eu vou marcá-lo assim.

Atualização 0 :Todas as respostas foram igualmente útil.Eu escolhi o que eu fiz, porque ele vibrava com a minha experiência a mais.

Atualização 1:Prática, Prática, Prática!

Foi útil?

Solução

Como uma preliminar comentário, TDD requer prática.Quando eu olhar para trás em testes que eu escrevi quando comecei TDD, eu vejo muitos problemas, assim como, quando eu olhar para o código que eu escrevi a alguns anos atrás.Continua fazendo, e como você começar a reconhecer o código bom do ruim, a mesma coisa vai acontecer com seus testes - com paciência.

Como fazer uma lista como essa?Eu inicialmente tinha alguns itens como "server deve iniciar-se", "servidor deve abortar se o canal não está disponível", etc.mas eles se envolveram e, finalmente, agora, é apenas algo como "cliente deve ser capaz de conectar-se ao servidor"

"A lista" pode ser bastante informal (que é o caso em Beck livro), mas quando você se mover para fazer os itens em testes, tente escrever as instruções em um "[Quando algo acontece a isso] e em seguida [esta condição deve ser verdadeira no que]" formato.Isto irá forçar você a pensar mais sobre o que é que você está verificando, como você iria verificar e traduz-se diretamente em testes - ou se não deve dar a você uma pista sobre o que parte da funcionalidade está faltando.Acho que caso de uso / cenário.Por exemplo, "servidor deve iniciar backup" é claro, porque ninguém é de iniciar uma ação.

Cada vez que as coisas mudaram, eu achei que Eu tinha que reescrever considerável de peças de os testes que era irritante.Eu percebi que os testes seriam um de certa forma invariável guia durante a minha desenvolvimento.Eles apenas senti mais código para manipular.

Primeiro, sim, os testes são mais de código, e requer manutenção e escrita fácil de testes requer prática.Concordo com S.Lott, se você precisar alterar seus testes muito, provavelmente você está teste "muito profundo".O ideal é que você quer testar, ao nível da interface pública, o que não é susceptível de mudança, e não no nível do detalhe de implementação, que poderia evoluir.Mas parte do exercício é sobre a vinda acima com um projeto, assim que você deve esperar para começar um pouco do que é errado e tem que se mover/refatorar seus testes.

Eu poderia zombar de um dos lados para testar a outra, mas, em seguida, todo o canal não seria testado e eu me preocupo que Eu sinto falta disso.

Não totalmente certo sobre isso.Do som dele, usando um mock era a idéia certa:tomar um lado, zombar do outro, e verifique que cada lado de obras, assumindo a outra é implementado corretamente.O teste de todo o sistema, é o teste de integração, o qual você também quer fazer, mas geralmente não faz parte do TDD processo.

O "Fake it till you make it" me deixou com um monte de bagunça código que eu mais tarde passei um monte de tempo para refatorar e limpar.Esta é a maneira como as coisas funcionam?

Você deve gastar um monte de tempo refatoração ao fazer TDD.Por outro lado, quando você finge, é temporária, e a sua imediata próximo passo deve ser a onu-falsos-lo.Normalmente, você não deve ter vários testes de passagem, porque você fingiu - você deve estar centrada em uma peça de cada vez, e o trabalho sobre refatoração-lo o mais rápido possível.

Eu acho que eu poderia ter feito isso em um dia se eu estivesse usando os testes de unidade depois de forma de código.Eu não consigo ver o ganho.

Novamente, é preciso prática, e você deve chegar mais rápido ao longo do tempo.Também, às vezes, o TDD é mais proveitoso do que outros, acho que em algumas situações, quando eu sei exatamente o código que eu quero escrever, é apenas mais rápido para escrever uma boa parte do código, e em seguida, escrever os testes.
Além de Beck, um livro que eu gostei é A Arte de Testes de Unidade, por Roy Osherove.Não é um livro de TDD, e é .Net-orientado, mas você pode querer dar-lhe um olhar de qualquer maneira:uma boa parte é sobre como escrever fácil de testes, testes de qualidade e de questões conexas.Eu achei que o livro ressoava com a minha experiência, depois de ter provas escritas e, às vezes, se esforçou para fazê-lo direito...
Portanto, o meu conselho é, não jogue a toalha, muito rápido, e dar-lhe algum tempo.Você também pode querer dar um tiro em algo mais fácil de testes de comunicação com o servidor coisas relacionadas, não parece ser o mais fácil de projeto para começar!

Outras dicas

  1. Kent Beck usa uma lista ...finalmente, agora, é apenas algo como "cliente deve ser capaz de conectar-se ao servidor" (que integrou a inicialização do servidor, etc.).

Muitas vezes, uma má prática.

Testes separados para cada camada da arquitetura são boas.

Consolidado testes tendem a obscurecer questões arquitetônicas.

No entanto, o teste somente as funções públicas.Não cada função.

E não investir muito tempo a otimizar o seu teste.Redundância nos testes não dói tanto quanto na aplicação de trabalho.Se as coisas mudam e um teste de obras, mas de um outro teste de quebra, talvez, em seguida, você pode refatorar seus testes.Não antes.

2.Como você lida com regrava?...Eu achei que eu tinha que reescrever uma grande parte dos testes.

O que você está testando em um nível muito baixo de detalhe.Teste o mais externo, público, a interface visível.A parte que deveria ser imutável.

E

Sim, significativa mudança de arquitetura significa significativo de testes mudança.

E

O código de teste é como você provar as coisas funcionam.Ele é quase tão importante como a própria aplicação.Sim, é mais código.Sim, você deve gerenciá-lo.

3.Eu precisava de um cliente e um servidor para se comunicar através do canal para testar ambos os lados.Eu poderia zombar de um dos lados para testar as outras, mas, em seguida, todo o canal não iria ser testado ...

Existem testes de unidade.Com as simulações.

Existem testes de integração, que testam a coisa toda.

Não confundi-los.

Você pode usar ferramentas de teste de unidade para fazer testes de integração, mas são coisas diferentes.

E o que você precisa fazer ambos.

4.O "Fake it till you make it" me deixou com um monte de bagunça código que mais tarde eu passei um monte de tempo para refatorar e limpar.Esta é a maneira como as coisas funcionam?

Sim.Isso é exatamente como funciona.A longo prazo, algumas pessoas acham mais eficaz do que esticar seus cérebros tentando fazer todo o design up front.Algumas pessoas não gostam disso e quer fazer todo o design up front;você é livre para fazer um monte de design up front, se você desejar.

Descobri que a refatoração é uma coisa boa e design up front é muito difícil.Talvez seja porque eu tenho a codificação por quase 40 anos e meu cérebro está se desgastando.

5.Eu não consigo ver o ganho.

Todos os verdadeiros gênios achar que o teste de diminui-los para baixo.

O resto de nós não pode ser com certeza o nosso código funciona até temos um conjunto completo de testes que provar que ele funciona.

Se você não precisa de prova que seu código funciona, você não precisa de testes.

P.Kent Beck usa uma lista que ele acrescenta e ataca de partir para guiar o processo de desenvolvimento.Como fazer uma lista como essa?Inicialmente, eu tinha alguns itens como "servidor deve iniciar", "servidor deve anular-se o canal não está disponível", etc.mas eles se envolveram e, finalmente, agora, é apenas algo como "cliente deve ser capaz de conectar-se ao servidor" (que integrou a inicialização do servidor, etc.).

Eu comece por escolher alguma coisa que eu possa verificar.No seu exemplo, você escolheu "servidor iniciado".

Server starts

Agora eu olho para qualquer prova, ainda mais simples que eu poderia querer escrever.Algo com menos variação, e menos peças móveis.Eu poderia considerar o "servidor configurado corretamente", por exemplo.

Configured server correctly
Server starts

Realmente, embora, o "servidor iniciado" depende "servidor configurado corretamente", então eu fazer essa ligação clara.

Configured server correctly
Server starts if configured correctly

Agora eu olho para as variações.Eu pergunto, "o Que poderia dar errado?" Eu poderia configurar o servidor incorrectamente.De quantas maneiras diferentes que importa?Cada um desses faz um teste.Como pode o servidor não iniciar mesmo que eu configurado corretamente?Cada caso de que faz um teste.

P.Como você lida com regrava?Eu inicialmente selecionado um half duplex sistema baseado em pipes nomeados para que eu pudesse desenvolver a lógica de aplicativo no meu computador e, em seguida, adicionar o USB da parte de comunicação.Ela mudou-se para tornar-se um soquete com base em coisa e, em seguida, mudou-se de utilizar os ' raw sockets usando o Python SocketServer módulo.Cada vez que as coisas mudaram, eu achei que eu tinha que reescrever uma grande parte dos testes que era irritante.Eu percebi que os testes seriam um pouco invariável guia durante meu desenvolvimento.Eles apenas senti mais código para manipular.

Quando eu mudar de comportamento, acho que é razoável para alterar os testes, e até mudar primeiro!Se eu tiver que mudar testes que não se verifique diretamente o comportamento que eu estou em processo de mudança, embora, isso é um sinal de que meus testes dependem de muitos comportamentos diferentes.Esses são os testes de integração, que eu acho que são uma farsa.(O Google "testes de Integração são uma farsa")

P.Eu precisava de um cliente e um servidor para se comunicar através do canal para testar ambos os lados.Eu poderia zombar de um dos lados para testar as outras, mas, em seguida, todo o canal não seria testado e eu me preocupo que eu tinha a perder.Isso prejudicou todo vermelho/verde/refatorar ritmo.Isso é apenas falta de experiência ou estou fazendo algo errado?

Se eu criar um cliente, um servidor e um canal, então eu vou tentar cada um isoladamente.Eu começo com o cliente, e quando eu test-drive, eu decidir como o servidor de canal e precisa se comportar.Em seguida, implementar o canal de servidor e de cada um, para coincidir com o comportamento que eu preciso.Ao verificar o cliente, eu stub do canal;quando a verificação de que o servidor, eu zombar do canal;ao verificar o canal, eu stub e simulação de cliente e servidor.Espero que isso faz sentido para você, desde que eu tenho que fazer algumas sérias pressupostos sobre a natureza do cliente, do servidor e do canal.

P.O "Fake it till you make it" me deixou com um monte de bagunça código que mais tarde eu passei um monte de tempo para refatorar e limpar.Esta é a maneira como as coisas funcionam?

Se você deixar o seu "fake it" código de ficar muito confuso antes de limpá-lo, então você pode ter gasto muito tempo fingir.O que disse, acho que apesar de eu acabar a limpeza de código mais com TDD, em geral, a ritmo se sente muito melhor.Isso vem da prática.

P.No final da sessão, agora eu tenho o meu cliente e o servidor em execução, com cerca de 3 ou 4 testes de unidade.Ele me levou cerca de uma semana para fazê-lo.Eu acho que eu poderia ter feito isso em um dia, se eu estivesse usando os testes de unidade após a forma de código.Eu não consigo ver o ganho.

Eu tenho que dizer que, a menos que o cliente e o servidor são muito, muito simples, você precisa de mais do que 3 ou 4 testes de cada verificá-los cuidadosamente.Eu acho que os testes de seleção (ou, pelo menos, executar) uma série de comportamentos diferentes de uma só vez, e que pode contribuir para o esforço que você levou para escrevê-los.

Além disso, não mede a curva de aprendizagem.Meu primeiro TDD experiência consistiu de re-escrita 3 meses de trabalho no 9, 14 horas por dia.Eu tinha 125 testes que levou 12 minutos para ser executado.Eu não tinha idéia do que estava fazendo, e ele sentiu lento, mas senti-me firme, e os resultados foram fantásticos.Essencialmente eu re-escreveu em 3 semanas, o que originalmente levou 3 meses para começar errado.Se eu escrevi agora, provavelmente eu poderia fazê-lo em 3-5 dias.A diferença?Meu conjunto de teste teria 500 testes que levar de 1 a 2 segundos para executar.Que veio com a prática.

Como um programador novato, a coisa que eu achei complicado sobre test-driven development, foi a ideia de que os testes devem vir em primeiro lugar.

Para o iniciante, que não é bem verdade.Design vem em primeiro lugar.(Interfaces, objetos, classes, métodos, qualquer que seja apropriado para o seu idioma.) Em seguida, você escreve seus testes para isso.Em seguida, tem de escrever o código que realmente faz coisas.

Tem sido um tempo desde que eu olhei para o livro, mas Beck parece escrever como se o projeto de código tipo do que acontece inconscientemente em sua cabeça.Para programadores experientes, que pode ser verdadeiro, mas para noobs como eu, noé,-uh.

Eu encontrei os primeiros capítulos de Código Completo realmente útil para pensar sobre o design.Eles enfatizam o fato de que seu projeto pode muito bem mudar, mesmo quando você estiver para baixo no nitty gritty nível de implementação.Quando isso acontece, você pode muito bem ter que re-escrever os testes, porque eles estavam com base nos mesmos pressupostos como seu projeto.

A codificação é difícil.Vamos fazer compras.

Para o ponto um, consulte um pergunta Perguntei a um tempo atrás, relativos ao seu primeiro ponto.

Em vez de lidar com os outros pontos em vez, eu vou oferecer algumas assessoria global.Prática.Ele me levou um bom tempo, e alguns 'desonesto' projetos (pessoais que) para reais obter TDD.Apenas o Google por muito mais razões sobre o porquê de TDD é tão bom.

Apesar de os testes de condução que o design do meu código, eu ainda tenho um quadro branco e rabisco algumas design.A partir deste, pelo menos você tem alguma idéia do que você está destinado a fazer.Então eu produzir a lista de testes por dispositivo elétrico que eu acho que eu preciso.Uma vez que você começar a trabalhar, mais recursos e testes são adicionados à lista.

Uma coisa que estava fora da sua pergunta é o ato de reescrever os testes novamente.Isso soa como você, estão a realização de provas comportamentais, ao invés de estado.Em outras palavras, os testes de som muito intimamente ligada ao seu código.Assim, uma mudança simples que não afecta a saída será a quebra de alguns testes.O teste de unidade (pelo menos um bom teste de unidade), também, é uma habilidade de mestre.

Eu recomendo a Testes Da Google Blog muito fortemente porque alguns dos artigos que lá fiz meu teste para TDD projetos muito melhor.

Os pipes nomeados foram colocados atrás de direito da interface, alterando a forma como a interface é implementada (de pipes nomeados para sockets para outra biblioteca de sockets) só deve testes de impacto para o componente que implementa essa interface.Corte as coisas mais/de forma diferente de ter ajudado...Que a interface de sockets estão atrás provavelmente irá evoluir para.

Eu comecei a fazer TDD talvez 6 meses atrás?Eu ainda estou aprendendo a mim mesmo.Posso dizer que ao longo do tempo meus testes e código de ter ficado muito melhor, de modo a mantê-lo.Eu realmente recomendo o livro XUnit Padrões de Projeto bem.

Como fazer esse tipo de lista para adicionar a e ficam de fora do guia o processo de desenvolvimento?Inicialmente, eu tinha um alguns itens como "servidor deve iniciar até", "servidor deve anular-se do canal não está disponível"

Itens no TDD listas de AFAZERES são mais refinadas do que isso, que visam testar um comportamento de apenas um método, por exemplo:

  • teste bem-sucedido de conexão do cliente
  • cliente de teste de conexão tipo de erro 1
  • cliente de teste de conexão tipo de erro 2
  • teste bem-sucedido de comunicação com o cliente
  • teste de comunicação com o cliente falhar quando não conectado

Você poderia construir uma lista de testes (positivo e negativo) para cada exemplo que você deu.Além disso, quando a unidade de teste que você não estabelecer qualquer conexão entre o servidor e o cliente.Você acabou de invocar métodos de isolamento, ...Isso responde a pergunta 3.

Como você lida com regrava?

Se o teste de unidade testes de comportamento e não a implementação, então eles não têm que ser reescrito.Se o teste de unidade de código realmente cria um pipe nomeado para comunicar-se com o código de produção e, então, obviamente, os testes têm de ser modificado quando a troca de tubo de tomada.Testes de unidade devem ficar longe de recursos externos, tais como sistemas de arquivos, redes, bancos de dados, porque eles são lentos, pode não estar disponível ...veja estes O Teste de unidade de regras.

Isto implica que o nível mais baixo de função não são a unidade testada, eles serão testados com testes de integração, onde todo o sistema é testado fim-a-fim.

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