Abrangência dos Testes Unitários

Os testes unitários são costumeiramente escritos pelos programadores dos módulos de um sistema. Ferramentas como JUnit e NUnit auxiliam na automação desta tarefa porque fornecem métodos próprios ao desenvolvimento e execução dos testes.

Os métodos dos testes unitários devem estar implementados em uma classe à parte que acompanhe as funcionalidades programadas para aquele módulo em questão. Um exemplo seria: na arquitetura de sistemas MVC (Model-View-Controller), de model Usuario, controller UsuarioController e view cadastrarUsuario.xhtml, o módulo de cadastro de usuário conteria a classe UsuarioTest. Esta classe deve conter basicamente a validação da função principal do módulo: cadastrar a entidade usuário. Mas, para que o teste cumpra o objetivo de detectar falhas no módulo, é adequado que se valide também os caminhos alternativos à ação cadastrar usuário. Exemplos são: testar nulidade de dados obrigatórios para a entidade, duplicar cadastro de usuário, entre outros.

Por permissão da arquitetura projetada ou por opção do programador, é possível que se realize teste unitário para todas as camadas de uma arquitetura: camada de banco de dados, de modelagem, de controle, de manipulação da apresentação, de apresentação, de integração, etc. No entanto, por conta do próprio conceito de unicidade, é adequado que se analise apenas um escopo de código-fonte por vez. Esse escopo pode corresponder a um método específico ou a um pequeno conjunto deles que levem ao caminho de cadastro com sucesso ou sem sucesso. Um exemplo da primeira situação seria o método testarCadastroUsuario(), relacionado com o método de cadastro com sucesso do UsuarioController, inserirUsuario(). Um exemplo do segundo seria testarUnicidadeUsuario(), relacionado aos métodos inserirUsuario() e validarUnicidade() do UsuarioController.

O ideal é que se reserve os testes unitários para as camadas de banco de dados e controle/serviço. Isso porque este é o espaço da arquitetura que geralmente abriga a maior parte da implementação das regras de negócio, à nível de código-fonte. Evidente que, caso haja mais camadas de persistência de funções/transações e validação dos dados da entidade, elas devem participar deste conjunto.

A camada de apresentação também pode ser validada com o auxílio das ferramentas de testes unitários, a exemplo do Selenium WebDriver que se relaciona com o JUnit, NUnit entre outras. Mas é importante que se observe o objetivo do teste deixará de ser “avaliar uma função unitária” (teste unitário) para “avaliar um fluxo de atividade sobre o sistema” (teste de sistema).

O teste unitário avalia unidades de código-fonte, ele é intrinsecamente, um teste de caixa branca voltado para a análise de uma função específica do sistema. Ele se relaciona com cada método codificado para a persistência ou validação de regra de negócio. Já o teste de sistema tem foco na execução de um fluxo de sistema que conclua uma atividade. Ele pode até ser à nível de código-fonte, mas seu resultado só pode ser observado à nível usual. Ele se relaciona a uma ação sobre o sistema: clique do botão inserir, na tela do sistema; disparo da trigger de atualização da lista de usuários, no banco de dados, etc.

No final das contas, além do conceito de testes unitários os seguintes fatores irão influenciar na abrangência de aplicação deles: o nível de flexibilidade da arquitetura do software, se o projeto permite que se crie classes integradas à todas as camadas do projeto; o ritmo do projeto: qual a frequência de entrega das atividades -final do dia, semana, mês; tamanho e objetivo do projeto: o custo X benefício deve ser avaliado; entre outros.

MapServer

O MapServer é um ambiente para o desenvolvimento de sistemas para geolocalização. Ele é um pouco mais que um framework e um pouco menos que um SIG(Sistema de Informação Geográfica). Essa é uma ferramenta criada pela universidade de Minessota, EUA, em parceria com a NASA para prestar apoio ao à visualização dos serviços de localização.

O MapServer suporta diversos formatos vetoriais de imagens, que possibilitam a manipulação e análise dos mapas geográficos. Ele também suporta formatos matriciais, a exemplo do: PNG e JPEG. Através de seu uso, é possível explorar a visualização e projeção dos mapas, pela seleção de um ponto no espaço, por exemplo. As projeções dependem de abordagens complementares, como o uso de bibliotecas acopladas à ferramenta.

