Fixture-Factory. Criando objetos para seus testes. Como criar objetos através de templates para serem utilizados como massa de dados em seus testes.



Documentos relacionados
Orientação a Objetos

Orientação a Objetos

Sistema de Controle de Solicitação de Desenvolvimento

Análise e Desenvolvimento de Sistemas ADS Programação Orientada a Obejeto POO 3º Semestre AULA 03 - INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETO (POO)

Manual de utilização do sistema OTRS (Atendimento) Cliente Externo

TESTES AUTOMATIZADOS COM JUNITE MOCKITO

Gerenciamento de Projetos

Introdução a Java. Hélder Nunes

Manual Operacional SIGA

Parte I. Demoiselle Mail

Sistema de Digitalização e Gerenciamento de Arquivos On-Line

TOTVS BA Guia de Customização Linha Logix

IP significa Internet Protocol. A Internet é uma rede, e assim como ocorre em qualquer tipo de rede, os seus nós (computadores, impressoras, etc.

USANDO O IZCODE PARA GERAR SOFTWARE RAPIDAMENTE

Gerenciamento de Contatos

Implementando uma Classe e Criando Objetos a partir dela

ISO/IEC 12207: Gerência de Configuração

Engenharia de Software III

Padrões de Projeto. Singleton

Linguagem de Programação III

Despachante Express - Software para o despachante documentalista veicular DESPACHANTE EXPRESS MANUAL DO USUÁRIO VERSÃO 1.1

Manual Administrador - Mídia System

Manual do Visualizador NF e KEY BEST

Construtor de sites SoftPixel GUIA RÁPIDO - 1 -

Manual do Atendente. Treinamento OTRS Help Desk

Criar alertas de suprimentos e serviço

Controle de Estoque. Configuração e personalização do módulo

Criando & Consumindo um WebService com ASP.NET 2.0 Publicado em: 25 de Agosto de 2007 Por Herman Ferdinando Arais

tarefa 1. Para criar uma Tarefa clique em Ativar edição.

QUALIDATA Soluções em Informática. Módulo CIEE com convênio empresas

Manual do Sistema "Vida Controle de Contatos" Editorial Brazil Informatica

O Excel é um programa de computador desenvolvido para gerenciar dados na forma de planilhas.

Esta dissertação apresentou duas abordagens para integração entre a linguagem Lua e o Common Language Runtime. O objetivo principal da integração foi

gerenciamento de portais e websites corporativos interface simples e amigável, ágil e funcional não dependendo mais de um profissional especializado

PROGRAMANDO EM C# ORIENTADO A OBJETOS

Entendendo como funciona o NAT

PAINEL GERENCIADOR DE S

Casos de teste semânticos. Casos de teste valorados. Determinar resultados esperados. Gerar script de teste automatizado.

Data Transformation Services (DTS) por Anderson Ferreira Souza

Plugins TerraView. Última revisão: 12/12/32006 Versão TerraLib: 3.1.4

Especificação do 3º Trabalho

Prevayler. Perola. André Luís Sales de Moraes Juliana Keiko Yamaguchi Tatiana Yuka Takaki

1. Apresentação Objetivos

Programação de Computadores - I. Profª Beatriz Profº Israel

Java Mail Server. Manual do Utilizador


Manual do Painel Administrativo

SISTEMA DE WORKFLOW PARA MODELAGEM E EXECUÇÃO DE PROCESSOS DE SOFTWARE. Aluno: Roberto Reinert Orientador: Everaldo A. Grahl

Trecho retirando do Manual do esocial Versão 1.1

Sistemas Operacionais

4 O Workflow e a Máquina de Regras

Planejando o aplicativo

Manual de Utilização do Zimbra

Evolução do Design através de Testes e o TDD

Vamos criar uma nova Página chamada Serviços. Clique em Adicionar Nova.

Acessando um Banco de Dados

A máscara de sub-rede pode ser usada para dividir uma rede existente em "sub-redes". Isso pode ser feito para:

Análise de Dados do Financeiro

Portal Sindical. Manual Operacional Empresas/Escritórios

PROGRAMAÇÃO ORIENTADA A OBJETOS -TRATAMENTO DE EXCEÇÕES. Prof. Angelo Augusto Frozza, M.Sc. frozza@ifc-camboriu.edu.br

IW10. Rev.: 02. Especificações Técnicas

NeXT Help Desk Manual do usuário. Abril/2011. NeXT Software

Projeto de Software Orientado a Objeto

3 Dicas MATADORAS Para Escrever s Que VENDEM Imóveis

SISTEMA DE GERENCIAMENTO DE PROJETOS - REDMINE MANUAL DE USO

ROTEIRO PARA TREINAMENTO DO SAGRES DIÁRIO Guia do Docente

Prototype, um Design Patterns de Criação

Como ganhar dinheiro recomendando cursos.

Processos Técnicos - Aulas 4 e 5

Comunidade de Suporte e Feedback

APLICATIVO WEB PARA O SETOR DE EXTENSÃO IFC VIDEIRA

NetBeans. Conhecendo um pouco da IDE

Tutorial Sistema de Eventos de Certificação e Capacitação

VVS Sistemas (21)

Manual de Operação do Sistema de Tickets Support Suite

TUTORIAL DO ALUNO. Olá, bem vindo à plataforma de cursos a distância da Uniapae!!!

Algoritmos e Estruturas de Dados II. Trabalho Prático 2

FERRAMENTAS DE COLABORAÇÃO CORPORATIVA

MANUAL DO USUÁRIO SORE Sistema Online de Reservas de Equipamento. Toledo PR. Versão Atualização 26/01/2009 Depto de TI - FASUL Página 1

Manual Portal Ambipar

3 Um Framework Orientado a Aspectos para Monitoramento e Análise de Processos de Negócio

UML Aspectos de projetos em Diagramas de classes

Manual do Ambiente Moodle para Professores

5 Mecanismo de seleção de componentes

SISTEMAS DE GESTÃO São Paulo, Janeiro de 2005

Guia Prático. PGRural. Adendo Livro Caixa Avançado

PHP: Formulários e upload de múltiplos arquivos Por Alfred Reinold Baudisch 28 de fevereiro de 2006.

Desenvolvendo Websites com PHP

Passo 1: Abra seu navegador e digite Passo 2: Na tela que surgir, clique em Get Started.

Entrar neste site/arquivo e estudar esse aplicativo Prof. Ricardo César de Carvalho

Sistema LigaMagic de Torneios

CONFIGURAÇÃO DE WORKFLOW

Manual de utilização do sistema de envio de sms marketing e corporativo da AGENCIA GLOBO. V

PHC XL CS. Reporting Financeiro em Microsoft Excel. O que ganha com este software:

Análise e Projeto de Sistemas

Pag: 1/20. SGI Manual. Controle de Padrões

Configurar o Furbot no Eclipse

O CONCEITO DE TDD NO DESENVOLVIMENTO DE SOFTWARE

Transcrição:

fixture-factory_ Fixture-Factory Criando objetos para seus testes Como criar objetos através de templates para serem utilizados como massa de dados em seus testes. Começamos testando métodos simples, mas e quando dependemos de objetos com determinados valores para realizar o teste, como fazer? O Fixture-Factory é um framework que surgiu para auxiliar na criação e manutenção de objetos utilizados nos testes, tudo isto de uma maneira simples e intuitiva através da declaraçāo de templates. Já faz algum tempo que a comunidade de desenvolvimento de software discute a necessidade de garantir a qualidade do que está sendo desenvolvido. Em busca disto surgiram algumas soluções como o uso de testes automatizados e TDD. Aplicar estes conceitos pode parecer um pouco complicado no início e uma das maiores dificuldades encontradas é de como criar os dados necessários para realizar os testes. Uma das soluções mais utilizadas é o uso de Fixtures. Neste artigo apresentaremos uma solução alternativa/complementar às Fixtures, que é o Fixture- -Factory um framework que auxiliar na criação dos dados necessários quando e onde precisamos. Tudo isto através uma maneira programática, feito de programadores para programadores. Fixtures As Fixtures são utilizadas para especificar os dados que serão criados. Para realizar essa especificação podem ser utilizados arquivos xml, json, yaml etc. Além de criar estes arquivos que dizem quais valores os objetos criados terão é necessário realizar algumas configurações para que tudo funcione (acesso a base de dados, por exemplo). Após configurado, é possível utilizar esses dados para mockar resultados de métodos, consultas a base de dados, consultas webservices etc. O grande problema das Fixtures é que elas acabam tornando-se difíceis de manter em longo prazo. Com o passar do tempo, a tendência é termos diversos arquivos de Fixtures e em alguns casos até arquivos grandes demais, que causam grande dificuldade / 26

Nykolas Laurentino de Lima nykolas.lima@gmail.com É programador na Amil, trabalha com Java há mais de 4 anos. Certificado SCJP e SCWCD. na manutenção. Além disso, os dados configurados nas Fixtures são em sua grande maioria hard-coded, o que muitas vezes leva o programador a escrever testes baseados nesses dados específicos. O problema de testar baseado em dados fixos é que quando os dados mudarem, quando a aplicação for para produção, por exemplo, o código pode não funcionar. Exemplo de fixture usando YAML: valid_student: id: 1 nome: Nykolas Laurentino de Lima email: nykolas.lima@gmail.com datanascimento: 02/06/1991 mediafinal: 7 Fixture-Factory O Fixture-Factory é um framework que foi criado para facilitar a criação de objetos para serem utilizados nos testes. Diferente das Fixtures, não é necessária nenhuma configuração adicional. Só é necessário descrever quais valores queremos que nossos objetos tenham e pronto. Além de não precisar de nenhuma configuração adicional, a definição dos valores que serão utilizados nos nossos objetos é feita programaticamente, ou seja, utilizando código Java. Sem arquivos XML, YAML, JSON ou qualquer outro tipo. O framework funciona de maneira similar ao Factory-Girl utilizado na criação de testes em Ruby. Template Para definirmos os valores que nossos objetos gerados terão é necessário escrevermos um template para eles. O template irá definir quais valores serão gerados para cada propriedade do nosso objeto, mas, diferentemente das Fixtures, os templates podem definir diversos valores possíveis para a mesma propriedade. Podemos gerar valores aleatórios baseados em uma lista de valores possíveis, por meio de expressões regulares, períodos de data etc. Uma das grandes vantagens na utilização de Templates e não de Fixtures estáticas é que criamos objetos que possuem valores que variam constantemente, a cada execução do mesmo teste o objeto utilizado por ele pode ter valores diferentes. Desta maneira nossos testes tendem a ser menos atrelados a dados específicos e mais direcionados a padrões de dados que nós definimos como válidos. Um exemplo muito comum de testes criados baseados em dados é quando dependemos de um período de data. Com o uso de Templates podemos definir que o valor de determinado atributo deve ser de 6 meses atrás, isto pode ser feito de uma maneira simples e fácil, o que com o uso Fixtures poderia demandar uma quantidade considerável de refactoring e mocks. Criando o Template A criação do template é bem simples, dizemos para qual classe desejamos criar o template, qual o nome dele e então configuramos os valores para as propriedades da classe. Vale lembrar que uma mesma classe pode ter diversos templates diferentes. Listagem 1. A Listagem 1 exemplifica a codificação de um template para a classe Client. add( id, 1L); add( name, Nykolas Laurentino de Lima ); add( nickname, geek ); add( email, ${nickname@gmail.com ); add( birthday, new Date()); ).addtemplate( nerdclient, add( id, 2L); add( name, Anderson Parra ); add( nickname, nerd ); add( email, ${nickname@gmail.com ); add( birthday, new Date()); 27 \

Na Listagem 1 nós criamos dois templates para a classe Client, um deles se chama geekclient e o outro nerdclient. Note que podemos utilizar placeholders para criar valores de uma propriedade a partir de outra propriedade, como foi feito na propriedade e-mail. Mais abaixo será explicado o uso de funções para gerar valores dinamicamente na criação do objeto. Para obter uma instância do template criado só precisamos informar a classe desejada e o nome do template: Listagem 2. A Listagem 2 exemplifica a codificação para obter uma instância da classe Client através do template geekclient. Fixture.from(Client.class).gimme( geekclient ); Um exemplo do objeto gerado para o template geekclient pode ser visto na figura 1. Figura 1. Exemplo de objeto gerado para o template geekclient. Relacionamentos Tratar os relacionamentos entre os objetos também pode ser feito de maneira simples e fácil através das RelationFunctions. Listagem 3. A Listagem 3 exemplifica a codificação das Relation Functions one e has. Fixture.of(Address.class).addTemplate( brazilianaddress, add( id, 1L); add( street, Paulista Avenue ); add( city, São Paulo ); add( state, SP ); add( country, Brazil ); add( zipcode, 0660800 ); Fixture.of(Phone.class).addTemplate( brazilianphonenumber, add( number, 11 9999-9999 ); add( address, one(address.class, brazilianaddress )); add( phones, has(3).of(phone.class, brazilianphonenumber )); A função one irá criar uma instância da classe Address utilizando o template brazilianaddress que foi criado logo acima. A propriedade phones é uma lista de telefones, portanto utilizamos a função has e dizemos para ela quantas instâncias nós queremos, de qual classe e qual template será utilizado. Agora ao obtermos uma instância do template geekclient, automaticamente serão criados os relacionamentos com Address e Phone utilizando os templates declarados. Um exemplo dos relacionamentos criados pode ser visto na figura 2. Functions As Functions são utilizadas para gerar valores dinâmicos para as propriedades de um objeto. As RelationFunctions explicadas na seção anterior exemplificam a geração de objetos para os relacionamentos, mas existem outras funções para auxiliar na criação de valores simples. Random A função random é utilizada para escolher um valor aleatoriamente dentre uma lista de possíveis valores. Figura 2. Exemplo de objeto gerado utilizando as funções de relacionamento one e has. / 28

Listagem 4. A Listagem 4 exemplifica a codificação da função random para geração de valores aleatórios. add( name, random( Nykolas Laurentino de Lima, Anderson Parra )); Ao obter uma instância do template geekclient a propriedade name terá seu valor gerado aleatoriamente conforme configurado. Regex A função regex pode ser utilizada para gerar valores baseados em uma expressão regex. Listagem 5. Utilizando expressões regulares para gerar o valor da propriedade. Fixture.of(Phone.class). addtemplate( brazilianphonenumber, add( number, regex( (\\d{2) (\\d{4) - (\\d{4) )); new SimpleDateFormat( yyyy-mm-dd ))); add( contractendingdate, afterdate( 2011-04-15 ), new SimpleDateFormat( yyyy-mm-dd )); add( lastlogindate, instant( now )); Name As funções name auxiliam na criação de nomes aleatórios. Listagem 7. Utilizando as funções de nomes para gerar nomes aleatórios. new Rule(){{ add( name, firstname()); add( lastname, lastname()); Um exemplo dos valores gerados pelas funções name e lastname pode ser visto na figura 4. Um exemplo do resultado da função regex pode ser visto na figura 3. Figura 4. Exemplo de valores gerados através das funções name e lastname. Figura 3. Exemplo de valor gerado através da função regex. Date Para tratamento de datas podemos utilizar as funções beforedate, afterdate, randomdate e instant. Estas funções facilitam a manipulação de datas através de uma interface simples e intuitiva. Listagem 6. Utilizando as funções de datas para gerar o valor das propriedades. add( birthday, randomdate( 1980-04-15, 1985-11-07, new SimpleDateFormat( yyyy-mm-dd ))); add( contractbegginingdate, beforedate( 2011-04-15, Refatorando nossos templates Podemos agora refatorar os templates para Client, Address e Phone para utilizarem as functions. Deste modo os valores serão gerados dinamicamente no momento em que nossos objetos forem utilizados nos testes. Listagem 8.Template para Client refatorado. Fixture.of(Client.class).addTemplate( geekandnerdclient, add( id, random(long.class, range(1l, 200L))); add( name, random( Nykolas Laurentino de Lima, Anderson Parra )); add( lastname, lastname()); add( nickname, random( nerd, geek )); add( email, ${nickname@gmail.com ); add( birthday, instant( 18 years ago )); add( address, one(address.class, brazilianaddress )); 29 \

add( phones, has(3).of(phone.class, brazilianphonenumber )); // Client Listagem 9. Template para Address refatorado. Fixture.of(Address.class).addTemplate( brazilianaddress, add( id, random(long.class, range(1l, 100L))); add( street, random( Paulista Avenue, Ibirapuera avenue )); add( city, São Paulo ); add( state, SP ); add( country, Brazil ); add( zipcode, random( 0660800, 17720000 )); Listagem 10. Template para Phone refatorado. Fixture.of(Phone.class). addtemplate( brazilianphonenumber, add( number, regex( (\\d{2) \\d{4-\\d{4 )); Após o refactoring é possível notar a melhora no código, na definição dos valores que serão gerados e o ganho que isto traz na abrangência e diversidade de dados que serão testados. Organizando seus templates É possível criar os templates em qualquer lugar. No @Before de uma classe de testes ou até mesmo dentro do próprio método que realiza o teste. Entretanto, uma boa prática para a organização dos templates é a criação de classes separadas para declarar os templates de cada módulo do seu sistema. Nos meus projetos pessoais eu costumo criar uma classe TemplateLoader que contém uma inner class para cada entidade ou módulo do meu sistema. Listagem 11. Exemplo de TemplateLoader responsável pela criação dos templates. public class TemplateLoader { public static void loadtemplates() { TemplateLoader.ClientTemplate.loadTemplates(); private static class ClientTemplate { public static void loadtemplates() { //Declaração dos outros templates relacionados a Após criar o TemplateLoader é possível chamar o método TemplateLoader.loadTemplates para carregar todos os templates ou carregar somente os templates desejados através do método TemplateLoader. ClientTemplate.loadTemplates(). Considerações finais O Fixture-Factory oferece uma DSL (domain- -specific language) simples e intuitiva para criação de objetos para nossos testes. Com o uso das Relation Functions, configurar os relacionamentos entre as entidades torna-se uma tarefa fácil. Para relacionamentos one-to-one basta utilizar a função one dizendo a classe e o nome do template a ser utilizado. Para relacionamentos one- -to-many a função has recebe a classe, a quantidade de instâncias desejadas e o nome do template a ser utilizado. Comparado com as Fixtures, o Fixture-Factory possui a vantagem de sua utilização e configuração ser feita 100% com código Java, não precisando de arquivos XML ou JSON. Com isto a leitura, debug, identificação de erros e refactoring são muito melhores (caso você erre algo na sintaxe, o compilador vai te avisar). Quando utilizamos fixtures ou criamos nossos objetos na mão no momento do teste, estes objetos possuem sempre os mesmos valores fixos que foram configurados. Isto pode influenciar o programador a escrever testes baseados nesses dados hard-coded, o que pode acabar escondendo problemas na implementação do código que poderiam ser identificados no momento do teste caso os valores fossem gerados através de padrões configurados no Template do Fixture-Factory. Este é um exemplo claro da vantagem do uso de Templates e das Functions do framework para geração dos objetos. /referências > DO repositório do Fixture-Factory no github é: https:// github.com/aparra/fixture-factory > Dúvidas, sugestões ou qualquer outro assunto relacionado ao framework podem ser enviadas para a lista Mailing List(https://groups.google.com/ forum/?fromgroups#!forum/fixture-factory). > Fontes utilizados no artigo: https://github.com/ nykolaslima/fixture-factory-mundoj > Factory-Girl, solução parecida utilizada em Ruby: https://github.com/thoughtbot/factory_girl / 30