Como um importante complemento, as técnicas de Test-Driven Development e Behavior-Driven Development serão empregadas na construção dos testes unitários e de aceitação, respectivamente.
A adoção de testes permite identificar problemas assim que os mesmos são inseridos no código e é mais um importante elemento para se alcançar um design mais enxuto, principalmente quando optamos pelo TDD e pela automatização.
No artigo “Dominando os tipos de testes automatizados”, publicado na Java Magazine 146, os conceitos relacionados a testes automatizados foram apresentados, considerando em especial os testes unitários, de integração e de aceitação.
Além dessa análise, foram exploradas também as relações de testes automatizados com código legado e com times ágeis, bem como o uso de práticas como Test-Driven Development e Behavior-Driven Development. Contudo, o artigo não apresentou exemplos reais de como os conceitos poderiam ser aplicados.
Deste modo, neste artigo abordaremos como utilizar os conceitos previamente estudados em código Java, por meio da construção de um projeto exemplo.
O intuito é demonstrar como testes unitários, de integração e de aceitação podem ser implementados, tendo como base suas características essenciais: teste unitário como um validador de implementação em termos de objetos sem dependências externas; teste de integração como validador de implementações que se relacionam com recursos (tais como banco de dados); e testes de aceitação como um validador de funcionalidades do cliente (descritas por meio da técnica de User Stories).
Exemplificando com Java
A partir de agora será criado um pequeno sistema para demonstração dos diferentes tipos de testes que foram analisados. Para isso, o sistema deve possuir alguma lógica a ser validada (para testes unitários), persistência em banco de dados (para testes de integração) e User Stories (para testes de aceitação).
Como os testes de aceitação estão vinculados apenas à camada de domínio (back-end da aplicação), não será necessária a criação de telas, da camada de visão.
Estrutura inicial da aplicação
A estrutura da aplicação começará com elementos básicos, e conforme a implementação for evoluindo, novas funcionalidades serão adicionadas. Para o gerenciamento de pacotes e realização de builds, adotaremos o Gradle. Sendo assim, é necessário tê-lo instalado em seu ambiente. Na seção Links você encontrará o endereço para download da última versão.
A Listagem 1 apresenta uma lista de comandos para criação de um projeto para os usuários da IDE IntelliJ. Estes comandos definem a estrutura de diretórios do projeto, adicionam o plugin idea ao arquivo principal do Gradle, build.gradle, e então executam o Gradle, que por consequência executa o plugin, o que gera os arquivos de projeto necessários à importação pela IDE. Caso utilize o Eclipse, o comando da Listagem 2 deve ser utilizado, de forma análoga. Por sua vez, caso deseje criar a estrutura do projeto independentemente da IDE, execute o comando da Listagem 3.
Listagem 1. Criação da estrutura do projeto para IntelliJ.
01 mkdir -p numerolog/src/main/java/br/com/devmedia numerolog/src/main/resources
02 numerolog/src/test/java/br/com/devmedia numerolog/src/test/resources
03 && printf “apply plugin:'java'\napply plugin:'idea'”
04 > numerolog/build.gradle && cd numerolog && gradle idea
Listagem 2. Criação da estrutura do projeto para Eclipse.
01 mkdir -p numerolog/src/main/java/br/com/devmedia numerolog/src/main/resources
02 numerolog/src/test/java/br/com/devmedia numerolog/src/test/resources
03 && printf “apply plugin:'java'\napply plugin:'eclipse'”
04 > numerolog/build.gradle && cd numerolog && gradle eclipse
Listagem 3. Criação da estrutura do projeto, independente de IDE.
01 mkdir -p numerolog/src/main/java/br/com/devmedia numerolog/src/main/resources
02 numerolog/src/test/java/br/com/devmedia numerolog/src/test/resources
03 && touch numerolog/build.gradle
Feito isso, a estrutura do projeto será criada contendo os diretórios para o código de produção e código de testes, bem como o arquivo de configuração do Gradle.
Nas Listagens 1 e 2, o plugin da IDE é adicionado ao build.gradle, e o comando gradle <nome da IDE> cria os arquivos de configuração para que as IDEs possam importar o projeto corretamente. Na Listagem 3, o arquivo build.gradle também é criado, mas, como esperado, sem especificar um plugin para qualquer IDE.
Importe o projeto em sua IDE (se tiver escolhido executar os comandos da Listagem 1 ou da Listagem 2) e edite o arquivo build.gradle para adicionar mais detalhes de configuração ao projeto, conforme o conteúdo apresentado na Listagem 4.
Listagem 4. Conteúdo do arquivo build.gradle.
01 apply plugin:'java'
02 apply plugin:'idea'
03
04 sourceCompatibility = 1.8
05 targetCompatibility = 1.8
06
07 repositories {
08 mavenCentral()
09 }
As primeiras linhas definem os plugins do Java e da IDE escolhida para uso. Já nas linhas 4 e 5, é especificada a versão do Java a ser adotada no projeto (neste caso, o Java 8). E as linhas de 7 a 9 declaram que o repositório central do Maven será utilizado como o repositório de dependências do projeto.
Definição do problema e das User Stories
Um requisito simples que foi escolhido para trabalharmos em nosso projeto exemplo é o da redução de letras
e datas a algarismos decimais, de 0 a 9, por somas e divisões sucessivas. O sistema aqui proposto deve realizar o cálculo numerológico dos dados do usuário, como nome e data de nascimento. Para implementarmos este requisito, codificaremos um algoritmo para representação do nome e da data de nascimento de usuários em números, a ser testado com testes unitários.
Para isso, o usuário será representado pela entidade Usuario e as ações do CRUD relacionado serão implementadas de forma que sejam verificadas com testes de integração. Por fim, utilizaremos User Stories (ou histórias de usuário, conforme conceitualizadas no outro artigo sobre testes) para escrever os testes de aceitação deste cálculo.
Começaremos definindo algumas User Stories relacionadas ao cálculo numerológico, sendo uma para o cálculo do nome e outra para o c ...