O MapServer disponibiliza uma interface que permite customização e expansão de suas funções à nível de código-fonte: a interface MapScript. Podem ser utilizadas as linguagens de programação PHP, Python, Java, PERL, Ruby ou C# para tanto. Seu ambiente pode ser executado em plataformas como Linux, Windows, Mac OS, FreeBSD, Solaris, entre outras plataformas  e distribuições desses sistemas operacionais.

O MapServer funciona como uma camada de intermediação entre o sistema de alto nível (o sistema que o cliente opera), o serviço presente no servidor e a base de dados, cluster, data warehouse ou outra fonte de armazenamento/coleta de informações do(s) GIS(s) relacionado(s). Um exemplo de banco de dados que se relaciona diretamente com ele é o PostGreSQL. Essa estrutura deve estar montada no ambiente local ou ambiente distribuído da aplicação. Quando uma requisição é realizada pelo cliente, ao sistema GIS, o MapServer busca na fonte de dados as informações necessárias para montar a visão requerida e “produz” a imagem no servidor do serviço. Ele funciona como um script integrado ao ambiente do servidor (CGI).

Através do MapServer, é possível buscar informações de várias fontes de dados e assim montar uma visão (imagem de mapa) consistente que represente os dados requisitados. Cada um desses dados podem estar presentes em camadas distintas (de forma genérica, uma camada é um pedaço da visão – outras pequenas imagens). Juntas, as camadas formam uma imagem completa ou mais detalhada que a anterior. O MapServer realiza esta atividade através de templates HTML. Um arquivo Mapfile guarda as informações da requisição: quais camadas buscar, qual o foco sobre o mapa, qual a projeção utilizada, entre outros, e direciona a edição dos templates HTML, os quais contém as camadas das visões. O formato dos arquivos Mapfile e templates HTML podem ser vistos no link à seguir: Link para o material introdutório.

Referências:

http://mapserver.org/

Evento de programação Ruby on Rails para meninas

O Rails Girls é um evento gratuito de tecnologia da informação voltado para a formação de meninas, estudantes/profissionais de TI ou não, em programação e na tecnologia Ruby on Rails. Ele ocorrerá pela 2ª vez em Salvador.

rails_girls

Link para o evento:

http://railsgirls.com/salvador201411

Informações:

Local: Todo o mundo | mas nesta data é a vez de Salvador, Bahia, Brasil

Data/Hora: 07 e 08 de novembro | dia 07/11 das 18 às 21hrs | dia 08/11  das 09 às 17:30.

Espaço: UFBA – Superintendência de Tecnologia da Informação – Laboratório 1 da RNP/ESR

Valor: Gratuito

Material necessário: Um notebook com permissão para instalação de software

Inscrevam-se e divirtam-se meninas! \o/

Introdução ao C++

C++ é uma linguagem multiparadigma que permite programação orientada a objetos. Ela foi criada no ano de 1983 com o intuito de expandir as funções da linguagem de programação C para aplicação no núcleo do Unix. O seu abordagem não está restrita a características de plataformas de programação de alta e baixo nível, sendo considerada uma linguagem de médio-nível. Desde sua criação ela vem sendo utilizada para o desenvolvimento de programas computacionais comerciais e particulares.

