Pergunta

Eu faço testes de unidade de escrita ao escrever APIs e funcionalidades do núcleo. Mas eu quero ser o fanboy legal que come, dorme e respira TDD e BDD. Qual é a melhor maneira de começar com TDD / BDD o caminho certo? Quaisquer livros, recursos, estruturas, melhores práticas?

O meu ambiente é backend Java com Grails frontend, integrado com vários serviços web externos e bancos de dados.

Foi útil?

Solução

Um bom lugar para começar é lendo blogs. Em seguida, comprar os livros das pessoas que estão blogando. Alguns eu recomendo:

"Uncle Bob" Martin e os rapazes no objeto Mentor: http://blog.objectmentor.com/

P.S. obter Bobs livro Clean Code:

http://www.amazon.com/Clean-Code-Handbook-Software- artesanato / dp / 0132350882

Meu amigo Tim Ottinger (ex-Objeto Mentor cara) http://agileinaflash.blogspot.com/ http://agileotter.blogspot.com/

Os caras JetBrains: http://www.jbrains.ca/permalink/285

Eu senti a necessidade de expandir sobre isso, como todo mundo parece só quero dar-lhe sua opinião sobre TDD e não ajudá-lo em sua busca para se tornar um Jedi-Ninja. O Michael Jordan de TDD é Kent Beck. Ele realmente fez escrever o livro sobre ele:

http://www.amazon.com/Test-Driven-Development-Kent- Beck / dp / 0321146530

Ele também blogs em:

http://www.threeriversinstitute.org/blog/?p=29

outros apoiadores "famosos" de TDD incluem:

Todos são grandes pessoas para seguir. Você também deve considerar frequentar algumas conferências como Agile 2010, ou Artesanato de software (este ano foram realizadas ao mesmo tempo em Chicago)

Outras dicas

Eu não gosto quando as pessoas dizem "Prática X nunca é ruim, se ele não funcionar, você não está fazendo a coisa certa." Desculpe, tem a mesma sensação que qualquer outro dogma religioso excesso de zelo. Eu não comprá-lo.

Eu concordo com essas pessoas que dizem que a melhor solução seu tempo e dinheiro pode pagar deve ser o objetivo.

Quem objetos para TDD não deve automaticamente ser acusado de desrespeitar qualidade. ( "Então, quando você parou de bater na sua mulher?") O fato é que software tem bugs nele, e o custo de eliminar todos eles tem de ser ponderado em relação ao benefício.

O mesmo acontece na fabricação. Tolerâncias de dimensões e acabamentos em superfícies não são todos iguais, porque às vezes uma tolerância estreita e um acabamento espelhado não são garantidos.

Sim, eu escrever testes de unidade, embora não muitas vezes antes de eu escrever a classe. Eu vi o efeito de testes em design. Eu medir e assistir a cobertura de código. Se eu descobrir que minha cobertura não é aceitável, eu escrevo mais testes. Eu entendo o benefício de uma rede de segurança de testes de unidade para refatoração. I siga essas práticas, mesmo quando estou trabalhando sozinho, porque eu tenho experimentado os benefícios em primeira mão. Eu consegui-lo.

Mas eu olhar de soslaio para qualquer companheiro que começou me incomodando sobre "comer, dormir e respirar testes unitários e TDD."

Meu gerente diz que a única maneira que vai me conseguir uma promoção é se eu posso obter a equipe para TDD / BDD.

Já pensou que talvez isso faz você soar como um chupa-up? Você já descobriu que o seu lancinante alienou o resto de sua equipe?

Esta resposta poderia me perder alguns pontos de reputação, mas tinha que ser dito.

Eu acho que a melhor abordagem seria a praticá-lo a si mesmo e deixar que outros vejam o benefício. Lidere pelo exemplo. Vai ser muito mais convincente do que correr sua boca.

Nossa, Grails tem geração de teste built-in. Se você está trabalhando em uma equipe que utiliza Grails, é necessária quanto mais vender?

