Algumas considerações sobre TDD e BDD

Parece haver muita confusão sobre a diferença entre TDD e BDD na comunidade Rails. A criação de vários frameworks competidores (RSpec, Shoulda, Expectations, etc) parece não ter ajudado muito já que cada proponente torce um pouco a visão dada por cada um deles.

A grande divisão

O problema é que a maioria das pessoas que pratica uma variante ou outra nunca leu a literatura sobre o assunto e por causa disso há uma falta de formalização sobre o assunto. Muito do que se vê escrito hoje tanto sobre TDD ou BDD é escrito da forma que aquela pessoa em particular pratica o assunto e não como o conceito foi sendo desenvolvido ao longo das anos.

Tome, por exemplo, TDD como popuralizado originalmente por Kent Beck no contexto de Extreme Programming. Existe uma granularidade envolvida no crescimento do código que pode ser descrita como orgânica.

Design ou Development?

Uma das coisas que sempre me ajudou a enxergar o modo apropriado de construir uma aplicação a partir de testes foi pensar no D final de TDD ou BDD não como desenvolvimento, mas como design.

Voltando ao tema de granularidade, se você fizer uma experimento e acompanhar dezenas de pessoas que “praticam” TDD ou BDD, o mais provável é que você perceba que os testes estão sendo escritos como uma forma de cobrir o código e não como uma forma de pensar no código em si. Um teste é escrito que demonstra um certo caso de uso da classe ou método em questão e o código para aquele trecho é então escrito.

É muito comum, dentro da prática descrita acima, que vários testes seja escritos em seqüência e o código da classe ou método inteiro seja depois implementado. Voltando ao modo como Kent Beck explicou o processo originalmente, nada por estar mais longe da realidade.

De fato, nos seus exemplos concretos sobre o assunto, Kent Beck compara o uso de TDD ao uso de uma lista de tarefas para a construção de código, o que força o desenvolvedor a pensar em detalhes sobre a arquitetura que está criando. Volta aqui o sentido de design e não de desenvolvimento puro.

Chega-se então ao ponto de que cada teste é pensado como uma forma de evoluir a arquitetura do código e pensar em como aquela classe ou método existe dentro do contexto mais generalizado da aplicação. Não é surpreendente que quando isso é feito, coberturas de 100% são factíveis, métodos ou funções não possuem mais do que algumas poucas linhas fazendo exatamente e o que deve fazer e não mais e uma delegação efetiva de responsabilidades acontece.

TDD versus BDD

Chega-se então ao ponto central da conversa? Qual é a diferença principal entre TDD e BDD? No ponto mais básico da cadeia, a resposta é: nenhuma.

Tanto TDD quando BDD são formas de se pensar em testes partindo de premissas ligeiramente diferentes mas chegando ao mesmo resultado prático. Sendo feitas de maneira apropriada, o resultado final dentro das necessidades acima (cobertura, delegação, arquitetura) é o mesmo e a conversação que deve acontecer no desenvolvimento ocorre naturalmente.

Apesar disso, há uma diferença histórica que está evoluindo com o tempo e que, em última instância, está se convertendo no foco de debate entre os dois campos. Essa diferença foi inicialmente expressa por Dan North (responsável pelo desenvolvimento do RBehave, que mais tarde se tornaria a base do Story Runner do RSpec) e depois elaborada por David Chelimsky.

Esse posicionamento coloca BDD não como uma oposição direta a TDD em termos práticas, mas como uma corrente filosófica que engloba TDD e expande o discurso para incluir elementos que vão além do metodológico e já começam a cair no processual.

Um exemplo claro disso é a ascensão de frameworks orientados a estórias (testes de aceitação de usuários) como o Cucumber. Esses esforços representam a graduação de BDD não somente com uma forma de fazer testes mas como um processo de pensar e executar testes ao longo de toda a gama de necessidades de uma aplicação (de unitários e visuais).

Essa conversa é a parte mais importante do BDD e, no caso do Rails e Ruby, o RSpec representa apenas uma faceta de tudo o que vem sendo pensado pela comunidade. Eventualmente, como Chelimsky coloca, TDD será um parte de algo maior que será chamado de BDD.

Finalizando