A estrutura de seus programas apresenta os seguintes elementos:

  • Cabeçalho – Espaço para a de inclusão de arquivos auxiliares (ex.: #include <iostream>) e declaração de ambiente (using namespace std) ;
    1. Variáveis podem ser declaradas no cabeçalho e portanto elas tornam-se de uso global no programaç
  •  Corpo – Espaço para a atribuição de classes, funções e instruções do programa.
    1. As variáveis declaradas no corpo do programa são locais. Elas só podem ser utilizadas no espaço onde são criadas.

Estrutura de um programa em C++

Esse link apresenta um tutorial completo para o aprendizado da linguagem, desde apresentação de tipos de variáveis às estruturas e condicionais. Os exemplos e atividades descritas no tutorial estão disponíveis neste outro link. Os programas foram desenvolvidos na IDE code::blocks, que oferece suporte à linguagem C++ e em ambiente Linux (Ubuntu).

Matriz em C++

Referências:

http://www.infoescola.com/informatica/cpp/

http://www.cplusplus.com/doc/tutorial/

Coding Dojo: uma abordagem multiutilitária

O Coding Dojo é uma técnica própria ao aprendizado e passagem de conhecimento a respeito de matérias da Computação como lógica de programação/estrutura de dados/linguagens de programação/testes de software. Se bem avaliado, é também uma abordagem social, pois ele traça uma forma de integrar o time e nivelar o  grau de conhecimento dos seus participantes.

O Coding Dojo acontece em uma reunião, onde um computador com o mínimo de configuração para programação e uma tela de projeção devem estar disponíveis para que duplas de desenvolvedores se juntem e iniciem um ciclo de testes+codificação. As duplas devem atuar na resolução de um problema/programa alvo, definido previamente para aquele dia/ocasião. Exemplos de problemas/programas alvo podem ser encontrados neste link.

Existem diversas metodologias para o desenvolvimento de Coding Dojo, sendo algumas: Kata, Randori e Kake. No entanto, a forma básica de implementar Coding Dojo segue esse esquema:

  • O computador é a ferramenta utilizada para integrar o time. Nele deve estar implantado o ambiente de desenvolvimento do programa. A tela de projeção deve apresentar todas as ações realizadas no ambiente de desenvolvimento para que o time tenha visão de todo o processo;
  • As duplas devem operar o computador e utilizar do ambiente de desenvolvimento para construir o programa. Todo o grupo: dupla atuante no computador + restante do time, pode opinar a respeito da direção e próximos passos a serem implementados no programa;
  • As duplas são formadas por: 1 integrante piloto e 1 integrante co-piloto; A dupla atual da etapa ouve as opiniões alheias, decide o próximo passo a executar para a resolução do problema e discutem a forma de implementá-lo;
  • As duplas não são fixas. Apenas a primeira delas é. No restante do tempo elas se revesam. Na etapa posterior à atual, o integrante piloto retorna para o grupo; o integrante co-piloto passa a ser piloto; e um novo integrante do grupo passa a ser o co-piloto.
  • As duplas têm um tempo fixo para implementar a tarefa atual daquela etapa do processo. Ao final do tempo cronometrado, a dupla passa por substituição e deve: 1 – dar prosseguimento à implementação da tarefa atual; ou 2 – implementar uma nova tarefa.
  • As duplas devem explicar suas ações ao restante do grupo durante a execução da tarefa ou após o seu fim;
  • A implementação do programa é executada através da metodologia TDD. Ou seja, antes que uma função do programa seja construída, o seu teste precisa ser escrito. Sendo assim, o objetivo de cada etapa do processo é fazer o testes passar. Após isso, a dupla atual da etapa decide qual será o próximo destino: refatorar o teste ou seguir para a implementação da outra função do programa.
  • A implementação do programa acaba quando todos os testes do problema/programa alvo definido passam. Neste ponto do processo o grupo decide evoluir o problema ou encerrar a reunião.

Podem existir variações desse formato descrito, como, por exemplo: (i) definir  mais de um problema/programa alvo para resolução no dia/ocasião; (ii) resolver um problema/programa alvo em mais de um dia/ocasião; (iii) dividir o time em subgrupos, para que trabalhem em tarefas paralelas ou compitam entre si \o/ ; (iv) integração de novas técnicas ao processo (ex.: BDD); (v) reunir o time em espaço virtual; (vi) integrar documentação ao processo; (vii) uso de mais de uma linguagem de programação ou ambiente de desenvolvimento (integração de novas ferramentas); entre outros. Essas são variações do processo aplicadas como formas de corresponder ao status/condição atual da equipe, da disposição e disponibilidade local da reunião, do conhecimento do grupo. Elas são responsáveis por enriquecer a experiência e intensificar a troca de conhecimento.

O problema deve ser escolhido de forma a fazer com que todas as pessoas do grupo executem os dois papéis da dupla ao menos 1 vez durante o processo de implementação do programa. Por conta disso, deve ser avaliado o tamanho dele. Deve ser observado também qual o grau de maturidade do time antes do início da reunião, para que sejam escolhidos problemas-alvo compatíveis com o tempo de experiência do assunto da maioria de seus integrantes. O nível de complexidade do problema/programa deve crescer a cada reunião realizada. A entrada de integrantes mais experientes também pode impulsionar a resolução de problemas mais complexos.

Com vistas a todas as características/regras citadas e o intuito de formação das reuniões, é possível atribuir os seguintes benefícios a ele:

  1. Desenvolvimento de raciocínio lógico – resolução dos problemas;
  2. Desenvolvimento profissional multidisciplinar – testes/codificação/instrumental (ferramentas);
  3. Desenvolvimento social – formação de networking, troca de experiências e culturas;
  4. Nivelamento de conhecimento da equipe – profissionais/estudantes de diversas áreas e níveis de conhecimento; Organização e disciplina – o ciclo segue um formato previamente estabelecido; as duplas têm um prazo para cumprir suas atividades;Tolerância e Respeito mútuo – o time deve respeitar todas as opiniões e compartilhar ideias.

Referências:

http://www.codingdojo.org/

http://dojorio.org/

http://www.devmedia.com.br/o-que-e-o-coding-dojo/30517

Uma estratégia para desenvolver/testar o seu código com eficácia

Oi galera,

Passando para deixar uma dica rápida!

Estes dias tenho focado mais no campo de programação, desenvolvendo módulos para um projeto complexo em ambiente Java. O que venho notando é que eu ganho maior eficácia sobre o que produzo seguindo os seguintes passos simples:

  1. Isolar uma função para codificar/testar;
  2. Analisar todos os requisitos que se relacionem com a função em questão;
  3. Priorizar os requisitos (para mim funciona assim: 1º lugar – ação principal (caminho feliz); 2º em diante, ações complementares (fluxos de exceção));
  4. Criar interface/estrutura primária (desenhar o botão na tela; desenvolver a consulta que irá participar da view);
    1. Teste – escrever método de teste;
  5. Fazer funcionar o requisito em evidência no momento (seguindo ordem de prioridades);
    1. Executar o teste e colher o(s) resultado(s) do teste;
  6. Ajustar comportamento e layout da função/componente;
    1. Reportar/arquivar o(s) resultado(s) do teste.
  7. Repetir os passos 3 a 6 até esgotar os requisitos da função.
  8. Executar os testes funcionais de roteiro e exploratórios sobre toda a função.
  9. Restando tempo (difícil! =] ) – refatorar código/teste.