A melhor prática IMHO: Do que é prático e não apenas porque é um processo. Não se esqueça que o objetivo de escrever aplicações é, e no mundo dos negócios, não está escrevendo testes. Não me interpretem mal, eles têm o seu lugar, mas que não deve ser o objetivo.

Encontrar alguém que tem vindo a fazer TDD BDD e programa / par com eles.

As métricas são, IMHO, a melhor maneira de ir daqui até lá. Mantenha o controle de quão bem o seu código é coberto, manter deltas de complexidade do código para cada commit, o uso do teste-corredores que assistem o seu código para alterações e constantemente re-executar os testes correspondentes. Nunca deixe comprimentos de teste ficar acima algumas linhas, de modo que todas as suas ferramentas funcionam bem. E eu recomendo uma vez por mês, tirar um dia para executar o código através de um testador de mutação. Este dia deve ser dedicado a apenas testes de escrita. Todo este material vai lhe trazer dor, se você não estiver fazendo bom TDD. Aprender com a dor, e em nenhuma hora em tudo, você vai estar fazendo isso direito.

E vista nunca perdem do que os testes são para: Descrever o comportamento desejado. Eles são a sua especificação executável. (Isso também é por isso que gosto Pepino ;! Agora você pode obter o seu PHB para escrever seus testes para você Bem, talvez não assim tão bom, mas é perto!)

"PS:. Meu gerente diz que a única maneira que vai me conseguir uma promoção é se eu posso obter a equipe para TDD / BDD"

A única maneira realista para conseguir uma equipe para fazer algo (sem matá-lo no processo) é demonstrar-lhes claramente que irá beneficiá-los a mudar seus hábitos. Em outras palavras, escrever código. Lotes de código. Toneladas de código. E então, quando o e-mail cruciais chegar que altere a especificação radicalmente, mostrar-lhes que você pode mudar seu código facilmente com refatoração eo que é pior, porque você estava preparado para ele com seus testes no local. O bar era verde, corte corte corte, RED BAR !!!!, corte corte corte, bar verde, ir para casa.

Leia Kent Beck livro sobre design orientado teste. Comece com testes e, em seguida, fazer o código. Obter um servidor em execução de construção que executa os testes! Você não precisa ot tê-lo para toda a equipe - fazê-lo por si mesmo e mostrar-lhes que ele ajuda

.

Pregação única irrita nativos:)

Eu venho fazendo TDD para um par de anos, mas ultimamente eu comecei a olhar mais para o caminho BDD de dirigir meu projeto e desenvolvimento. Recursos que me ajudaram a começar a fazer BDD foi o primeiro e formost blog de Dan do Norte (o 'fundador' do BDD). Dê uma olhada na Apresentando BDD . Há também um 'oficial' BDD Wiki sobre a behaviour-driven.org com algum bom post vale a pena ler.

A única coisa que eu achei realmente difícil quando se inicia com BDD (e ainda encontrar um pouco difícil) é como formular os cenários para torná-los adequados para BDD. Scott Bellware é um homem bem qualificados no BDD (ou Context-Spesification como ele gosta de cunhar-lo) e seu artigo -Driven Comportamento Desenvolvimento em Revista Código me ajudou muito na compreensão da maneira BDD de pensar e formular histórias de usuários.

Eu também recomendo o TekPub screencast projeto-driven comportamento com Specflow por Rob Conery. Uma ótima introdução para BDD e uma ferramenta (SpecFlow) muito bom adequado para fazer BDD em C #.

Quanto aos recursos TDD, já há um monte de boas recomendações aqui. Mas eu só quero salientar um par de livros que eu posso realmente recomendo;

Para começo fazer testes de unidade, em seguida, ler sobre como fazê-lo direito última ensinar sua equipe como TDD e levá-los a bordo -. Porque na minha experiência nada é mais importante, em seguida, fazer o teste de unidade com toda a sua equipe

Você também precisará de um processo de construção adequada -. Usando um servidor de compilação que iria construir o seu código e executar o seu testst Eu recomendo usar TeamCity (livre com limitações)

Aprender a testes de boa unidade certas é a parte mais difícil -. Alguns dos que você vai aprender por si mesmo (desde que você mantenha o teste de unidade) eo resto você pode aprender com pesquisando na internet

