sexta-feira, 7 de dezembro de 2012

Behavior Driven Development




Behavior Driven Development (BDD) ou ainda uma tradução livre Desenvolvimento Guiado por Comportamento é uma técnica de desenvolvimento Ágil que encoraja colaboração entre desenvolvedores, setores de qualidade e pessoas não técnicas ou de negócios num projeto de software. Foi originalmente concebido em 2003, por Dan North [1]como uma resposta à TDD, e tem se expandido bastante nos últimos anos (Behavior Driven Development, 2012). No BDD, os testes de aceitação são descritos em linguagens naturais próximas do domínio do negócio usando DSL. Para estes testes de aceitação são usadas DSTL e se estes possuírem formalidade suficiente podem ser interpretados e executados por uma ferramenta especializada (CAETANO, 2012). Os testes descritos em linguagem natural são interpretados por ferramentas especializadas que, por sua vez, exercitam o código/API do sistema para demonstrar se o comportamento foi atendido.
O BDD pode ser visto como uma evolução da técnica de programação TDD [ (AL., 2009), e compartilha com essa técnica a característica principal de se escrever testes antes de escrever a implementação do que está sendo testado, para então desenvolvê-la até que o teste passe. (RIMMER, 2010) mostra que outra forma de se ver o BDD é como uma nova compreensão sobre o processo de TDD que estabelece que o teste não é o ponto central real da técnica, mas sim a descoberta e compreensão, através da definição dos testes, do comportamento que está se querendo obter com um código. O processo de BDD incrementa o TDD de forma a resolver algumas questões em aberto com as seguintes práticas: cada funcionalidade deve ser claramente compreendida por ambas partes (desenvolvedores e clientes), para isso se deve usar uma linguagem para os casos de teste compreensível a ambas partes, uma vez que os casos de teste são na realidade especificações de comportamento; cada funcionalidade deve possuir um valor claro e verificável para o negócio, de modo a priorizar o mais importante e evitar o que pode não vir a ser necessário; deve-se planejar a frente o mínimo possível, escrevendo testes para o menor e mais prioritário subconjunto de funcionalidades possível e o desenvolvendo antes de adicionar mais funcionalidades (AL., 2009).
O foco em BDD é a linguagem e interações usadas no processo de desenvolvimento de software. O BDD propicia o uso da língua nativa, a linguagem natural, em combinação com a linguagem ubíqua (usada no processo de desenvolvimento de software) permitindo que os desenvolvedores foquem em por que o código deve ser criado, ao invés de detalhes técnicos minimizando assim, traduções entre linguagem técnica na qual o código é escrito e outras linguagens de domínio, usuários, clientes, gerência do projeto, etc. (NORTH, 2006).

As práticas de BDD incluem:
       Envolver as partes interessadas no processo através de Outside-in Development (Desenvolvimento de Fora pra Dentro)
       Usar exemplos para descrever o comportamento de uma aplicação ou unidades de código
       Automatizar os exemplos para prover um feedback rápido e testes de regressão
   Usar deve (should em inglês) na hora de descrever o comportamento de software para ajudar esclarecer responsabilidades e permitir que funcionalidades do software sejam questionadas
     Usar dublês de teste [2](mocks, stubs, fakes, dummies, spies) para auxiliar na colaboração entre módulos e códigos que ainda não foram escritos


BDD é guiado pelos valores de negócios; que é o benefício trazido para o negócio no qual a aplicação está sendo produzida. A única maneira na qual o benefício pode ser percebido é através de interfaces de usuário para a aplicação, comumente (mas nem sempre) a interface gráfica de usuário. Da mesma maneira, cada trecho de código, começando com a interface de usuário, pode ser considerado como sendo um cliente de outros módulos de código no qual a interface é utilizada. Cada elemento de código provê algum comportamento, o qual em colaboração com outros elementos provê o comportamento da aplicação. A primeira parte de código de produção que os desenvolvedores que usam BDD implementam é a interface de usuário, pois dessa maneira os desenvolvedores podem se beneficiar com um feedback rápido para saber se a interface está adequada ou não. Através de código, e usando princípios de design e refatoração, desenvolvedores descobrem colaboradores para a interface de usuário, e posteriormente para cada unidade de código. Isso os ajuda a aderirem o princípio de YAGNI, desde que cada trecho de código de produção é requerido pelos negócios ou por outro trecho de código já escrito (Behavior Driven Development, 2012).
Devido ao impacto da aplicação de BDD no projeto como um todo ele se tornou uma metodologia ágil de segunda geração. (Primeira geração, Scrum, XP. Segunda geração BDD). Segundo (CHELIMSKY, ASTELS, et al., 2010) o desenvolvimento guiado por comportamento se baseia em três princípios básicos:

       O bastante é o bastante: Planejamento antecipado, análise, e design são atividades que possuem um retorno decrescente. Não deve-se fazer menos do que o necessário para iniciar o projeto, porém, mais do que isso é desperdício de esforço. Isso também se aplica à automação do processo. Ter um processo de implantação do sistema e testes automatizados é importante, mas deve-se evitar automatizar tudo.
       Entregar valor aos stakeholders: Se uma atividade não está entregando valor ou melhorando a capacidade de entregar valor, então não se deve executá-la e deve-se focar em outra atividade.
       Tudo é comportamento: Não importa se ao nível de código, à nível de aplicação, ou além, pode-se utilizar o mesmo pensamento e construção linguística para quaisquer níveis de granularidade.


Defensores de BDD alegam que o uso de "deve" (should) e "garantirQue" (ensureThat) em exemplos de BDD incentivam os desenvolvedores a questionarem se as responsabilidade que eles estão atribuindo aos seus objetos são apropriados, ou se elas podem ser delegadas ou movidas inteiramente para outros objetos. Um objeto que é mais simples que o código de colaboração e provê a mesma interface, porém com um comportamento mais previsível, pode ser injetado no código que precisa dele, e os exemplos de comportamento do código podem ser escrito usando estes objetos ao invés da versão de produção.
A palavra-chave para este tipo de técnica é "especificação executável” baseada no comportamento da aplicação. Especificações executáveis ​​têm muito mais chance de não serem abandonas, já escrevê-las, ao contrário de escrever estática não executável e tradicional documentação, torna-se efetivamente parte de todo o processo de desenvolvimento. Executando estas especificações é possível visualizar instantaneamente o que realmente o software em questão faz, enquanto no momento em que se inspeciona o código fonte é revelado somente o que este supostamente deveria realizar. Trazendo á tona um benefício desta prática, gerando para uma equipe praticante uma maior confiança em relação ao trabalho que está sendo desenvolvido


[1] Ativista da causa Ágil. Mais informações em: http://dannorth.net/
[2] Mais informações em: http://martinfowler.com/articles/mocksArentStubs.html

Testes Ágeis




A maioria dos métodos ágeis tenta delimitar e reduzir o risco pelo desenvolvimento do software em curtos períodos, denominados iterações, os quais despendem menos de uma semana de tempo a um máximo de quatro semanas, sendo que cada iteração é como um projeto de software em pequena escala do projeto principal, e inclui em si todas as tarefas necessárias para implantar um mini-incremento de uma nova funcionalidade: planejamento, análise de requisitos, projeto, codificação, teste e documentação (Desenvolvimento ágil de software, 2005). Enquanto em um processo convencional cada iteração não está necessariamente focando em adicionar um conjunto de funcionalidades, um projeto de software com metodologia ágil busca a capacidade de implantar uma versão nova do software ao fim de cada iteração, etapa a qual a equipe responsável reavalia as prioridades do projeto.
Pressman denota a filosofia do método ágil para desenvolvimento de software da seguinte forma:
 “A engenharia de software ágil combina uma filosofia e um conjunto de diretrizes de desenvolvimento. A filosofia encoraja a satisfação do cliente e a entrega incremental do software logo de início; equipes de projeto pequenas, altamente motivadas, métodos informais, produtos de trabalho de engenharia de software mínimos e simplicidade global de desenvolvimento. As diretrizes de desenvolvimento enfatizam a entrega em contraposição à análise e ao projeto (apesar dessas atividades não serem desencorajadas) e a comunicação ativa entre desenvolvedores e clientes” (PRESSMAN, 2002)

Métodos ágeis enfatizam comunicações em tempo real, preferencialmente in loco, em vez de documentação escrita. A maioria dos stakeholders de um grupo ágil deve estar agrupada em uma sala. Isso inclui todos aqueles necessários para terminar o software: no mínimo, os programadores, gerentes e/ou analistas de negócio e seus clientes. Nesta sala devem também se encontrar os testadores e projetistas. Métodos ágeis também enfatizam trabalho no software como uma medida primária de progresso. Combinado com a comunicação face-a-face, métodos ágeis produzem pouca documentação em relação a outros métodos, sendo este um dos pontos que podem ser considerados negativos (Desenvolvimento ágil de software, 2005). É recomendada apenas a produção de documentação que realmente será útil.
Segundo (NADALETE, 2010) em se tratando de desenvolvimento ágil, alguns princípios definidos por meio do Manifesto Ágil são utilizados com o objetivo de nortear a linha de produção, como:

       Indivíduos e interações entre eles mais que processos e ferramentas;
       Software em funcionamento mais que documentação abrangente;
       Colaboração com o cliente mais que negociação de contratos;
       Capacidade de responder a mudanças mais que seguir um plano.

Os mesmos princípios usados para direcionar o desenvolvimento ágil, devem ser considerados quando for aplicado teste ágil, ou seja, testar de forma ágil exige uma forte adaptação na rotina e dinâmica da equipe de teste, em relação ao processo de desenvolvimento adotado, com o objetivo de propiciar um processo relativamente simples e que possa ser executado com grande facilidade e agilidade, cobrindo o maior número de riscos, com um nível de qualidade que seja apreciada e valorizada pelo cliente ou usuário final (NADALETE, 2010).
Afirma (LEAL, 2009) que os requisitos para metodologias de teste para processos ágeis não possuem grande diferenciação em relação processos guiados por planos. O que é diferente é o grau de importância atribuído aos testes em cada um dos processos. Nos processos guiados por planos, existe uma extensa série de artefatos documentais resultantes de uma análise profunda sobre o sistema a ser desenvolvido. Sendo assim testes são utilizados nesse caso apenas como mais um artefato produzido pelo processo visando garantir a detecção de erros antes da liberação da versão final
Segundo análise comparativa realizada por (NETO, 2004) tomando como base os documentos gerados na etapa de testes o RUP orientado para pequenos projetos gera apenas um único documento que é o Modelo de Testes, já a XP gera quatro, que são os Testes de Aceitação, Testes de Dados, Testes de Resultados e Unidades de Testes (KENT, 1999).   Esses quatro documentos gerados na programação extrema são englobados num único documento no Processo Unificado da Rational, fazendo com que este artefato se torne extenso e abrangente, porém sendo tratado como único (KRUCHTEN, 2000)
Reitera (MÁRIO, 2009) que no processo XP antes do desenvolvimento do código, recomenda o processo, que se crie uma bateria de testes unitários para que a história fique satisfeita. Então o foco dos programadores é a satisfação destes testes unitários. Para a codificação o XP, recomenda que esta seja feita em pares, isto garante outros aspectos como qualidade, e rapidez. Os testes unitários são mantidos ao longo das várias iterações e passam a fazer parte de uma bateria de testes de regressão, que não é mais do que todos os testes unitários agrupados para serem testados periodicamente de uma vez em períodos curtos. A ideia é confirmar que nada deixou de funcionar. Os clientes são considerados parte da equipe de desenvolvimento, uma vez que a todo o momento são questionados sobre prioridades e testes de versões.
Ressalta-se que muitos métodos ágeis, como Lean, Scrum e XP recomendam que todas as pessoas de um projeto (programadores, gerentes, equipes de homologação e até mesmo os clientes) trabalhem controlando a qualidade do produto todos os dias e a todo o momento, pois acreditam que prevenir defeitos é mais fácil e barato que identificá-los e corrigi-los. A Programação eXtrema, em particular, recomenda explicitamente testes automatizados para ajudar a garantir a qualidade dos sistemas de software (BERNARDO, 2008). Através da definição do processo ideal e simplificado, onde o teste ágil é suportado, um conjunto de práticas que proporcionem a diminuição do tempo entre o erro e a sua descoberta tende a ser estabelecidos em conjunto com uma sistemática de trabalho que possibilite à área de teste de software ser mais proativa do que reativa.
Analisemos algumas das práticas do processo de teste tradicional aplicados na tentativa de gerenciar o "chaos", ou ao menos evitar culpados (HENDRICKSON, 2006).

       A área de teste de software assumindo a postura de "Último Defensor da Qualidade";
       Restrições no gerenciamento de mudanças;
       Preparação detalhada e planejamento acima de tudo;
       Conjunto de documentação pesado para a terceirização dos esforços de teste;
       Critérios de entrada e saída rigorosos e com aprovações;
       Automatização de testes pesada e com foco nas regressões;
       Tentativas de execução do processo.

Ao se tratar de teste ágil, essas mesmas práticas não se adaptam à dinâmica almejada. Em um ambiente ágil de controle de qualidade devem-se considerar os prazos e as atividades de teste do começo ao fim da iteração (NADALETE, 2010). Ao contrário do teste tradicional, não se espera que uma única equipe se responsabilize pela qualidade final das entregas, mas sim que todas as equipes tenham sua colaboração no controle dessa qualidade, desde o levantamento das necessidades do cliente, até a implantação do produto final gerado.
 Ainda afirma que no teste tradicional, espera-se que os defeitos sejam identificados no último nível, pela equipe de QA, enquanto que ao se aplicar teste ágil, isso é antecipado pela própria equipe de desenvolvimento por meio de práticas como desenvolvimento em pares, integração contínua, pequenas entregas, refatoração constante e padrões de codificação, de técnicas como TDD (Test Driven Development) e ATDD (Acceptance Test Driven Development), e através da automatização dos testes gerados. Ao se trabalhar com testes ágeis, (NADALETE, 2010) observa algumas mudanças de conceito em relação ao modelo tradicional, tais como:

  •     Mudanças são inevitáveis, e com base nisso toda equipe, incluindo os programadores, testadores e clientes, são responsáveis pelo resultado final;
  •          Todos da equipe devem estar acessíveis e se comunicando ativamente através do projeto;
  •          O teste de software se torna mais preventivo, ou seja, programadores testam mais cedo, com mais frequência e agressivamente. Neste ponto a prática de TDD pode e deve ser aplicada;
  •          Toda equipe solicita ativamente feedback das demais;
  •        Testadores e programadores tendem a ser mais proativos (participação direta com o cliente) e técnicos (aplicação de práticas XP e técnicas como TDD e ATDD);
  •          Testadores precisam saber automatizar, com o intuito de manter o ciclo de entregas dos testes sempre no prazo estabelecido e com teste de regressão atualizado. Só não se automatiza o que realmente não pode ser automatizado ou não vale a pena ser automatizado (e.g. Teste de Usabilidade);
  •          Os testes tonam-se uma rotina que nasce e morre junto à iteração planejada.