Essa receita mescla as estratégias: dividir para conquistar e desenvolvimento iterativo/incremental. Meu objetivo é integrar esse processo com o TDD ou BDD \o/.

Esse é apenas o método que eu observei seguir para obter o resultado mais proveitoso quando codifico/testo as funções deste sistema. Ele tem me evitado muito estresse e perda de tempo como no princípio. Existem outros meios e abordagens para realizar as mesmas tarefas. Cabe a cada profissional avaliar qual a forma mais adequada de gerenciar o seu processo de desenvolvimento/testes.

Se você também possui um método para desempenhar suas atividades, compartilhe!!

Até mais! 🙂

Pesquisa por Criteria

O assunto pode não ser novidade, mas é bastante proveitoso. A interface Hibernate serve de camada de mediação entre a base de dados e o código de alto nível da aplicação. Uma das formas de consulta que o Hibernate disponibiliza, além do SQL Nativo e HQL, é o Criteria. Cada uma delas deve ser utilizada para um propósito específico.

Acredito, que, para melhor desempenho das consultas realizada pela aplicação (já mapeada, contendo objetos bem estruturados) elas devem ser escritas nesta sequência de exclusão: 1) criteria 2) hql 3) nativo. Sendo que cada qual deve ser considerada, em relação à outra, por benefícios que apresente ou até mesmo possibilidade de acesso a uma tarefa específica (ex.: em alguns casos, só ó possível realizar busca por colletions complexos com hql ou sql nativo).

Ao criar um script de consulta através do criteria, os objetos disponíveis no ambiente do projeto podem ser utilizados e reuso da consulta também é facilitado. Vejamos algumas das características que permeiam a escrita de uma operação de consulta através do Criteria:

  • Instância: Para criar um scrpit criteria é necessário utilizar as classes Criteria ou DetachedCriteria do Hibernate. A segunda opção deve ser utilizada quando se quer realizar uma operação na Sessão corrente do sistema, ou seja, sem que esteja imposta a criação de um novo atributo Session na página/módulo/tela em questão. Lembrando que, segundo documentação oficial: “a Sessão é uma fábrica para instâncias de Criteria“.

    Instância do Criteria

    criação criteria

  • Restrições de consulta: As classes Criteria disponibilizam uma série de Restrictions e desta forma é possível informar condições à consulta realizada. Exemplos são: Rectrictions.eq, que avalia a igualdade do valor de um atributo com um resultado esperado; Restrictions.ilike, utilizado para comparar partículas de um valor texto, ex.: String contendo nome de uma pessoa; Restrictions.in, que avalia um conjunto de valores; e assim por diante.

    Restrições

    Restrições do Criteria

  • Ordenação: A ordenação crescente ou decrescente pode ser conseguida a partir do comando addOrder. O nome da propriedade pode ser passado diretamente ou através de um Property.

    Ordenação

    Ordenação por elemento Property

  • Associações: A relação entre as tabelas também pode ser especificada em uma consulta por Criteria. Isso pode ser alcançada através das Restrictions, ou, mais claramente, pelo comando explicíto de Junção, o createAlias. Esse comando possibilita a criação das junções de Inner, Left, Right e Full Join.

    Junção por creatAlias

    Junção por creatAlias