Você sabe que você alcançou seu objetivo Quando não está escrevendo testes de unidade como parte do desenvolvimento vão olhar para você simplesmente errado.

Lembre-se, meios ágeis que você não está completamente esgotado em qualquer método particular. Se você está trabalhando em algo onde os benefícios do TDD não valem a pena (como fazer edições de tentativa e erro em uma interface Swing), então não use TDD.

Eu não posso ver que ninguém tem realmente expressou que TDD é não sobre o teste. TDD-ing é sobre expressar o comportamento esperado antes de fazer a pequena modificação comportamental mudança. Isto melhora a concepção e permite se concentrar em uma maneira que eu nunca experimentou antes. Você começa testes que protege os seus futuros refatorações e cobertura de 90% para livre.

Para saber que eu sugeriria (resumindo o que já foi dito e adicionando um dos meu próprio):

  1. visitar os blogs e ler os livros mencionados acima
  2. emparelhar-se com alguém proficiente em TDD
  3. prática

Eu pratiquei o Bowling kata (exercícios) sozinho cerca de 20 vezes (cerca de 30 minutos cada) antes de começar a ver a luz. Começou por analisar descrição do Tio Bob dele aqui . Há uma série de katas no site codingdojo.org incluindo soluções e discussões. Experimentá-los!

Para tirar uma citação de Nike:. APENAS FAÇA-

Segundo conselho - nunca confiar na interface de outra pessoa. Sempre gravação, ao nível de cada classe, para a interface que você desejou existia -. Escrever-se um adaptador para a implementação real, se necessário

Além disso, acho que é útil para evitar valores de retorno em métodos e pensar do código em termos de mensagem de passagem, em vez de chamadas de função.

YMMV.

Um ano atrás, eu tinha pouca idéia de como fazer TDD (mas realmente queria (o quão frustrante)) e nunca tinha ouvido falar de BDD ... agora eu faço tanto compulsivamente. Estive em um ambiente de desenvolvimento .Net, não Java, mas eu ainda substituído o botão - "F5 Run" com uma macro para Executar pepino (BDD) ou MBUnit (TDD), dependendo se é um Recurso / Cenário ou Specification. No depurador, se possível. $ 1 no pote se você usar o depurador (JOKING (tipo de)).

O processo é muito incrível. O quadro que estamos adicionalmente usando é pelo The Oracle Eu fui abençoado para se deparar, e absorvendo informações de, e que o quadro que ele / que usamos é MavenThought.

Tudo começa com BDD. Nossa BDD é pepino se em linha reta ontop de rubi ferro.

Feature:

Cenário: .... Dado que faço blá ...
Quando eu fazer outra coisa ... Então as coisas maravilhosas acontecem ...

Cenário: ...

E isso não é a unidade de teste em si, mas ele dirige o recurso, cenário, cenário, e por sua vez a unidade (de teste) especificações .. Então você começa em um cenário, e com cada passo que você precisa para completar no cenário lo impulsiona o seu TDD.

E o TDD temos vindo a utilizar é o tipo de BDD de certa forma, porque olhamos para os comportamentos do SUT (Test Sob System) requer e um comportamento é especificada por especificação (classe "teste" arquivo).

Exemplo:

Aqui é a especificação para um comportamento:. Quando o teste Em Sistema é criado

