{"id":311,"date":"2009-09-07T23:59:30","date_gmt":"2009-09-07T22:59:30","guid":{"rendered":"http:\/\/www.dtsato.com\/blog\/?page_id=311"},"modified":"2009-09-08T00:16:42","modified_gmt":"2009-09-07T23:16:42","slug":"introduzindo_desenvolvimento_orientado_comportamento_bdd","status":"publish","type":"page","link":"https:\/\/www.dtsato.com\/blog\/work\/introduzindo_desenvolvimento_orientado_comportamento_bdd\/","title":{"rendered":"Introduzindo Desenvolvimento Orientado por Comportamento (BDD)"},"content":{"rendered":"<p><em>Esta \u00e9 uma tradu\u00e7\u00e3o do artigo <a href=\"http:\/\/dannorth.net\/introducing-bdd\">Introducing BDD<\/a>, escrito por <a href=\"http:\/\/dannorth.net\">Dan North<\/a> e traduzido por  <a href=\"http:\/\/www.lixo.org\">Carlos Vilella<\/a> e <a href=\"http:\/\/www.dtsato.com\">Danilo Sato<\/a><\/em><\/p>\n<p>Eu estava com um problema. Ao usar e ensinar pr\u00e1ticas \u00e1geis como Test-Driven Development (Desenvolvimento Orientado por Testes ou TDD) em diferentes projetos, acabava topando sempre com as mesmas confus\u00f5es e desentendimentos. Programadores queriam saber por onde come\u00e7ar, o que testar e o que n\u00e3o testar, quanto testar de cada vez, como dar nomes aos testes e como entender a causa de uma falha.<\/p>\n<p>Quanto mais eu me aprofundei em TDD, mais eu senti que minha pr\u00f3pria jornada n\u00e3o tinha sido um processo gradual e cont\u00ednuo (<em>&#8220;p\u00f5e a cera, tira a cera&#8221;<\/em>), mas sim uma s\u00e9rie enorme de becos sem sa\u00edda. Me lembro de pensar muito mais em <em>\u201cse pelo menos algu\u00e9m tivesse me dito isso!\u201d<\/em> do que <em>\u201cuau, uma porta se abriu\u201d<\/em>. Decidi que tinha que ser poss\u00edvel apresentar TDD de uma maneira que mostra diretamente as qualidades da t\u00e9cnica, evitando todas as armadilhas.<\/p>\n<p>Minha resposta \u00e9 o <strong>Behaviour-Driven Development<\/strong> (Desenvolvimento Orientado por Comportamentos ou BDD). Esta t\u00e9cnica evoluiu a partir de pr\u00e1ticas \u00e1geis estabelecidas e seu intuito \u00e9 torna-las mais acess\u00edveis e efetivas para times que est\u00e3o dando seus primeiros passos no desenvolvimento \u00e1gil de software. Com o tempo, BDD se amplout o cen\u00e1rio mais abrangente de an\u00e1lise \u00e1gil e testes de aceita\u00e7\u00e3o automatizados.<\/p>\n<h3>Nomes de m\u00e9todos devem ser frases<\/h3>\n<p>Meu primeiro \u201caha!\u201d aconteceu quando me mostraram um utilit\u00e1rio extremamente simples, <a href=\"http:\/\/agiledox.sourceforge.net\/\">agiledox<\/a>, escrito pelo meu colega Chris Stevenson. O agiledox l\u00ea uma classe de testes do JUnit e exibe o nome dos m\u00e9todos em forma de frases, ent\u00e3o um conjunto de testes assim:<\/p>\n<pre lang=\"java\">\r\npublic class CustomerLookupTest extends TestCase {\r\n  public void testFindsCustomerById() {\r\n    ...\r\n  }\r\n  public void testFailsForDuplicateCustomers() {\r\n    ...\r\n  }\r\n}\r\n<\/pre>\n<p>fica mais ou menos assim:<\/p>\n<pre>\r\nCustomerLookup\r\n- finds customer by id\r\n- fails for duplicate customers\r\n- ...\r\n<\/pre>\n<p>A palavra \u201ctest\u201d \u00e9 removida tanto do nome da classe quanto do nome dos m\u00e9todos e o texto do nome do m\u00e9todo \u00e9 convertido de camel-case para uma frase comum. Isso \u00e9 tudo que o agiledox faz, mas seu efeito \u00e9 impressionante.<\/p>\n<p>Os desenvolvedores descobriram que ele poderia ajud\u00e1-los gerando pelo menos uma parte da documenta\u00e7\u00e3o e come\u00e7aram a nomear os m\u00e9todos de teste com frases que faziam sentido. Melhor ainda, eles descobriram que quando escreviam nomes de m\u00e9todos na linguagem do cliente, os documentos gerados faziam sentido para o cliente, analistas e testadores.<\/p>\n<h3>Um modelo de frase simples mant\u00e9m o foco do teste<\/h3>\n<p>Ent\u00e3o eu descobri a conven\u00e7\u00e3o de usar a palavra &#8220;deveria&#8221; (<em>&#8220;should&#8221;<\/em>) nos m\u00e9todos de teste. Este modelo \u2013 a classe <em>&#8220;deveria&#8221;<\/em> fazer alguma coisa \u2013 implica que voc\u00ea s\u00f3 pode definir um teste para uma classe espec\u00edfica. Isso mant\u00e9m seu foco. Se voc\u00ea estiver escrevendo um teste cujo nome n\u00e3o se encaixa no modelo, ent\u00e3o pode ser que o comportamento que voc\u00ea est\u00e1 tentando testar pertence a outro lugar.<\/p>\n<p>Por exemplo: eu estava escrevendo uma classe para valida\u00e7\u00e3o de entrada de uma tela. A maioria dos campos eram detalhes comuns de um cliente \u2013 nome, sobrenome, etc. \u2013 al\u00e9m de campos para data de nascimento e idade. Eu comecei escrevendo um <code>ClientDetailsValidatorTest<\/code> com m\u00e9todos como <code>testShouldFailForMissingSurname<\/code> e <code>testShouldFailForMissingTitle<\/code>.<\/p>\n<p>Comecei a desenvolver a l\u00f3gica para calcular a idade e entrei num mundo confuso de regras de neg\u00f3cio: e se a idade e a data de nascimento forem preenchidas mas n\u00e3o coincidirem? E se a data de nascimento \u00e9 hoje? Como calcular a idade se tudo que eu tenho \u00e9 a data de nascimento? Eu estava escrevendo testes com nomes cada vez mais complicados para descrever tais comportamentos, ent\u00e3o eu decidi move-los para outro lugar. Isso me levou a criar uma nova classe, <code>AgeCalculator<\/code>, com seu pr\u00f3prio <code>AgeCalculatorTest<\/code>. Com todos os comportamentos relacionados ao c\u00e1lculo de idades movidos para a calculadora, o validador s\u00f3 precisava de um teste nessa \u00e1rea para garantir que ele interagia corretamente com a calculadora.<\/p>\n<p>Se uma classe est\u00e1 fazendo mais de uma coisa, eu geralmente tomo como indica\u00e7\u00e3o que eu devo introduzir outras classes para fazer um pouco do trabalho. Eu defino o novo servi\u00e7o como uma interface descrevendo o que ele faz, e passo o servi\u00e7o atrav\u00e9s do construtor da classe:<\/p>\n<pre lang=\"java'>\r\npublic client ClientDetailsValidator {\r\n  private final AgeCalculator ageCalc;\r\n    public ClientDetailsValidator(AgeCalculator ageCalc) {\r\n      this.ageCalc = ageCalc;\r\n  }\r\n}\r\n<\/pre>\n<p>Esta maneira de conectar os objetos, conhecida como \u201cinje\u00e7\u00e3o de depend\u00eancias&#8221; (<a href=\"http:\/\/www.martinfowler.com\/articles\/injection.html\">dependency injection<\/a>), \u00e9 especialmente \u00fatil em conjunto com mocks.<\/p>\n<h3>Um nome de teste expressivo ajuda quando o teste falha<\/h3>\n<p>Depois de um tempo, descobri que quando eu modificava c\u00f3digo que fazia um teste falhar, eu podia olhar para o nome do m\u00e9todo de teste e identificar qual o comportamento esperado do c\u00f3digo. Tipicamente, uma das tr\u00eas coisas havia acontecido:<\/p>\n<ul>\n<li>Eu introduzi um bug. Oops. Solu\u00e7\u00e3o: consertar o bug.<\/li>\n<li>O comportamento esperado ainda era relevante mas se mudou para outro lugar. Solu\u00e7\u00e3o: mover o teste e talvez modific\u00e1-lo.<\/li>\n<li>O comportamento n\u00e3o era mais esperado. Solu\u00e7\u00e3o: remover o teste.<\/li>\n<\/ul>\n<p>O \u00faltimo acontece comumente em projetos \u00e1geis, conforme a compreens\u00e3o da solu\u00e7\u00e3o amadurece. Infelizmente, praticantes novatos de TDD t\u00eam um medo inato de apagar testes, como se de certa forma isso reduzisse a qualidade do c\u00f3digo.<\/p>\n<p>Um aspecto mais sutil da palavra &#8220;deveria&#8221; se torna aparente quando comparada com alternativas mais formais, como &#8220;ir\u00e1&#8221; (&#8220;will&#8221;) ou &#8220;vai&#8221; (&#8220;shall&#8221;). &#8220;Deveria&#8221; lhe permite, implicitamente, duvidar da premissa do teste: &#8220;Deveria? Mesmo?&#8221; Isto torna mais f\u00e1cil decidir se um teste est\u00e1 falhando por causa de um bug introduzido recentemente ou simplesmente porque suas premissas sobre o comportamento do sistema mudaram.<\/p>\n<h3>&#8220;Comportamento&#8221; \u00e9 uma palavra mais \u00fatil que &#8220;teste&#8221;<\/h3>\n<p>Agora eu tinha uma ferramenta &#8211; agiledox &#8211; para remover a palavra &#8220;test&#8221; e um padr\u00e3o para os nomes de m\u00e9todos de teste. Me ocorreu, ent\u00e3o, que as dificuldades que muitas pessoas tem com TDD quase sempre vem da palavra &#8220;teste&#8221;.<\/p>\n<p>Isso n\u00e3o quer dizer que testar n\u00e3o \u00e9 intr\u00ednseco ao TDD \u2013 o conjunto de m\u00e9todos resultante \u00e9 uma maneira efetiva de garantir que seu c\u00f3digo funciona. No entanto, se os m\u00e9todos n\u00e3o descrevem completamente o comportamento do sistema, eles provavelmente est\u00e3o trazendo uma falsa sensa\u00e7\u00e3o de seguran\u00e7a.<\/p>\n<p>Comecei a usar a palavra &#8220;comportamento&#8221; no lugar de &#8220;teste&#8221; quando utilizava TDD e descobri n\u00e3o s\u00f3 que a palavra se encaixava no contexto, como tamb\u00e9m que uma categoria inteira de d\u00favidas se dissipou magicamente. Agora eu tinha respostas para alguma dessas quest\u00f5es sobre TDD. Fica f\u00e1cil nomear seu teste: \u00e9 uma senten\u00e7a descrevendo o pr\u00f3ximo comportamento em que voc\u00ea est\u00e1 interessado. Quanto testar se torna uma quest\u00e3o simples: n\u00e3o d\u00e1 pra descrever em uma frase muito mais do que o comportamento necess\u00e1rio. Quando um teste falha, basta seguir o processo descrito anteriormente: ou um bug foi introduzido, ou o comportamento mudou ou o teste n\u00e3o \u00e9 mais relevante.<\/p>\n<p>Descobri que a diferen\u00e7a entre pensar em testes e pensar em comportamentos \u00e9 t\u00e3o profunda que comecei a me referir a TDD como BDD, ou <strong>Behaviour-Driven Development<\/strong>.<\/p>\n<h3>JBehave d\u00e1 mais \u00eanfase ao comportamento do que aos testes<\/h3>\n<p>No fim de 2003, decidi me dedicar a isso, era a hora de colocar dinheiro &#8211; ou pelo menos esfor\u00e7o &#8211; no que eu falava. Comecei a escrever um substituto ao JUnit chamado JBehave, que removia qualquer refer\u00eancia a testes, substituindo-as com um vocabul\u00e1rio constru\u00eddo a partir da verifica\u00e7\u00e3o de comportamento. Eu fiz isso para ver o quanto um framework assim evoluiria se eu aderisse estritamente aos meus mantras. Eu tamb\u00e9m pensei que seria uma ferramenta de ensino valiosa para introduzir TDD e BDD sem a distra\u00e7\u00e3o causada pelo vocabul\u00e1rio baseado em testes.<\/p>\n<p>Para definir o comportamento de uma classe hipot\u00e9tica chamada <code>CustomerLookup<\/code>, eu escreveria uma classe de comportamento chamada, por exemplo, <code>CustomerLookupBehaviour<\/code>. Ela conteria m\u00e9todos que come\u00e7am com &#8220;should&#8221; (&#8220;deveria&#8221;). O verificador de comportamentos iria instanciar essa classe e chamar cada m\u00e9todo em sequ\u00eancia, assim como o JUnit. De forma similar, geraria um relat\u00f3rio e um resumo das opera\u00e7\u00f5es executadas.<\/p>\n<p>Minha primeira meta foi fazer com que o JBehave se auto-verificasse. Eu apenas adicionei o comportamento necess\u00e1rio para o JBehave se auto-executar. Eu pude ent\u00e3o migrar todos os testes do JUnit para comportamentos do JBehave, obtendo o mesmo feedback imediato proporcionado pelo JUnit.<\/p>\n<h3>Determine o pr\u00f3ximo comportamento mais importante<\/h3>\n<p>Ent\u00e3o eu descobri o conceito de <strong>valor de neg\u00f3cio<\/strong>. Eu sempre tive consci\u00eancia de que eu escrevia software por um motivo, \u00e9 claro, mas nunca tinha realmente pensado sobre o valor do c\u00f3digo que eu estava escrevendo a cada momento. Outro colega, o analista de neg\u00f3cios Chris Matts, me fez pensar sobre o valor de neg\u00f3cio no contexto de BDD.<\/p>\n<p>J\u00e1 que eu tinha em mente o objetivo de tornar o JBehave auto-contido, eu achei uma maneira bem \u00fatil de me manter focado nas perguntas que eu tinha que fazer: qual \u00e9 a pr\u00f3xima coisa mais importante que o sistema n\u00e3o faz?<\/p>\n<p>Esta pergunta faz com que voc\u00ea identifique o valor das funcionalidades que ainda n\u00e3o est\u00e3o implementadas e priorize-as. Ela tamb\u00e9m ajuda a formular o nome do m\u00e9todo de comportamento: o sistema n\u00e3o faz X (onde X \u00e9 algum comportamento significativo), e X \u00e9 importante, o que quer dizer que ele deveria fazer X; ent\u00e3o seu pr\u00f3ximo m\u00e9todo de comportamento \u00e9 simplesmente:<\/p>\n<pre lang=\"java\">\r\npublic void shouldDoX() {\r\n    \/\/ \u2026\r\n}\r\n<\/pre>\n<p>Agora eu tinha a resposta para outra d\u00favida a respeito de TDD: saber por onde come\u00e7ar.<\/p>\n<h3>Requisitos tamb\u00e9m s\u00e3o comportamentos<\/h3>\n<p>Nesse ponto, eu tinha um framework que me ajudava a entender &#8211; e mais importante, explicar &#8211; como TDD funciona e uma abordagem que evitava todas as armadilhas que eu j\u00e1 havia encontrado.<\/p>\n<p>Ao fim de 2004, enquanto eu estava descrevendo o meu novo vocabul\u00e1rio para o Chris, ele disse: &#8220;Mas isso \u00e9 exatamente como an\u00e1lise.&#8221; Houve uma longa pausa enquanto process\u00e1vamos isso, e ent\u00e3o decidimos aplicar todo esse pensamento orientado a comportamentos para definir requisitos. Se pud\u00e9ssemos desenvolver um vocabul\u00e1rio consistente entre analistas, testadores, desenvolvedores e o cliente, estar\u00edamos no caminho certo para eliminar algumas das ambiguidades e problemas de comunica\u00e7\u00e3o que ocorrem quando t\u00e9cnicos falam com clientes.<\/p>\n<h3>BDD oferece uma &#8220;linguagem ub\u00edqua&#8221; para an\u00e1lise<\/h3>\n<p>Nessa \u00e9poca, Eric Evans publicou seu livro best-seller Domain-Driven Design. Nele, ele descreve o conceito de modelar um sistema usando uma linguagem ub\u00edqua baseada no dom\u00ednio de neg\u00f3cio para que o vocabul\u00e1rio de neg\u00f3cio tamb\u00e9m permeie o c\u00f3digo.<\/p>\n<p>Chris e eu percebemos que est\u00e1vamos tentando definir uma linguagem ub\u00edqua para o pr\u00f3prio processo de an\u00e1lise! N\u00f3s t\u00ednhamos um bom in\u00edcio. Um padr\u00e3o para escrever hist\u00f3rias j\u00e1 estava sendo usado na empresa, seguindo o seguinte modelo:<\/p>\n<p><code><br \/>\n<strong>Como um<\/strong> [X]<br \/>\n<strong>Eu gostaria de<\/strong> [Y]<br \/>\n<strong>Para que<\/strong> [Z]<br \/>\n<\/code><\/p>\n<p>Onde Y \u00e9 alguma funcionalidade, Z \u00e9 o benef\u00edcio ou valor de neg\u00f3cio da funcionalidade, e X \u00e9 a pessoa (ou papel) que vai se beneficiar dela. A vantagem \u00e9 que ela te for\u00e7a a identificar o valor de entregar uma hist\u00f3ria quando voc\u00ea inicialmente a define. Quando n\u00e3o existe valor de neg\u00f3cio real para uma hist\u00f3ria, ela normalmente acaba definida como algo do tipo &#8220;&#8230;Eu gostaria de [alguma funcionalidade]&#8230; para que [porque eu quero, ok?]&#8221; Fazer isto tamb\u00e9m pode tornar mais f\u00e1cil remover alguns requisitos mais esot\u00e9ricos do caminho.<\/p>\n<p>A partir deste ponto, o Chris e eu come\u00e7amos a descobrir o que todo testador \u00e1gil j\u00e1 sabe: o comportamento de uma hist\u00f3ria \u00e9 simplesmente seu teste de aceita\u00e7\u00e3o &#8211; se o sistema atende a todos os crit\u00e9rios de aceita\u00e7\u00e3o, ele est\u00e1 se comportando corretamente; caso contr\u00e1rio, n\u00e3o. Ent\u00e3o criamos um modelo para capturar os crit\u00e9rios de aceita\u00e7\u00e3o de uma hist\u00f3ria.<\/p>\n<p>O modelo deveria ser flex\u00edvel o suficiente para n\u00e3o parecer artificial ou restritivo para os analistas, por\u00e9m estruturado o suficiente para que pud\u00e9ssemos quebrar as hist\u00f3rias em peda\u00e7os que pudessem ser automatizados. N\u00f3s come\u00e7amos a descrever os crit\u00e9rios de aceita\u00e7\u00e3o com base nos cen\u00e1rios, da seguinte forma:<\/p>\n<p><code><br \/>\n<strong>Dado<\/strong> algum contexto inicial (entradas),<br \/>\n<strong>Quando<\/strong> um evento ocorre (eventos),<br \/>\n<strong>Ent\u00e3o<\/strong> verifique alguns resultados (sa\u00eddas)<br \/>\n<\/code><\/p>\n<p>Para ilustrar, vamos usar o exemplo cl\u00e1ssico de um caixa autom\u00e1tico. Uma das hist\u00f3rias poderia ser mais ou menos assim:<\/p>\n<p><code><br \/>\n<u>T\u00edtulo: Cliente retira dinheiro<\/u><br \/>\n<em>Como<\/em> um cliente,<br \/>\n<em>Eu gostaria de<\/em> retirar dinheiro de um caixa autom\u00e1tico,<br \/>\n<em>Para que<\/em> eu n\u00e3o tenha que esperar numa fila de banco.<br \/>\n<\/code><\/p>\n<p>Como sabemos quando essa hist\u00f3ria est\u00e1 entregue? Existem diversos cen\u00e1rios a considerar: a conta pode estar em cr\u00e9dito, a conta pode estar negativa mas com limite ou ainda estar com o limite estourado. Haver\u00e3o outros cen\u00e1rios, \u00e9 claro, como quando a conta est\u00e1 em cr\u00e9dito mas uma retirada a torna negativa ou quando o caixa autom\u00e1tico n\u00e3o tem dinheiro suficiente para completar a opera\u00e7\u00e3o.<\/p>\n<p>Usando o modelo entradas-eventos-sa\u00eddas (<em>given-when-then<\/em>), os dois primeiros cen\u00e1rios poderiam ficar assim:<\/p>\n<p><code><br \/>\n<u>Cen\u00e1rio 1: Conta est\u00e1 em cr\u00e9dito<\/u><br \/>\n<em>Dado que<\/em> a conta est\u00e1 em cr\u00e9dito<br \/>\n<em>E<\/em> o cart\u00e3o \u00e9 v\u00e1lido<br \/>\n<em>E<\/em> o caixa tem dinheiro suficiente<br \/>\n<em>Quando<\/em> o cliente requisita dinheiro<br \/>\n<em>Ent\u00e3o<\/em> verifique que a conta foi debitada<br \/>\n<em>E<\/em> verifique que o dinheiro \u00e9 entregue<br \/>\n<em>E<\/em> verifique que o cart\u00e3o \u00e9 devolvido<br \/>\n<\/code><\/p>\n<p>Perceba o uso da palavra &#8220;e&#8221; para conectar m\u00faltiplas entradas e m\u00faltiplas sa\u00eddas de forma natural.<\/p>\n<p><code><br \/>\n<u>Cen\u00e1rio 2: Conta est\u00e1 negativa al\u00e9m do limite<\/u><br \/>\n<em>Dado<\/em> que a conta est\u00e1 negativa<br \/>\n<em>E<\/em> o cart\u00e3o \u00e9 v\u00e1lido<br \/>\n<em>Quando<\/em> o cliente requisita dinheiro<br \/>\n<em>Ent\u00e3o<\/em> verifique que uma mensagem de rejei\u00e7\u00e3o \u00e9 mostrada<br \/>\n<em>E<\/em> o dinheiro n\u00e3o \u00e9 entregue<br \/>\n<em>E<\/em> o cart\u00e3o \u00e9 devolvido<br \/>\n<\/code><\/p>\n<p>Ambos cen\u00e1rios s\u00e3o baseados no mesmo evento e at\u00e9 tem algumas entradas e sa\u00eddas em comum. Idealmente, n\u00f3s queremos economizar tempo e reusar entradas, eventos e sa\u00eddas.<\/p>\n<h3>Crit\u00e9rios de aceita\u00e7\u00e3o devem ser execut\u00e1veis<\/h3>\n<p>Os fragmentos do cen\u00e1rio \u2013 as entradas, eventos e sa\u00eddas &#8211; s\u00e3o suficientemente detalhados para ser representados diretamente no c\u00f3digo. O JBehave define um modelo de objetos que permite mapear um cen\u00e1rio diretamente em classes Java.<\/p>\n<p>Voc\u00ea escreve uma classe representando cada entrada (<em>given<\/em>):<\/p>\n<pre lang=\"java\">\r\npublic class AccountIsInCredit implements Given {\r\n   public void setup(World world) {\r\n      \u2026\r\n   }\r\n}\r\npublic class CardIsValid implements Given {\r\n   public void setup(World world) {\r\n      \u2026\r\n   }\r\n}\r\n<\/pre>\n<p>e uma para o evento (<em>when<\/em>):<\/p>\n<pre lang=\"java\">\r\npublic class CustomerRequestsCash implements Event {\r\n   public void occurIn(World world) {\r\n      \u2026\r\n   }\r\n}\r\n<\/pre>\n<p>e assim por diante, para as sa\u00eddas (<em>then<\/em>). O JBehave ent\u00e3o conecta todos estes objetos e os executa. Ele cria um &#8220;mundo&#8221;, que \u00e9 apenas um lugar para guardar seus objetos, e o passa para cada uma das entradas, uma de cada vez, para que elas populem o mundo com informa\u00e7\u00f5es conhecidas sobre o estado da aplica\u00e7\u00e3o. O JBehave ent\u00e3o diz ao evento para &#8220;ocorrer dentro do&#8221; mundo, que efetivamente roda o comportamento do cen\u00e1rio. Finalmente, ele passa o controle \u00e0s sa\u00eddas que definimos para a hist\u00f3ria.<\/p>\n<p>Usando uma classe para representar cada fragmento nos possibilita a reutiliza\u00e7\u00e3o em outros cen\u00e1rios ou hist\u00f3rias. Inicialmente, os fragmentos s\u00e3o implementados usando <em>mocks<\/em> para criar uma conta que est\u00e1 em cr\u00e9dito ou um cart\u00e3o v\u00e1lido. Estes servem como ponto de partida para implementar os comportamentos. Conforme voc\u00ea implementa a aplica\u00e7\u00e3o, as entradas e sa\u00eddas s\u00e3o alterados para usar as classes de verdade que foram implementadas,de forma que quando a implementa\u00e7\u00e3o do cen\u00e1rio for finalizada, voc\u00ea ter\u00e1 verdadeiros testes funcionais de ponta a ponta.<\/p>\n<h3>O presente e o futuro do BDD<\/h3>\n<p>Ap\u00f3s uma breve pausa, o JBehave est\u00e1 novamente em desenvolvimento. O n\u00facleo est\u00e1 bem completo e robusto. O pr\u00f3ximo passo \u00e9 a integra\u00e7\u00e3o com IDEs Java populares, como o IntelliJ IDEA e o Eclipse.<\/p>\n<p><a href=\"http:\/\/daveastels.com\/\">Dave Astels<\/a> est\u00e1 promovendo o BDD ativamente. Os posts no seu blog e diversos artigos publicados provocaram uma enxurrada de atividades, mais notavelmente o projeto <a href=\"http:\/\/rspec.info\">RSpec<\/a>, um framework para BDD escrito em Ruby. Eu comecei a trabalhar no RBehave, que ser\u00e1 uma implementa\u00e7\u00e3o do JBehave em Ruby (<em>nota do tradutor: atualmente, o projeto ativo \u00e9 o <a href=\"http:\/\/cukes.info\/\">cucumber<\/a>, inspirado no Story Runner implementado por Dan North no RBehave<\/em>).<\/p>\n<p>V\u00e1rios colegas de trabalho t\u00eam usado t\u00e9cnicas de BDD em diversos projetos do mundo real e as t\u00e9cnicas se mostraram eficientes. O mecanismo de execu\u00e7\u00e3o de hist\u00f3rias do JBehave &#8211; a parte que verifica os cen\u00e1rios de aceita\u00e7\u00e3o &#8211; est\u00e1 em constante desenvolvimento.<\/p>\n<p>A vis\u00e3o \u00e9 ter um editor integrado que permite que analistas de neg\u00f3cio e testadores capturem hist\u00f3rias num editor de textos que pode gerar <em>stubs<\/em> para as classes de comportamento, todos numa linguagem compat\u00edvel com o dom\u00ednio de neg\u00f3cio. O BDD evoluiu com a ajuda de muitas pessoas e sou profundamente grato a todas elas.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Esta \u00e9 uma tradu\u00e7\u00e3o do artigo Introducing BDD, escrito por Dan North e traduzido por Carlos Vilella e Danilo Sato Eu estava com um problema. Ao usar e ensinar pr\u00e1ticas \u00e1geis como Test-Driven Development (Desenvolvimento Orientado por Testes ou TDD) em diferentes projetos, acabava topando sempre com as mesmas confus\u00f5es e desentendimentos. Programadores queriam saber [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":87,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-311","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.dtsato.com\/blog\/wp-json\/wp\/v2\/pages\/311","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dtsato.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.dtsato.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.dtsato.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dtsato.com\/blog\/wp-json\/wp\/v2\/comments?post=311"}],"version-history":[{"count":11,"href":"https:\/\/www.dtsato.com\/blog\/wp-json\/wp\/v2\/pages\/311\/revisions"}],"predecessor-version":[{"id":324,"href":"https:\/\/www.dtsato.com\/blog\/wp-json\/wp\/v2\/pages\/311\/revisions\/324"}],"up":[{"embeddable":true,"href":"https:\/\/www.dtsato.com\/blog\/wp-json\/wp\/v2\/pages\/87"}],"wp:attachment":[{"href":"https:\/\/www.dtsato.com\/blog\/wp-json\/wp\/v2\/media?parent=311"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}