A consulta por Criteria aumenta a produtividade do desenvolvedor, por tornar a consulta mais fácil, legível e objetiva para ele. Assim como torna a consulta mais segura, pois o código já não manipula uma String Sql. A ação de utilizar consulta por Criteria também retira do desenvolvedor/arquiteto/projetista a responsabilidade de conhecer todos comandos SQL e particularidades que cada base dados apresenta (comandos específicos), delegando ao Hibernate a tarefa de criar a query nativa a partir da manipulação dos objetos vigentes no projeto. Desta forma, depois de mapeadas as tabelas da base no projeto, já não é necessário recorrer à estrutura interna da base de dados para nomear cada variável ou realizar associações entre elas.

Os conceitos apresentados neste post  são apenas mecanismos básicos da consulta por Criteria. Se explorado, esse tema pode apresentar um mundo à parte.

Referências:

http://docs.jboss.org/hibernate/orm/3.5/reference/pt-BR/html/querycriteria.html

http://www.devmedia.com.br/hibernate-api-criteria-realizando-consultas/29627

https://www.ibm.com/developerworks/community/blogs/fd26864d-cb41-49cf-b719-d89c6b072893/entry/criteria_hibernate_na_pr_C3_A1tica?lang=en

PMD, FindBugs e CheckStyle

As ferramentas PMD, FindBugs e CheckStyle vêm sendo largamente utilizadas por programadores em ambientes de codificação automatizados como suporte ao controle de código-fonte. Elas analisam estaticamente o código para prover informações a respeito de pontos de risco e pontos de melhoria que ele possua.

A prática de inspeção/auditoria/revisão de código-fonte auxilia na: 1) organização; 2) clareza; 3) facilidade de reuso e manutenção; 4)  consistência, entre outros aspectos, do software em desenvolvimento. Ambas as técnicas, PMD, FindBugs e CheckStyle podem ser combinadas para obter maior cobertura do código na inspeção. No entanto, é importante saber diferenciar a função de cada uma delas para julgar qual(is) dela(s) seja(m) a(s) mais adequada(s) ao escopo do projeto. São atividades desempenhadas por elas:

  • PMD = Analisa o código-fonte à procura de problemas potenciais (bugs e warnings), código não utilizado, código de baixa qualidade, expressões complicadas ou ilegíveis e duplicidade de código. Exemplos:
    1. variáveis e importações não utilizadas;
    2. expressões muito longas;
    3. uso do método equals() ao invés do sinal ‘==’;
    4. laços e declarações desnecessários.
  • FindBugs = Possui função similar ao PMD, no entanto, ele trabalha sobre bytecode, ao invés do código-fonte. Exemplos:
    1. uso inadequado dos métodos .equals() e .hashCode();
    2. casts inseguros/impróprios;
    3. nulidade de variáveis;
    4. possíveis estouros de memória;
    5. possíveis exceções ignoradas.
  • CheckStyle = Analisa o estilo e convenções do código-fonte. Não analisa erros e possibilidade de erros no código, como o PMD e FindBugs, mas verifica a conformidade dele em relação aos padrões estabelecidos (documentação, comentários, sintaxe). Exemplos:
    1.  JavaDoc ausente/impróprio;
    2. espaços em branco;
    3. ausência de chaves e parênteses nas variáveis e condições;
    4. extensão da expressão;
    5. outras convenções a respeito de nomenclatura. 

Tutorial a respeito do plug-in CheckStyle para a IDE Eclipse: http://www.vogella.com/tutorials/Checkstyle/article.html

Referências:
https://www.sparkred.com/blog/open-source-java-static-code-analyzers/

http://tirthalpatel.blogspot.com.br/2014/01/static-code-analyzers-checkstyle-pmd-findbugs.html