A confusão experimentada atualmente é mais resultado da conversação acima do que da diferença real entre os frameworks. Ainda citando Chelimsky, quando BDD era somente sobre testes unitários, não havia diferença nenhum entre TDD e BDD. Ambos eram e são sobre a melhor forma de testar uma aplicação e nada mais do que isso.

Para dar um exemplo, atualmente eu tenho preferido a combinação Test/Unit + Shoulda + RR ao invés do meu usual RSpec. Gosto da leveza dos anteriores em relação ao último quando os testes se tornam mais envolvidos. Mas isso representa apenas dores de crescimento do RSpec. É bem possível que quando este último estiver mais estabilizado, lidando mais com a magia negra que ele precisa para sua sintaxe, eu mude novamente de prática.

De uma forma geral, então, escolha o frameworks que melhor lhe convier. Desde que a forma como você faz testes esteja correta, o resultado final estará correto também.

14 Replies to “Algumas considerações sobre TDD e BDD”

  1. Esse negócio de inventar sigla é um vício perigoso em nossa área. Criou-se muita nebulosidade e confusão nesse ponto (TDD, BDD, DDD etc), sem necessidade.

    Um ponto sempre deve ser central, independente da sigla que você usa é nunca testar o código escrito e sim o comportamento do software (ex: não testar se existe um named_scope ou um método específico numa classe, mas se o resultado e as interações esperadas estão corretos).

    Outra coisa que acredito ser muito importante é derrubar o mito de frameworks de BDD. Framework não faz nada. Desenvolvedores sim. Alguns frameworks, como RSpec, uitilizam um vocabulário mais adequado, que deve auxiliar na mudança de pensamento, que é o que importa, e não fazem nada além disso.

  2. Concordo com a questão de siglas. O pessoal do BDD parece estar chegando em um consenso de separação nesse sentido. Acho que dá para clarificar bastante a questão se isso acontecer.

    Sobre frameworks, usei no sentido original de estrutura básica, conceito por trás de um sistema ou método. Eu não ligo para frameworks em si no sentido de biblioteca. Um é igual a meia dúzia. Mas gosto de estruturas gerais. 🙂

  3. Excelente o artigo!
    Finalmente vejo um artigo em português realmente esclarecedor sobre TDD/BDD.
    Já havia lido sobre em artigos de Dan North, David Chelimsky, Dave Astels, entre outros não brasileiros e achava que estava faltando algo do tipo em nossa língua.

    Muito obrigado!

  4. Bem,
    Primeiro, uma dúvida: o que seria RR?
    Eu já li um pouco a respeito de testes mas ainda não comecei a usar.
    Gostaria que, se possível, vocês me indicassem por onde começar. Devo ler a documentação do Rspec/ Test/Unit? Há algum bom livro ensinando como devem ser feitos os testes?
    Sabendo que nunca utilizei nenhum framework, com qual devo começar? É mais questão de gosto?
    E desculpe pelo excesso de perguntas 🙂

  5. Æ!!

    Parabens pelo artigo Ronaldo!
    Espero que os brasileiros comecem a postar mais sobre testes, por que não tenho visto muitos posts sobre testes.

    Um post “tutorial” como programar com testes seria legal! =)

    Há braços

  6. Ronaldo,

    Essa parte: “É bem possível que quando este último estiver mais estabilizado, lidando mais com a magia negra que ele precisa para sua sintaxe, eu mude novamente de prática.”

    Me deixou curioso sobre uma questão, qual sua visão hoje, 09 de março de 2009, sobre os frameworks pra testes de aplicação? Desde que você escreveu o post, houve alguma mudança? E o que você acrescentaria neste post, se fosse reescrevê-lo hoje?

    Tá parecendo entrevista, né, rs, mas é só curiosidade mesmo. Penso que suas novas experiências (desde a época até o momento) podem ter construido novos conceitos, então peço que compartilhe conosco 😉

  7. Brilhante o post. Lendo quase 4 anos depois de escrito ainda possui um conteúdo relevante.

    Estou há poucos dias estudando testes no Rails e desejo aplicá-lo nos projetos atuais e futuros. Tentei usar o framework nativo do Rails, RSpec e agora MiniTest. Por serem 3 opções fortes ainda estou indeciso sobre qual devo me focar. Depois deste artigo estou inclinado a escolher a abordagem BDD.

    Parabéns!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.