Há mais uma especificação (arquivo de classe C # When_blah_happens) para um outro comportamento quando uma propriedade mudanças, mas que é separado em um arquivo separado.

using MavenThought.Commons.Testing;
using SharpTestsEx;

namespace Price.Displacement.Module.Designer.Tests.Model.Observers
{
    /// <summary>
    /// Specification when diffuser observer is created
    /// </summary>
    [ConstructorSpecification]
    public class When_diffuser_observer_is_created
        : DiffuserObserverSpecification
    {
        /// <summary>
        /// Checks the diffuser injection
        /// </summary>
        [It]
        public void Should_return_the_injected_diffuser()
        {
            Sut.Diffuser.Should().Be.SameInstanceAs(this.ConcreteDiffuser);
        }
    }
}

Este é provavelmente o comportamento mais simples para uma SUT, porque neste caso quando ele é criado, a propriedade difusor deve ser o mesmo que o difusor injetado. Eu tive que usar um difusor de concreto em vez de um Mock porque neste caso o difusor é um objeto Núcleo / Domínio e tem nenhuma notificação de propriedades para a interface. 95% do tempo nos referimos a todas as nossas dependências como Dep (), em vez de injetar a coisa real.

Muitas vezes, temos mais do que um [Ele] Should_do_xyz (), e às vezes um pouco de configuração como, talvez, até 10 linhas de stubbing. Este é apenas um exemplo muito simples, sem GivenThat () ou AndGivenThatAfterCreated () nessa especificação.

Para a configuração de cada especificação de nós geralmente só precisar substituir um par de métodos da especificação:

GivenThat () ==> isso acontece antes do SUT é criado.

CreatSut () ==> Nós auto criação simulada do sut com StructureMap e 90% do tempo nunca precisa substituir isso, mas se você é construtor injeção de um concreto, você tem que substituir esse.

AndGivenThatAfterCreated () => isso acontece após o SUT é criado.

WhenIRun () => a menos que seja um [ConstructorSpecification] nós usamos isto para executar uma linha de código que é o comportamento que estamos especificando para o SUT

Além disso, se houver um comportamento comum de dois ou mais especificações do mesmo SUT, passamos isso para o specifcation base.

Tudo que eu tenho que fazer para executar a especificação é destaque é nome, exemplo "When_diffuser_observer_is_created" e pressione F5, pois lembre-se, para mim F5 executa uma tarefa Rake ambos os testes: recurso [tag] se pepino, ou teste: class [SUT ]. Faz sentido para mim, porque toda vez que você executar o depurador é um jogar fora, nenhum código é criado (oh e custa $ 1 (brincando)).

Esta é uma maneira muito, muito limpo de especificar comportamento com TDD e ter realmente, SUTs realmente simples e especificações simples. Se você tentar e ser codificador de cowboy e escrever a porcaria SUT com dependências de disco rígido, etc, você vai sentir a dor de tentar fazer TDD e ficar fartos / desistir ou morder a bala e fazê-lo direito.

E aqui está o SUT real. Temos um pouco de fantasia e usar PostSharp para adicionar propriedade notificar alterado no difusor, então daí o Post.Cast <>. E, novamente, that É por isso que injetou um concreto em vez de Mock. De qualquer forma, como você pode ver o comportamento faltando definido em outra especificação é quando alguma coisa muda no difusor.

using System.ComponentModel;
using MavenThought.Commons.Events;
using PostSharp;
using Price.Displacement.Core.Products;
using Price.Displacement.Domain;

namespace Price.Displacement.Desktop.Module.Designer.Model.Observers
{
    /// <summary>
    /// Implementation of current observer for the selected product
    /// </summary>
    public class DiffuserObserver : AbstractNotifyPropertyChanged, IDiffuserObserver
    {
        /// <summary>
        /// gets the diffuser
        /// </summary>
        public IDiffuser Diffuser { get; private set; }

        /// <summary>
        /// Initialize with a diffuser
        /// </summary>
        /// <param name="diffuser">The diffuser to observe</param>
        public void Initialize(IDiffuser diffuser)
        {
            this.Diffuser = diffuser;
            this.NotifyInterface().PropertyChanged += (x, e) => this.OnPropertyChanged(e.PropertyName);
        }

        /// <summary>
        /// Gets the notify interface to use
        /// </summary>
        /// <returns>The instance of notify property changed interface</returns>
        protected INotifyPropertyChanged NotifyInterface()
        {
            return Post.Cast<Diffuser, INotifyPropertyChanged>((Diffuser)Diffuser);
        }
    }
}

Em conclusão, este estilo BDD / TDD de rochas de desenvolvimento. Demorou um ano, mas eu sou um convertido total, como um modo de vida. Eu não teria aprendido isso sozinho. Peguei tudo, desde The Oracle http://orthocoders.com/ .

Red ou pílula azul, a escolha é sua.

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