http://www.sw-engineering-candies.com/blog-1/comparison-of-findbugs-pmd-and-checkstyle

Transformando XML com XSLT

XSLT (eXtensible Stylesheet Language for Transformation) é uma linguagem de marcação criada pela W3C para  manipular arquivos XML. Ela faz parte da especificação XSL junto com mais duas linguagens: XSL-FO e XPath. As informações inseridas no arquivo XSL, com a linguagem XSLT, definem um formato de apresentação para o(s) arquivo(s) XML relacionado(s). Essa tecnologia pode ser utilizada, por exemplo, para formatar, de forma direta, os dados dos arquivos XML utilizados na geração de arquivos  HTML, PDF, etc.

xsltPara conseguir formatar um arquivo XML com XSLT é necessário: 1) escrever um arquivo de extensão xsl e 2) associar o template criado a um arquivo xml. O arquivo XSL deve conter as anotações XSLT e assim atuar como uma folha de estilo para os arquivos XML.

Pode-se comparar a relação xls/xslt/xml à relação css/html, sendo que o uso das anotações XSLT permite, além de acrescentar, esconder informações do arquivo XML. A interação do XSLT sobre os arquivos XML não modifica o conteúdo presente nos arquivos XML e por isso é possível obter a sua estrutura original na saída do processo de transformação xsl/xslt/xml.

Essas são algumas das tags XSLT que são utilizadas no arquivo XSL para formatar os arquivos XML:

  • <xsl:value-of> = extrai o valor de um elemento XML;
  • <xsl:for-each> = seleciona todos os elementos XML de um nó específico do arquivo XML;
  • <xsl:sort> = ordena a saída do for-each;
  • <xsl:if> = descreve uma condição;
  • <xsl:choose> <xsl:when> <xsl:otherwise> = descreve múltiplas condições;
  • <xsl:apply-templates> = aplica um estilo a um elemento a um nó de elementos XML;

Ainda, é preciso adicionar uma das seguintes tags <xsl:stylesheet> ou <xsl:transform>  para declarar um arquivo XSL em um arquivo XML. Veja o seguinte tutorial da W3Schools (http://www.w3schools.com/xsl/xsl_transformation.asp) para transformar arquivos XML com  anotações XSLT.

Referências:
http://www.w3.org/TR/xslt
http://www.w3schools.com/xsl/
http://pt.wikipedia.org/wiki/XSLT

 

Diferença entre TDD e BDD

TDD e BDD são metodologias de desenvolvimento ágil. No TDD (Test Driven Development) o desenvolvimento deve ser guiado a testes, onde um teste unitário deve ser escrito antes que uma funcionalidade do sistema o seja. O objetivo, então, é fazer com que o teste passe com sucesso, significando que assim a funcionalidade está pronta e conta com garantia de qualidade.

No BDD (Behaviour Driven Development) o desenvolvimento deve ser guiado aos comportamentos que o sistema deve apresentar. Desta forma, um comportamento (requisito/especificação) é priorizado em relação ao teste unitário, o que não exclui a execução do fluxo do TDD neste processo. A figura abaixo apresenta o fluxo do TDD e BDD:

tdd_bdd

Existem algumas ferramentas que oferecem apoio à adoção de uma metodologia ou outra ao processo de codificação do sistemas, das quais RSpec(http://rspec.info/)  e Cucumber(http://cukes.info/) são exemplos. Em resumo elas permitem: 1) escrever uma especificação em uma “pseudo linguagem”; 2) transformar a especificação em uma função de teste. Isso porque esses frameworks implementam o TDD para guiar a realização do BDD.

Assim como o TDD e BDD, existem outras metodologias de desenvolvimento ágil que pode ser aplicadas à etapa de codificação do software (DDD, FDD, ATDD, etc). Cada uma delas evidencia uma etapa do ciclo de vida do processo de desenvolvimento do software ou um artefato que faça parte dele como forma de guiar a construção do sistema. Para saber qual deles utilizar é necessário realizar uma análise sobre o projeto, time e outros recursos envolvidos ao processo.

 

Referências:
http://sobrecodigo.com/comparacao-entre-tdd-e-bdd-como-aprender-um-me-ajudou-com-o-outro/
http://caironoleto.com/2008/06/11/diferenca-entre-tdd-e-bdd/
http://blog.fasagri.com.br/?p=113