Você está na página 1de 67

UNIVERSIDADE VEIGA DE ALMEIDA

BACHARELADO EM SISTEMAS DE INFORMAO

INTRODUO A TESTES AUTOMATIZADOS EM RUBY ON RAILS

Thiago Cifani Ayres Escola

Cabo Frio 2011

THIAGO CIFANI AYRES ESCOLA

INTRODUO A TESTES AUTOMATIZADOS EM RUBY ON RAILS

Trabalho desenvolvido durante a disciplina Monografia e apresentada ao Curso de Sistemas de Informao da Universidade Veiga de Almeida, campus Cabo Frio, como prrequisito para a obteno do ttulo de Bacharel em Sistemas de Informao.

Orientador: Prof. Matheus Bousquet Bandini, M.Sc.

Campus Cabo Frio 2011

Universidade Veiga de Almeida - UVA Faculdade de Informtica Curso de Bacharelado em Sistemas de Informao

Reitor: Prof. Dr. Mrio Veiga de Almeida Jr. Vice-Reitor: Prof. Tarqunio Prisco Lemos da Silva Coordenador do Curso de Informtica: Prof. Edgar

Banca Examinadora:

__________________________________ Prof. Matheus Bousquet Bandini (Orientador) M.Sc. em Sistemas e Computao IME/RJ

__________________________________ Prof. Douglas Ericson Marcelino de Oliveira M.Sc. em Sistemas e Computao IME/RJ

__________________________________ Prof. Rodrigo Lessa de Sena Especialista em Computao Grfica - UVA

Universidade Veiga de Almeida Cabo Frio Estrada das Perynas, s/n CEP: 28901-970 - Cabo Frio RJ

Dedico este trabalho a Arnaldo, Rose, Priscilla e Elaine.

AGRADECIMENTOS
Agradeo a meus pais, famlia, amigos e professores. Agradeo todas estas pessoas que se fizeram presentes e ocuparam com excelncia o devido papel em minha vida. Agradeo pelo carinho, respeito, dedicao e incentivo para continuar mesmo com todos os atenuantes da vida.

LISTA DE FIGURAS
Figura 3.1 Modelo MVC Rails ............................................................................................. 23 Figura 3.2 Cdigo Rails para Localizar Cliente por ID ........................................................ 24 Figura 3.3 Exemplo de uso do Active Record ...................................................................... 25 Figura 4.1 Exemplo de Estrutura de Teste Unitrio.............................................................. 29 Figura 4.2 Teste Unitrio com Assero ............................................................................... 29 Figura 4.3 Teste Unitrio com Assert Equals ....................................................................... 30 Figura 4.4 Teste Unitrio com Assert Not Equal .................................................................. 30 Figura 4.5 Exemplo de Repetio de Cdigo em Teste Unitrio.......................................... 31 Figura 4.6 Exemplo de Mtodo Setup .................................................................................. 32 Figura 4.7 Ciclo do TDD ...................................................................................................... 36 Figura 4.8 Exemplo de Describe com RSpec ....................................................................... 39 Figura 4.9 Exemplo de Describe com Context e IT.............................................................. 39 Figura 4.10 Exemplo de Sada Formatada do RSpec............................................................... 39 Figura 4.11 Exemplo de Teste RSpec Pendente ................................................................... 40 Figura 4.12 Sada RSpec Teste Pendente.............................................................................. 40 Figura 4.13 Teste RSpec pendente com mensagem personalizada ....................................... 41 Figura 4.14 Teste RSpec com It para descrever comportamento ......................................... 41 Figura 4.15 Teste RSpec Let e Specify ................................................................................. 42 Figura 4.16 Teste Exemplo cenrio com cucumber .............................................................. 43 Figura 5.1 GemFile para Testes ............................................................................................ 47 Figura 5.2 Comandos Instalao ........................................................................................... 48 Figura 5.3 Team Feature ....................................................................................................... 48 Figura 5.4 Team Steps Pendentes ......................................................................................... 49 Figura 5.5 Team Steps .......................................................................................................... 49 Figura 5.6 Controlador Team ................................................................................................ 50 Figura 5.7 team_spec.rb ........................................................................................................ 50 Figura 5.8 Team model ......................................................................................................... 51

LISTA DE ABREVIATURAS E SIGLAS


API BDD CoC DRY DSL ERB HTML IDE JVM MRI MVC RoR SAAS SSH SVN TDD URL VPS YAML YARV XP Application Programming Interface Behavior Driven Development Convention Over Configuration Don't Repeat Yourself Domain Specific Language Embedded Ruby Hyper Text Markup Language Integrated Development Environment Java Virtual Machine Matz's Ruby Interpreter Model View Controller Ruby on Rails Software as a Service Secure Shell Subversion Test Driven Development Uniform Resource Locator Virtual Private Server YAML Aint Markup Language Yet another Ruby VM Extreme Programming

RESUMO

Este trabalho apresenta as formas de desenvolvimento de software baseado em testes automatizados em Ruby on Rails como tecnologia para desenvolvimento de aplicaes para a Internet. So demonstrados suas principais caractersticas e componentes. Tambm so exibidos diversos frameworks que facilitam a elaborao de testes e gems relacionadas. Por fim, uma pequena sute de testes desenvolvida, de forma a exemplificar a utilizao dos recursos apresentados. Atravs da anlise das caractersticas da ferramenta e dos resultados obtidos no estudo de caso respondida a razo do Ruby on Rails ser uma plataforma que cumpre com sucesso sua proposta de simplicidade e agilidade.

ABSTRACT

This paper presents the ways of developing software-based automated tests in Ruby on Rails as the technology to develop applications for the Internet. Showing us the main characteristics and components. Also displayed are several frameworks that facilitate the development of tests and related gems. Finally, a small tests suite is developed in order to illustrate the use of appeals. By analyzing the characteristics of the tool and the results obtained in the study case, is answered the reason for Ruby on Rails to be a platform that successfully fulfills its proposal of simplicity and agility.

SUMRIO
1 INTRODUO ................................................................................................... 12 1.1 1.2 1.3 1.4 1.5 1.6 1.7 2 CONTEXTUALIZAO ................................................................................... 12 PROBLEMA ................................................................................................... 12 HIPTESE ..................................................................................................... 12 OBJETIVO ..................................................................................................... 13 JUSTIFICATIVA ............................................................................................. 13 METODOLOGIA DE PESQUISA ....................................................................... 13 ORGANIZAO DO TEXTO ............................................................................ 13

HISTRICO ........................................................................................................ 15 2.1 2.2 2.3 O COMPUTADOR .......................................................................................... 15 LINGUAGENS DE PROGRAMAO ................................................................. 15 MANIFESTO GIL ......................................................................................... 16

TECNOLOGIAS ENVOLVIDAS ....................................................................... 19 3.1 3.1.1 3.1.2 3.2 3.2.1 3.2.2 RUBY ............................................................................................................ 19 RubyGems ................................................................................................ 21 RVM ........................................................................................................ 21 RAILS ............................................................................................................ 21 Padro MVC ........................................................................................... 22 Suporte a Modelo no Rails ....................................................................... 24 3.2.2.1 Mapeamento Objeto Relacional ................................................... 24 3.2.2.2 Active Record .............................................................................. 25 3.2.3 Action Pack: Visualizao e Controlador ............................................... 25 3.2.3.1 Suporte a Visualizao ................................................................. 26 3.2.3.2 Controlador ................................................................................. 26

TESTES AUTOMATIZADOS ............................................................................ 27 4.1 TESTES EM RUBY ON RAILS .......................................................................... 28

4.1.1 Setup e TearDown ....................................................................................... 31 4.1.2 O que pode ser testado em Rails ................................................................. 32 4.1.3 Fixtures ....................................................................................................... 34

4.2 4.3

TEST DRIVEN DEVELOPMENT......................................................................... 34 BEHAVIOR DRIVEN DEVELOPMENT ................................................................ 36

4.3.1 Os Princpios do BDD ................................................................................. 37 4.4 RSPEC ........................................................................................................... 38

4.4.1 Descrevendo Comportamentos ................................................................... 38 4.4.2 Exemplos Pendentes.................................................................................... 40 4.4.3 Before, After, Specify, Let .......................................................................... 41 4.5 5 CUCUMBER ................................................................................................... 42

ESTUDO DE CASO ............................................................................................ 45 5.1 5.2 AMBIENTAO .............................................................................................. 45 PROERD ......................................................................................................... 45

5.2.1 Origem ......................................................................................................... 45 5.2.2 Propsito...................................................................................................... 46 5.3 5.4 OBJETIVO ...................................................................................................... 46 IMPLEMENTAO .......................................................................................... 47

5.4.1 Ferramentas ................................................................................................. 47 5.4.2 Testes com Rspec e Cucumber.................................................................... 47 6 CONSIDERAES FINAIS ............................................................................... 52 6.1 CONCLUSES ................................................................................................ 53

ANEXO A CDIGO FONTE TESTES .......................................................... 54 REFERNCIAS BIBLIOGRFICAS ................................................................ 65

12

1.

INTRODUO
Contextualizao

1.1

Atualmente o desenvolvimento de software tem crescido em larga escala no Brasil e no mundo. Com a popularizao da internet e dos smartsfones, desenvolver software tornou-se uma forma de adquirir conhecimento e renda. Mas com o grande aumento de profissionais na rea, observou-se a necessidade de elaborar padres de especificao para o desenvolvimento desses aplicativos. Para facilitar o trabalho das equipes na elaborao e implementao do projeto, so tomadas boas prticas para desenvolver software funcional e legvel, uma das mais importantes prticas adotadas para essa facilitao so os testes automatizados.

1.2

Problema

A grande dificuldade que as empresas de software enfrentam nos dias de hoje a manuteno do sistema em produo. Sabe-se que necessidades surgem a todo instante, e que para o desenvolvedor, lembrar do cdigo criado a algum tempo no uma tarefa fcil. O problema dessa deficincia torna a manuteno do cdigo quase invivel. O rodzio de profissionais em equipes tambm torna a padronizao do cdigo algo de difcil administrao. Devido a essas dificuldades, foram criados frameworks para facilitar o processo de criao e manuteno do cdigo fonte, otimizando todo o processo e garantido o retorno esperado do mesmo.

1.3

Hiptese

O ambiente de testes automatizados em Ruby On Rails, foco do trabalho, um conjunto de ferramentas integradas que visam tornar o desenvolvimento de aplicaes web simples e rpido. Esse ambiente visa cobrir o software com testes que garantem que determinada funcionalidade foi implementada com xito e executa sua funo da melhor forma esperada. Os testes automatizados tambm viso auxiliar o desenvolvimento atravs de reduo na complexidade do cdigo, o que facilitaria a manuteno futura. Atravs dos testes, pode ser feita uma leitura de cada mtodo do sistema em questo e entender seu comportamento por completo. A maioria dos testes auxilia o programador a entender a regra de negcio e program-la da melhor maneira possvel.

13

1.4

Objetivo

O objetivo desta pesquisa apresentar o ambiente de Testes Automatizados em Ruby on Rails. Seus benefcios e usos sero explicados ao decorrer do trabalho. Ser respondido ao longo deste trabalho o que teste automatizado, TDD e BDD. Sero explicadas as suas principais caractersticas, componentes e seu funcionamento. Ao final, ser apresentado um projeto construdo utilizando Ruby on Rails de forma a validar a proposta dos testes automatizados.

1.5

Justificativa

Ao adotar o padro gil de desenvolvimento que prioriza um produto de qualidade e um total contato com o cliente, o desenvolvedor se depara com um cenrio onde existem mudanas constantes. Essas mudanas podem prejudicar a qualidade do cdigo exponencialmente se no trabalhada de uma forma a facilitar seu entendimento. Com testes automatizados, qualquer desenvolvedor que entenda teste poder determinar perfeitamente o comportamento da aplicao e de seus mtodos. Com eles tambm possvel afirmar que quando uma funcionalidade terminada realmente est terminada. Os testes facilitam a escrita do cdigo, facilita a interao da equipe e torna o sistema mais resistente a falhas e bugs.

1.6

Metodologia de Pesquisa

Foram utilizados livros especializados no assunto como fontes de pesquisa, documentos produzidos pela comunidade que desenvolve a plataforma Ruby On Rails, alm de sites na internet.

1.7

Organizao do Texto

O texto est organizado em 6 captulos. O Captulo 2 mostra a evoluo das tecnologias que culminaram com o surgimento de aplicaes na Internet, linguagens de programao e o Manifesto gil. O Captulo 3 apresenta a linguagem de programao Ruby, suas origens e ideais. Introduzir o framework Ruby On Rails seus componentes e principais caractersticas. O Captulo 4 apresenta 14

testes automatizados em Ruby On Rails, TDD, BDD e o uso de dois frameworks muito utilizados na comunidade para determinar o comportamento da aplicao e fazer teste de integrao. O captulo 5 procura demonstrar a utilizao dos conceitos apresentados atravs do desenvolvimento de um sistema baseado na plataforma Ruby On Rails. As consideraes finais sobre o projeto de estudo deste texto se encontram no Captulo 6.

15

2. HISTRICO
2.1 O Computador
Pode-se considerar o computador como uma das grandes descobertas da humanidade. Temse hoje o computador como uma ferramenta essencial no dia a dia de muitas empresas e indstrias. Seu principal papel o processamento de dados, sabe-se que os dados que so inseridos passam por um processamento e armazenagem, o que permite a anlise e compreenso de uma larga escala de informao em poucos segundos. Na dcada de 40, os computadores eram gigantescos e ocupavam grande espao fsico, eram utilizados principalmente para pesquisas cientficas e operaes militares. Os computadores dessa dcada tinham programas especficos para cada rea de atuao e eram usados somente por especialistas. Com o passar das dcadas e a grande quantidade de informao a serem processadas, as empresas foram motivadas a expandir o uso dos computadores. Com isso, passaram a fabricar computadores com tamanhos reduzidos e com um poder de processamento maior. Existiam terminais de acesso a grandes mainframes, estes, gerenciavam todos os aplicativos e efetuavam o processamento dos dados. Devido popularizao dos computadores nas empresas, notou-se uma grande possibilidade de expandir o mesmo para a utilizao domstica, o que proporcionou um maior contato do usurio leigo e o surgimento de programas personalizados para atender diversas necessidades que surgiriam com o tempo. Atualmente, com o crescimento da demanda por computadores e dispositivos portteis de acesso a internet e a aplicativos, os smartfones e tecnologias mveis tem tomado uma grande fatia do mercado tecnolgico para utilizao e resoluo de problemas rotineiros.

2.2 Linguagem de Programao


Uma linguagem de programao um conjunto de instrues que so lidas por uma mquina para efetuar algum processamento, ou seja, este conjunto de instrues forma o programa de computador. A linguagem permite que o programador controle o comportamento do programa e as decises do computador de acordo com uma srie de blocos de cdigos e estruturas que permitem a tomada de decises pela mquina. 16

O conjunto de instrues que so digitadas no computador compem o que chamado de cdigo fonte de um software. O que ser compilado e transformado em linguagem de mquina para que o processador venha a entender. A principal motivao para utilizar uma linguagem de programao para a elaborao de um software a produtividade. A maioria das linguagens de programao eleva o nvel da programao utilizando sintaxe e conceitos mais prximos da linguagem humana. As primeiras linguagens de programao surgiram na dcada de 50, sendo como principais daquela poca, FORTRAN, LISP, COBOL. Na dcada de 70 as linguagens que comearam a aparecer foram, Pascal, SQL e C, ento comeou a debater-se sobre a criao de linguagens estruturadas. Programao estruturada a programao onde utilizado um fluxo para a execuo do cdigo escrito, ao contrrio das linguagens que utilizavam o famoso GOTO para levar a diversas partes do cdigo, a programao estruturada segue um bloco de cdigo com vrias funes e subrotinas que seguidas estruturalmente processam as informaes de acordo com as condies impostas pelo desenvolvedor. Um pouco mais tarde foi criada a programao orientada a objetos. A orientao a objetos visa determinar escopos reduzidos para a construo dos blocos de cdigo, facilitando assim o entendimento do programa e sua real funo e fluxo de troca de mensagens. Esse paradigma visa modelagem de objetos do mundo real, agregando a eles comportamentos semelhantes no contexto da aplicao. A comunicao entre os objetos feita atravs de mensagens entre os mtodos. As linguagens que inspiraram a orientao a objetos foram o C++ e o Perl. Na dcada de 90 houve o surgimento do Java, Python e C#. A maioria dessas linguagens era direcionada a web, devido popularizao da internet no mundo e a necessidade de aplicaes para internet. Uma peculiaridade da era da internet, foi o surgimento de linguagens de script, como PHP, Ruby e JavaScript.

2.3 Manifesto gil


Com o aumento exponencial do uso de computadores por empresas e indivduos, a necessidade de produzir software tornou-se algo vital para a humanidade. Vrias empresas comearam a ser formadas ao redor do globo, desenvolvendo de formas distintas. Com a necessidade de mo de obra e padronizao na produo, reas da computao foram surgindo, tais como a Engenharia de Software. Portanto, foram elaborados alguns modelos para especificar o desenvolvimento de sistemas, dos quais se destaca o modelo cascata ou seqencial, que visa construo do software por etapas pr-determinadas. 17

Ao longo dos anos, alguns desenvolvedores perceberam que a forma de trabalhar no estava correta, ou seja, as questes de levantamento de requisito antes e codificao depois de preencher papis de documentao no se encaixavam na realidade do mercado. Esses, mais conhecidos como signatrios, elaboraram o manifesto gil, que determina algumas prioridades na elaborao do software no mundo real. Esse manifesto visa reforar as boas prticas para desenvolvimento apontando o modelo a ser seguido num projeto. Nesse manifesto temos quatro valores principais:

Os indivduos e suas interaes acima de procedimentos e ferramentas O funcionamento do software acima de documentao abrangente A colaborao dos clientes acima da negociao de contratos A capacidade de resposta s mudanas acima de um plano pr-estabelecido

O que foi observado com esses valores principais, que o processo clssico para elaborao de um projeto de software era engessado por partes vitais e seqenciais, ou seja, se alguma das partes no fosse completada a tempo, o projeto ficava congelado esperando liberao de tal parte. J o manifesto gil prega uma interao constante com o cliente para ter feedback das funcionalidades implementadas, o produto sendo posto em produo antes mesmo de uma extensa documentao, e outros valores que vem melhorando a forma de desenvolver software atualmente. A agilidade nos projetos no implica na velocidade do desenvolvimento e sim nos curtos perodos de tempo que o produto leva para ser entregue, ou seja, tm-se entregas semanais dos produtos, para saber se tal funcionalidade atende a necessidade do cliente. A busca por simplicidade no cdigo e qualidade tcnica tambm so fatores abordados pelo manifesto gil. A partir dele, alguns dos signatrios ganharam notoriedade no meio do mundo do desenvolvimento, dentre eles podemos ressaltar Kent Beck, o criador do XP (BECK, 99). A tcnica do XP utilizada para agilizar o processo de desenvolvimento e reduzir a complexidade do cdigo criado pelo desenvolvedor atravs de boas prticas, sendo elas:

Testes automatizados Programao em Par Refatorao

Com os testes possvel afirmar que o cdigo elaborado realmente faz o que ele se prope a fazer. A programao em par visa qualidade do software e o aprendizado com duas pessoas

18

programando juntas uma funcionalidade. E a refatorao o ato de sempre melhorar o cdigo uma vez criado.

Refatorao ajuda voc a fazer cdigo mais legvel. Quando estamos refatorando, vemos cdigo que funciona, mas ainda no est totalmente estruturado. Um pouco de tempo gasto com refatorao pode fazer o cdigo ser auto-explicativo. Programar dessa forma sempre querer mostrar o que aquilo significa pra voc. [FOWL 99, p. 48]

19

3. TECNOLOGIAS ENVOLVIDAS
3.1 Ruby
Antigamente, a forma de diferenciar uma linguagem era fcil: haviam apenas a compilada, como C ou Fortran, ou a interpretada, como BASIC. Sabe-se que linguagens compiladas do velocidade e acesso de baixo nvel em computadores. J as interpretadas so de alto nvel, porm mais lentas. O tempo se passou e alguns designers de linguagem comearam a chamar suas criaes de Linguagem de Script. Isso significa que essas linguagens, alm de serem interpretadas, podiam ser usadas para substituir arquivos batch e shell scripts, manipulando o comportamento de outros programas e algumas funes do sistema operacional. Dentre as linguagens de Script podemos citar: Python, Perl, TCL e Ruby. [THOM, 04] Ruby uma linguagem de script com uma tipagem dinmica, forte e gerenciamento de memria automtico. fcil de aprender. Tarefas dirias so simples de codificar e, uma vez tendo as criado, fcil mant-las e expand-las. uma linguagem transparente, porque no existem partes obscuras na escrita do cdigo, por outro lado, esse muito legvel e torna o entendimento fcil para o programador. A dificuldade que o programador tem em outras linguagens para expressar o pensamento lgico, no existe em Ruby. Pela facilidade que h em escrever cdigo em Ruby, podemos nos preocupar apenas com as regras de negcio do escopo do software e com alguns padres de manuteno e melhorias constantes. Com a facilidade na leitura do cdigo digitado, o risco de errar ou escrever cdigo com comportamento duvidoso quase nula. Ruby uma linguagem concebida pelo intelecto de um homem atravs dos pontos positivos de diversas linguagens. Yukihiro Matsumoto, mais conhecido na comunidade como Matz, pegou os pontos principais de diversas linguagens como, ADA, LISP, Smalltalk, Python, Perl, e incorporou no ncleo da linguagem. [FLAN, 08] Pode-se ressaltar que Ruby fortemente orientada a objetos, ou seja, tudo um objeto. Outro aspecto importante que esta linguagem possui uma poderosa capacidade de metaprogramao. Matz se preocupou em fazer uma linguagem que realmente fosse amiga do programador, tornando seu trabalho dirio divertido. Em suas prprias palavras ele dizia: Ruby is designed to make programmers happy (Ruby projetada para fazer os programadores felizes) [MATZ].

20

Ruby uma linguagem orientada a objetos genuna. Tudo que manipulado um objeto e os resultados dessa manipulao tambm so objetos. [THOM 04, p.09]

A primeira publicao de Ruby, a verso 0.95, foi lanada em dezembro de 1995. O primeiro livro sobre a linguagem fora do Japo foi impresso somente em 2000. A verso da linguagem amplamente utilizada hoje a 1.8. Em 30 de janeiro de 2009 a verso 1.9.1 foi introduzida, incorporando novas caractersticas e melhorias, principalmente no que diz respeito ao desempenho. Ruby, at sua verso 1.8, tinha apenas duas principais implementaes. A primeira e mais comum a MRI (Matzs Ruby Interpreter), interpretador do prprio Matsumoto. A segunda chamada JRuby, e roda o cdigo ruby dentro da JVM (Java Virtual Machine). A partir da verso 1.9 uma nova mquina virtual utilizada, o YARV (Yet another Ruby VM), uma mquina virtual que interpreta byte code visando aumentar a velocidade de programas em Ruby.

3.1.2 RubyGems
RubyGems um gerenciador de pacotes para a linguagem de programao Ruby. Uma gem um conjunto de cdigos reutilizveis que podem ser distribudos num formato muito parecido com o repositrio apt-get do Linux. O interessante na utilizao de gems o padro imposto na elaborao da mesma e seu controle de verses.

RubyGems

um

framework

de

instalao

empacotamento para bibliotecas e aplicativos, facilitando a localizao, instalao, atualizao e desinstalao de pacotes Ruby. (THOM 04, p. 203)

Para instalar uma gem no Ruby, basta digitar o seguinte comando:

gem install nomedagem

21

3.1.3 RVM Ruby Version Manager


RVM um gerenciador de controle de verso para a linguagem Ruby que permite ao desenvolvedor ter vrias verses da linguagem instaladas na mesma mquina. Antes da criao do RVM era difcil e conflitante utilizar verses diferentes do Ruby com gems diferentes e alternar de acordo com cada projeto. J com o uso da RVM basta digitar: rvm use versaodoruby, para utilizar a verso especificada. Com o RVM possvel ter vrias verses de Ruby instalados na mquina e vrias gems dentro de cada verso, o que facilita bastante na hora de desenvolver um projeto, bem como contribui na questo da compatibilidade entre sistemas desenvolvidos com verses distintas.

3.2 Rails
Com a popularizao do desenvolvimento web e com as prticas geis sendo incorporadas nas empresas em todo o mundo, a maioria dos desenvolvedores passaram a reaproveitar cdigo para evitar a repetio na hora de iniciar um novo projeto e ter que configurar todos os diretrios, pastas, banco de dados e ambiente. A partir do momento que a reutilizao de cdigo tornou-se uma tarefa quase que obrigatria na rea de desenvolvimento, foram surgindo os frameworks para abstrao de camadas mais complexas de programao e para reuso do cdigo usado em projetos. Uma faanha que a orientao a objetos conseguiu obter foi estruturao de blocos de cdigos imensos, em pequenas classes especialistas. Alguns conceitos como Herana, Polimorfismo e Interfaces auxiliam o desenvolvedor a estruturar melhor o seu cdigo e faz-lo sem muitas linhas em um nico arquivo. Pensando assim, surgiu o Ruby on Rails. David Heinemeier Hansson (DHH), o criador do Rails, cansado de utilizar cdigos gigantescos, como Java e PHP, resolveu utilizar alguma linguagem nova que atendesse sua necessidade naquele momento. Ele ento, ao iniciar seu projeto intitulado BaseCamp, na 37 Signals, empresa na qual ele foi contratado como programador, comeou a preparar seu ambiente de desenvolvimento, fazendo classes genricas, abusando da orientao a objetos e da linguagem Ruby, que permitia o uso intenso deste paradigma.[RUBY, 11] Rails foi lanado em 2005 para uso pela comunidade como open source, o que permitiu sua constante melhora e adio de funcionalidades por um grupo intitulado CORE TEAM e por outros desenvolvedores. 22

ROR (Ruby On Rails) tem como objetivo facilitar o desenvolvimento de aplicaes web. um framework que facilita a elaborao de aplicativos e torna fcil a manuteno devido a alguns princpios de qualidade de software. O primeiro princpio, Convention Over Configuration (CoC), diz que o programador que seguir algumas convenes ter rapidamente sua aplicao rodando com o mnimo de complexidade. Programadores Java que j passaram por problemas de dependncias, configuraes de XML (eXtensible Markup Language), banco de dados e servidores, podem facilmente migrar para ROR e ver o quanto de configurao encapsulada.

Rails prioriza indivduos e interaes. No existem ferramentas pesadas, configuraes complexas e processos elaborados. [RUBY, 2011, p21] Rails tambm possui o princpio de DRY (Dont Repeat Yourself), ou seja, deve-se apenas ter cdigo no lugar onde aquele cdigo destina-se a ser usado. No se deve repetir o cdigo gerado em outros lugares. Se esse cdigo usado em vrios locais, deve-se torn-lo genrico e de acesso mltiplo a vrias classes. DHH quando criou o Rails fez pensando de forma gil e dentro de alguns padres de projeto. Uma caracterstica que confirma essa afirmao a criao de trs ambientes de execuo, Production (Produo), Development (Desenvolvimento) e Test (teste). Como se sabe, uma aplicao em produo tem toda uma particularidade, assim como nos outros ambientes. Em Java, necessrio sempre que feita uma modificao, reiniciar o servidor e iniciar o mesmo para visualizar a modificao efetuada. J no ROR tem-se como utilizar o ambiente de desenvolvimento e simplesmente atualizar o navegador para visualizar a modificao efetuada no cdigo. Ratificando o uso de metodologias geis, o ambiente de teste fora criado para facilitar a execuo de sutes de testes e configurao de algumas peculiaridades como seed de banco de dados, fixtures, etc. E o ltimo conceito, o KISS (Keep it Simple Stupid) visa manter o cdigo criado na forma mais simples possvel, permitindo que qualquer desenvolvedor entenda o que o mesmo faz, e reforando o uso de refatorao no cdigo criado.

3.2.1 Padro MVC


Em 1979, Trygve Reenskaug desenvolveu uma nova arquitetura para desenvolver aplicaes interativas. Na sua concepo, as aplicaes eram distribudas em trs partes: Modelo, Visualizao e Controlador. [RUBY, 11] 23

O modelo responsvel por manter o estado da aplicao. O modelo quase no tem contato com o usurio, ele responsvel pelo armazenamento da informao na base de dados. Representa tambm a entidade no sistema a ser desenvolvido e mantm em si, toda a regra de negcio da aplicao.

Um modelo mais que apenas dados. Ele agrega todas as regras de negcio que se aplica aos dados. [RUBY, 2011, p. 51] A visualizao responsvel pela apresentao dos dados obtidos pelo modelo, gerando assim a interface. Sabe-se que essa interface pode ser representada de diversas formas para o mesmo modelo, dependendo assim da necessidade do usurio. O controlador como o prprio nome j diz, controla toda interao do usurio com o sistema e qual visualizao o mesmo vai obter, ou seja, ele orquestra o modelo, e a visualizao deste, e as entradas de dados do usurio. atravs do controlador que podemos buscar adicionar e localizar dados no sistema. Ruby on Rails um framework MVC. Ao criar uma aplicao Rails, pode-se observar que o framework cria automaticamente os diretrios para os controladores, as visualizaes e os modelos. Sendo assim, o Rails consegue interpretar todo o cdigo adicionado nos trs locais, respeitando o conceito de MVC e deixando a aplicao mais fcil de ser mantida.

Figura 3.1 - Fonte: Modelo MVC Rails, http://wiki.cercomp.ufg.br/Equipe_Web/RoR/MVC, 2011

24

3.2.2 Suporte a Modelo no Rails

O objetivo principal do Rails proporcionar aos desenvolvedores para web que utilizam o padro MVC a possibilidade de armazenar dados no banco de dados atravs da prpria aplicao. Ele trata cada modelo criado atravs do framework como uma entidade, e atravs dessa conveno nota-se que o Rails cria automaticamente a tabela no banco de dados para receber os respectivos dados e seus relacionamentos caso existam. O problema em trabalhar com uma linguagem de programao orientada a objetos e um banco de dados relacional j conhecido, devido complexidade em questo. correto afirmar que objetos possuem dados e mtodos. Em contrapartida, bancos de dados so somente linhas e colunas com conjunto de valores. O mapeamento objeto-relacional sempre foi uma tarefa difcil de ser implementada, at mesmo em outras linguagens. Devido a essa dificuldade, alguns desenvolvedores comearam a estudar padres de mapeamento objeto-relacional, o que permitia a comunicao e modelagem dos objetos em colunas do banco de dados. Essas bibliotecas que fazem essa comunicao so conhecidas como ORMs (Object-Relational Mapping).

3.2.2.1 Mapeamento Objeto-Relacional


Bibliotecas de Mapeamento Objeto-Relacional mapeiam as tabelas do banco de dados em classes. Por exemplo, se existe uma tabela chamada cliente, deve existir uma classe chamada cliente. Os objetos clientes correspondem a linhas na tabela e seus atributos a colunas da mesma. Cada objeto tem mtodos get e set para preench-lo com os dados das colunas. Rails, em especfico, traz mtodos que auxiliam a manipular os dados vindos do banco de dados. Por exemplo, possvel observar nesse cdigo Ruby a complexidade SQL que foi omitida para achar um cliente por seu cdigo:
cliente = Cliente.find(1)

Figura 3.2 Cdigo Rails para localizar Cliente por id

25

Em resumo, uma camada de Mapeamento Objeto-relacional mapeia tabelas para classes, linhas para objetos e colunas para atributos desse objeto. Geralmente, para que esse processo ocorra, necessrio utilizar arquivos XML para fazer o relacionamento dos campos. Porm, com a Conveno sobre a Configurao do Rails, o processo automtico.

3.2.2.2 Active Record


Active Record (AR) a camada ORM que vem com o Rails. Ele segue estritamente o padro dos ORMs tradicionais, porm, uma das grandes adies feitas foi reduo de configurao se o padro do framework for seguido. Para entender melhor como isso feito, veremos um cdigo em Rails de um mapeamento de uma tabela chamada clientes:
classCliente<ActiveRecord::Base end

cliente = Cliente.find(1) cliente.nome = Thiago cliente.save

Figura 3.3 Exemplo de Uso do AR

Como observado a classe automaticamente, quando criada, herda de ActiveRecord::Base, que a classe ORM que vem por padro em Rails. Com essa classe herdada, todos os mtodos e atributos da classe ActiveRecord passam a fazer parte da classe Cliente, podendo simplesmente fazer um find e localizar um cliente por id. Localizando o registro, possvel modific-lo e depois salv-lo na base de dados. O AR do Rails a base do Modelo do padro MVC e tambm um padro de projeto estabelecido por Martin Fowler [FOW 03]. Ele possui algumas validaes dos atributos pertencentes ao modelo e outros mtodos que fazem dele um framework prtico e .

3.3 Action Pack: Visualizao e Controlador


Quando analisado a fundo a visualizao e o controlador no padro MVC, possvel perceber o quo interligados esto. O controlador recebe vrias requisies das interfaces geradas

26

pela visualizao. Por outro lado, o controlador alimenta a camada de visualizao com os dados do Modelo. Devido a essa aproximao, o Rails agrupou os dois num pacote chamado ActionPack.

3.3.1 Suporte a Visualizao


A parte de visualizao em Rails responsvel por criar todas as telas que vo exibir as respostas geradas pelas requisies. A visualizao uma pgina HTML padro. Quando queremos utilizar texto dinmico na aplicao, ele utiliza alguma ao do controlador e exibe atravs de um cdigo Ruby dentro do HTML com extenso ERB (Embedded Ruby).

3.3.2 Controlador
O controlador o centro da lgica da aplicao. Ele coordena a interao do usurio com a camada de visualizao e o modelo. Quando um usurio clica em algum link da aplicao, o controlador o responsvel por executar aquela requisio, filtrando alguns dados, modificando-os e salvando-os e exibindo seu resultado atravs de URLs amigveis.

O Controlador no Rails o centro de toda lgica da aplicao. Ele coordena as interaes do usurio, as

visualizaes e o modelo. [RUBY, 2011, p.57]

Todos

os

controladores

criados

pelo

Rails,

so

destinados

herdar

de

ActionController::Base, mas o framework cria um controlador chamado ApplicationController e o faz ser herdado pelos controladores criados pelo usurio, mantendo assim mtodos criados para uso generalizado dos controladores em um s lugar.

27

4. TESTES AUTOMATIZADOS
Qualidade de Software um assunto discutido em larga escala por empresas, desenvolvedores e clientes. Antigamente era satisfatrio ter um sistema em produo, porm existem outras preocupaes. Um cdigo bem escrito considerado um cdigo limpo segundo desenvolvedores experientes no mercado. O que seria um cdigo limpo e um cdigo ruim? Segundo o livro Clean Code [MART, 09] um cdigo bom um cdigo que realmente expressa o que ele faz apenas sendo lido, tanto pelo autor do mesmo, como por outros desenvolvedores. Um cdigo ruim simplesmente o contrrio da afirmao acima. Com as metodologias geis sendo popularizadas e com o crescente uso da Programao eXtrema (XP) [BACK,04], a necessidade de acelerar o processo de testes de software foi tornandose cada vez mais necessria. Antes de ouvir-se falar em testes automatizados, os desenvolvedores depuravam o cdigo existente atravs de debugging. Debugar um cdigo seguir seu fluxo e tentar achar a parte que lana erros ou excees em ambiente de execuo. Se fosse necessrio debugar um sistema complexo e com milhares de linhas de cdigo, isso poderia ser uma tarefa complexa e nada produtiva. Essa antiga forma de teste, depurao e correo de erros era utilizada principalmente na metodologia de desenvolvimento em cascata, onde se levantavam as funcionalidades, faziam os diagramas, implementava-os e lanavaos para aprovao e teste. Estes testes do modelo em cascata no eram automatizados, eram feitos por Testers, pessoas especializadas em apenas realizar testes manuais em softwares. Porm, testes manuais so demorados e na maioria das vezes no cobrem todas as possibilidades de resposta de um cdigo, o que no garantia que o cdigo implementado alterasse o comportamento de outro mtodo ou funo em outra parte. Algumas empresas ainda utilizam este modelo de testes em software, e por incrvel que parea, ainda existem algumas que no fazem testes. O que foi observado com o tempo que modificao no cdigo com o sistema em produo mais custosa do que as em projeto. Segundo o Manifesto gil, necessrio ter interaes com o cliente constantemente e estar plenamente disposto a modificar o cdigo. Com testes automatizados, a rotina e o desgaste devido aos testes manuais acabam. Pode-se executar o conjunto de testes quantas vezes for necessrio, cobrindo praticamente a totalidade do cdigo implementado e tendo a certeza, de que, depois de adicionada uma nova funcionalidade, todo o sistema ir funcionar corretamente sem sofrer alteraes comportamentais. 28

No mundo dos testes automatizados, h os testes unitrios que so responsveis por testar pedaos de cdigo unitariamente; tem-se os testes de integrao que permite averiguar o fluxo de dados e a comunicao dos diversos mdulos implementados separadamente; e tambm os testes de aceitao que literalmente testam a aceitao do sistema por seus usurios e se as funcionalidades respondem de acordo com o que foi analisado e descrito.

Existem vrios benefcios de se ter testes bem elaborados. Voc ter um melhor design no cdigo que lhe proporcionar mais confiana. Mas o mais importante que se voc testa bem, seu trabalho mais produtivo. [RAPP, 2011, P.17] O mais importante dos testes automatizados que eles facilitam a vida do programador e o auxilia a criar um cdigo mais legvel e simples. Toda complexidade do cdigo reduzida com o auxlio de testes. Existe uma tcnica chamada TDD, comentada mais adiante, que define passos para implementao de cdigo depois de ter testes escritos. Sendo assim, o design do sistema tornase mais coeso e qualquer desenvolvedor que ler as especificaes dos testes entender o comportamento dos mtodos das classes. Testes auxiliam na criao e na manuteno do cdigo fonte de um sistema. Segundo Feathers, cdigo legado cdigo sem testes, ou seja, no importa se o cdigo antigo ou novo, se no tiver testes um cdigo legado.

4.1 Testes em Ruby on Rails


Ruby on Rails, por ser um framework gil para desenvolvimento web, como o prprio Dave Thomas menciona no livro Agile Web Development [RUBY, 11] , j vem com vrias bibliotecas de testes automatizados. A biblioteca padro a Test::Unit, que vem junto com o Ruby at sua verso 1.8.7. A partir da 1.9.2 a padro passou a ser a biblioteca chamada minitest. Testes automatizados esto no corao de uma aplicao Rails. A partir do momento que o desenvolvedor utiliza o comando rails new nomeaplicacao (Rails 3.0.6), criado um diretrio especfico para testes unitrios, gerando toda uma infraestrutura para iniciao com testes. Testes unitrios so testes que pegam a menor unidade em uma classe. Para ser mais exato, estes testes testam os retornos dos mtodos, localizados principalmente no modelo. Se existir um modelo chamado produto, dentro da pasta test/unit/, haver um arquivo chamado produto_test.rb. Dentro desse arquivo existe cdigo Ruby como o que visto logo abaixo: 29

classProdutoTest<ActiveSupport::TestCase # Replace this with your real tests. test "the truth" do assert true end end

Figura 4.1 Exemplo de Estrutura de Teste Unitrio

classe

gerada

ProdutoTest

uma

subclasse

de

ActiveSupport::TestCase.

ActiveSupport::TestCase uma subclasse de Test::Unit::TestCase, o que indica que os geradores de teste do Rails so baseados no RubyTest::Unit que vem pr-instalado com o Ruby. O bom disso que se o desenvolvedor j tem habilidades com os testes unitrios em Ruby, esse conhecimento pode ser utilizado em aplicaes Rails. Para os novatos em testes unitrios, o Rails cria uma assero (assert) como exemplo de como criar mtodos de testes no framework. Toda assero tem por regra retornar verdadeiro (true) para os testes escritos. Quando escrito assert true para que o resultado seja verdadeiro, ou seja, para que o teste passe, a resposta daquele mtodo deve ser verdadeira. Para aprofundar-se nos testes unitrios, preciso primeiramente aprender como utilizar alguns mtodos do framework de testes do Ruby. Esses mtodos conhecidos como asseres possuem a funcionalidade de retornar true ou false. Se uma assero falsa, o teste falha e o conjunto de testes que est sendo executado interrompido. Se a assero verdadeira, o teste passa e garante que o mtodo est bem estruturado para aquela funcionalidade escrita. A seguir apresentado um simples exemplo do uso de asseres no Test::Unit:

test "produto deve ter um nome" do @produto = Produto.new @produto.nome = radio assert (@produto.nome == "radio") end

Figura 4.2 Teste Unitrio com Assero

30

Esse simples teste garante que o objeto produto que foi instanciado dentro de uma varivel de instncia (@produto) chamada produto deve possuir um nome. Caso o nome no fosse definido, o teste retornaria falso e nos exibiria uma mensagem dizendo que o teste produto deve ter um nome retornou falso porque no est atribuindo um nome para o objeto produto. A assero mais usada a assert_equal que garante que um valor atribudo a um objeto igual ao valor descrito no teste. Sabendo que para efetuar um teste, devemos ter um banco de dados especfico para testes, ou outros meios de instanciar objetos para executar os testes, os valores que sero testados so pr-configurados para que o teste passe. A assero assert_equal(), recebe dois argumentos: um valor esperado e um valor que esta dentro do objeto e retorna true se os valores forem iguais. Implicitamente, o mtodo assert_equal utilizado o operador == do Ruby para comparao de igualdade, assim como o equals do Java e C#. [RUBY, 11]

test

produto.nome deve ser igual a camisa do @produto = produto.new assert_equal camisa, @produto.nome

end

Figura 4.3 Teste Unitrio com Assert_Equal

Note que todos os mtodos de teste feitos seguem a mesma estrutura. Comeam com a palavra chave test, nome do mtodo, do, bloco de cdigo e end, indicando o fim do mtodo. Isso facilita o parser do TestUnit identificar os mtodos que so efetivamente testes. Se for necessrio testar a falha de um teste, ou seja, se um valor diferente do outro, pode-se usar o assert_not_equal().

test

deve retornar verdadeiro se produto.nome for diferente do @produto = produto.new @produto.nome = cala assert_not_equal camisa, @produto.nome

end

Figura 4.4 Teste Unitrio com Assert_not_equal

Como visto, boa prtica colocar no nome dos testes a real inteno do mesmo. Sero listadas aqui algumas asseres utilizadas pelo Test::Unit framework do Ruby: 31

assert_instance_of(klass, object)( ), assert_kind_of(klass, object)( ) Informa se o objeto um objeto da classe passada como argumento;

assert_match(pattern, string) ( ), assert_no_match(pattern, string) ( ) Igual o assert_equal() mas para expresses regulares;

assert_nil(object) ( ), assert_not_nil(object) ( ) Verifica se um objeto nulo ou no;

assert_raise(*args, &block) ( ), assert_nothing_raised(*args, &block)( ) Verifica se uma exceo levantada e o teste bem sucedido se essa exceo foi levantada

pelo bloco passado. Na negativa o contrrio ocorre.

possvel obter maiores informaes sobre asseres e como utiliz-las no site do framework de testes unitrios no Ruby. 4.1.1 Setup e TearDown Quando os testes crescem em quantidade de mtodos, duplicaes podem ser encontradas no cdigo, ou seja, observando os pequenos testes escritos nos exemplos a seguir, verifica-se que a parte de configurao dos objetos idntica:
test deve retornar verdadeiro se produto.nome for diferente do @produto = Produto.new @produto.nome = camisa assert_not_equal camisa, @produto.nome end test produto.nome deve ser igual a camisa do @produto = Produto.new @produto.nome = camisa assert_equal camisa, @produto.nome end test "produto deve ter um nome" do @produto = Produto.new @produto.nome = camisa assert (@produto.nome == "camisa") end

Figura 4.5 Exemplo de Repetio de Cdigo em Teste Unitrio 32

Nesses testes sempre obrigatrio instanciar os objetos e, em alguns, atribuir contedo s variveis. Para evitar duplicao de cdigo e seguir sempre o princpio DRY em testes, pode-se utilizar um mtodo chamado setup.
def setup @produto = Produto.new @produto.nome = thiago end

4.6 Exemplo do Mtodo Setup

Esse mtodo carregado automaticamente ao executar cada mtodo de teste do conjunto de testes, evitando a repetio de cdigo em cada teste escrito. Em testes unitrios, utilizado um mtodo chamado tearDown para executar algo depois de rodar os testes.

4.1.2 O que pode ser testado em Rails?


Quando se testa uma aplicao Rails, o framework especifica o local padro dos testes baseado na classe que ser testada. Todos os arquivos e diretrios de testes em uma aplicao so encontrados em uma pasta chamada test dentro da pasta do projeto. Tendo todos os arquivos em apenas uma pasta centralizada de testes, facilita a localizao dos arquivos e a criao e manuteno de novos arquivos. As classes de teste para os modelos encontram-se no diretrio

test/init/nomedaclasse_test.rb. Para essa classe de teste criada, o framework espera ter uma classe modelo que a corresponda. Os testes funcionais e os controladores tm a mesma relao que os testes unitrios e os modelos. Isso significa que testes funcionais so relevantes a testes especficos de controllers. Essas classes esto localizadas em test/functional. Para cada classe controladora, existe um teste funcional criado. Se esse controlador foi gerado atravs dos geradores do Rails. Todos os testes de controladores no Rails herdam de ActionController::TestCase, que uma subclasse de ActiveSupport::TestCase que tambm utilizado pelos modelos. [RAPP, 11]

33

O objetivo do teste de controlador simular uma nica requisio para especificar o mtodo do controlador e fazer asseres sobre o resultado. [RAPP, 11, p. 131]

O Rails cria tambm um arquivo chamado test_helper.rb que contem algumas funcionalidades e configuraes comuns a todos os testes, bem parecido com o

applicationController que gerado para compartilhar mtodos em todos os controllers. O que torna essa informao preciosa que todos os arquivos de testes fazem um require (como o import do Java) do arquivo test_helper para que o mesmo possa ser executado com xito. Existem ainda dois outros tipos de testes em Rails. O teste de integrao que, mesmo sendo um pouco ignorado, responsvel por testar seqncias de eventos que invocam vrias aes e controladores e os testes de desempenho. Os testes de integrao do diretrizes para validao de interaes complexas na aplicao e tambm garantem que no existam falhas nos testes dos controladores. Os testes de integrao so criados usando o comando script/generate integration_test e no so gerados automaticamente por nenhum outro gerador do Rails.

Testes de integrao so a ferramenta de escolha no Rails para testar qualquer processo que chama uma ou mais aes do controlador. [RAPP, 2011, p. 218] J os testes de desempenho so diferentes dos outros testes automatizados. Eles no verificam se um mtodo retorna o que lhe prescrito ou se existe algum erro de implementao, mas eles do informaes sobre o desempenho das aes que so chamadas enquanto outros testes so executados. Para executar o conjunto de testes em Rails pode-se utilizar o comando rake test. Esse comando roda todos os testes existentes na aplicao. Caso seja necessrio rodar somente testes de um grupo especfico, por exemplo, unitrios, basta digitar rake test:units, ou qualquer uma das outras opes. Se o teste for executado com sucesso, o resultado no terminal do computador ser um . (ponto). Se o teste resultou em erro, a letra E aparecer informando o erro e, se uma assero falhar, ser exibido um F.

34

4.1.3 Fixtures
Na maioria das vezes, testar alguma funcionalidade em um sistema depende da existncia de dados pr-cadastrados na base de dados. Agora se for necessrio criar dados fictcios todas as vezes que testes rodarem na aplicao, haveria vrios problemas de repetio e grande parte do tempo produtivo seria perdido. Devido a essa necessidade, o Rails vem com algo chamado fixtures. Segundo Rappin, uma fixture um conjunto de dados predefinidos usados como base para mltiplos testes. Em Rails, todo modelo tem uma base de teste relacionada. Elas so escritas em arquivos YAML (YAML is not another Markup Language), e proporcionam um conjunto complexo de dados que so carregados automaticamente antes de cada teste. A base de dados de teste em Rails renovada a cada vez que um teste executado, por isso temos trs ambientes. Se existe um modelo chamado produto, h uma fixture em test/fixtures/ chamada produto.yml. Estas seguem o padro de indentao para que o framework possa identificar os dados escritos no arquivo.

4.2 Test Driven Development

Desenvolvimento Guiado por Teste, ou simplesmente TDD como conhecida, uma tcnica usado por equipes geis para desenvolver software guiado por teste. Antes de implementar qualquer funcionalidade no sistema, escreve-se primeiramente um teste que apresente falha e baseado nesse teste, cria-se o cdigo que vai atender estritamente o que o teste necessita. Ele utilizado para design de aplicao pois, atravs dos testes que so elaborados antes do cdigo, possvel entender as regras de negcio da aplicao e o que o cdigo escrito realmente far.

Test Driven Development uma prtica de desenvolvimento que envolve escrever teste antes de escrever cdigo a ser testado. Comea escrevendo um pequeno teste para o cdigo que ainda no existe. [CHE 10] Escrevendo o cdigo baseado de testes, o desenvolvedor tem o cuidado de pensar na melhor forma de resolver um determinado problema da maneira mais simples possvel. Testando primeiro e

35

escrevendo cdigo depois, pode-se pensar melhor na funcionalidade e ter a certeza de que o cdigo implementado funciona, atendendo necessidade descrita no teste. Segundo BECK, todas as vezes que algum toma uma deciso e no a testa, a probabilidade dessa deciso estar incorreta praticamente 100%. Ele tambm acredita que as funcionalidades que no podem ser expressadas atravs de testes automatizados simplesmente no existem. Esta tcnica possui um ciclo conhecido como Ciclo do TDD. Nele tem que sempre escrever um teste que apresente falha. Em seguida, escrever um cdigo da maneira mais simples que faa o teste ser bem sucedido. Por fim, refatorar esse cdigo escrito fazendo com que o mesmo fique o mais simples e compreensvel. Como a maioria das ferramentas de teste retornam verde quando o teste passa e vermelho quando o mesmo falha, diz-se que este ciclo baseado em trs passos: RED/GREEN/REFACTOR. Seguindo esse ciclo, o desenvolvedor cria regras de melhoria do cdigo que facilitam exponencialmente a harmonia da equipe e a qualidade do cdigo como um todo. Rodando sempre os testes e criando cdigo baseado num teste j criado, tem-se segurana de que o cdigo gerado atende real necessidade do teste e no afeta outras reas do sistema. Tendo uma aplicao sobre 100% de cobertura de testes, pode-se afirmar que ela est bem estruturada e supostamente sem bugs que podem gerar resultados inesperados quando colocada em produo. Essa tcnica passou a ser difundida por um dos signatrios do movimento gil, Kent Beck, que, atravs da Programao Extrema [BECK 04], comeou a implementar o TDD na prtica em equipes de desenvolvimento de software. Alm do ciclo do TDD temos segundo Martin [MART 09], trs leis:

1. No se pode escrever cdigo antes de ter um teste falhando. 2. No se pode escrever mais teste se o teste j escrito ainda falha e no compila. 3. No se pode escrever cdigo alm do necessrio para fazer o teste passar.

Segundo Beck, devem-se seguir o ciclo do TDD com passos de beb, ou seja, um passo errado no entendimento ou seguimento do ciclo pode prejudicar todo o processo. Se uma funcionalidade muito complexa e pensar em um teste pra ela mais difcil do que escrever diretamente o cdigo para execut-la, necessrio pensar na menor parte da funcionalidade, ou seja, a mais simples possvel e ir incrementando a mesma bem devagar at ter entendido e especificado atravs do teste o comportamento esperado.

36

O lado positivo do TDD alm do ganho em produtividade devido baixa correo de bugs, a facilidade de ter cdigo autoexplicativo atravs dos testes para novos desenvolvedores. Atualmente quando se quer saber a funcionalidade de uma gem em Rails ou de algum cdigo do prprio framework, os desenvolvedores lem os testes e, por eles, j entendem o comportamento do cdigo que coberto por aquele teste. importante frisar que uma alterao no framework sem testes no aceita pelo ncleo do Rails. Devido a essa exigncia, o cdigo do Rails, mesmo depois de anos sendo modificado e sendo utilizado por milhares de desenvolvedores em todo o mundo, continua bem escrito e 100% coberto por testes, assegurando seu bom funcionamento.

Figura 4.7 Ciclo do TDD, http://reddevnews.com/articles/2007/11/01/testdriven-development-tdd.aspx, 2011

4.3 Behavior Driven Development


Enquanto TDD baseia-se no desenvolvimento guiado por testes, BDD baseia-se na descrio do comportamento da aplicao baseado na opinio dos clientes. Baseados nessa descrio pode-se afirmar que BDD necessita de um entendimento completo do mundo da aplicao baseado no ponto

37

de vista dos clientes (stakeholders1) para entregar algo til. preciso entender o domnio que a aplicao ser aplicada, os desafios e oportunidades que eles enfrentam e as palavras que eles costumam usar para descrever o comportamento que eles querem da aplicao. [CHE 10] BDD foi concebido em 2003 por Dan North em resposta ao TDD de Kent Beck. Uma das grandes diferenas de um para o outro que no BDD podemos utilizar a nossa lngua nativa para especificar os comportamentos. Isso permite aos desenvolvedores focar diretamente em como criar o software e a funcionalidade, ao invs de detalhes tcnicos da ferramenta ou da linguagem. Algo interessante que com ele possvel tornar os testes compreensveis por usurios e clientes, bem como utilizar as prprias especificaes destes testes para descrever as funcionalidades na ferramenta de testes comportamentais. Dan North criou o primeiro framework em Java, o Jbehave, seguido do Rbehave que o anterior portado para Ruby.

4.3.1 Os Princpios do BDD


Alguns profissionais que trabalham com BDD afirmam que praticar essa metodologia o mesmo que escrever software que realmente vale a pena, porque ele se baseia inteiramente no que os clientes querem.

Os trs princpios, segundo Chelimsky so:

1. O suficiente suficiente: Designs gigantescos, anlises interminveis. Deve-se fazer o menos possvel para comear e, qualquer coisa alm disso, um desperdcio. Isso tambm ajuda a pensar em sempre automatizar as tarefas repetitivas como deploy e build; 2. Entregar algo de valor: Se a pessoa est fazendo algo que no tem valor ou no est aumentando sua habilidade de entregar valor, pare e faa outra coisa; 3. Tudo comportamento: Independente se em nvel de codificao, aplicao ou algo alm, deve-se sempre usar o mesmo pensamento e linguistica de construo para descrever comportamento em qualquer nvel de granularidade.

Parte interessada no projeto.

38

4.4 Rspec
O RSpec uma DSL (Domain-Specific Language) para especificar o comportamento desejado do cdigo Ruby. O mais interessante que scripts do RSpec (specs) podem ser bem mais legveis que os prprios testes unitrios, permitindo que o autor consiga expressar suas intenes relacionadas ao cdigo de uma forma mais simples e expressiva, tornando a leitura dos testes e do cdigo uma tarefa fcil. Scripts do Rspec so colees de comportamentos, que, por sua vez, tem colees de exemplos. O mtodo describe cria um objeto com comportamentos. O comportamento configura o contexto para um conjunto de especificaes definidas com o mtodo with, onde deve ser passada uma sentena para descrever o contexto que ser especificado. Rspec pode ser usado para especificar testes de modelos e controladores, assim como tambm pode ser usado para teste de visualizao e integrao. Isso significa que, dominando este framework, o profissional tem uma ferramenta que atende todas as necessidades de cobertura de testes tanto para uso somente com TDD como BDD. Algumas palavras chaves so usadas para definir utilizao do framework. So elas: Subject Code: O cdigo cujo comportamento est sendo especificando com o RSpec; Expectation: Uma expresso de como o subject code deve se comportar; Code Example: Um exemplo executvel de como o subject code pode ser usado e como o seu comportamento esperado (expresso com expectations) em um determinado contexto; Example group : Grupo de code examples.

4.4.1 Descrevendo Comportamentos


Rspec prov uma DSL para especificao do comportamento de objetos. Isso abraa a metfora de descrever o comportamento da mesma forma que o expressamos se estamos conversando com um cliente ou outro desenvolvedor. Um exemplo disso poderia ser algo como:

Voc: Descreva uma conta. Algum: Deve ter um saldo de R$ 0

Pode-se expressar essa conversa em RSpec da seguinte forma: 39

Describe Uma nova conta do It deveter um saldo de 0 reais do Conta = Conta.new conta.saldo.should == Money.new(0, :real) end end

Figura 4.8 Exemplo de Describe no RSPEC

Usa-se o mtodo describe para definir um grupo de exemplo. A string que passada para ele especifica o que queremos descrever (uma nova conta). O mtodo it define o cdigo de exemplo. A string passada para ele descreve o comportamento que se deseja especificar sobre essa condio (deve ter um saldo de 0 (zero) reais). Assim como o describe, o mtodo context serve como um apelido para o mtodo anterior, podendo assim utilizar os dois relacionados, ou seja, o primeiro mais utilizado para descrever coisas e o segundo para descrever o prprio contexto da coisa a ser especificada.

describe Conta do context sendo nova do It deve ter saldo 0 do end end end

Figura 4.9 Exemplo de Describe com Context e It

Resumindo, escrevendo com describe, context e it possvel especificar de uma maneira mais abrangente o teste em RSpec, possibilitando que o seu resultado possa ser utilizado como documentao. Um exemplo de sada do resultado do Rspec seria:

Conta Sendo nova Deve ter saldo 0

Figura 4.10 Exemplo de sada formatada do Rspec 40

Como observado, as especificaes geradas pelo RSpec servem perfeitamente para uma futura documentao do sistema.

4.4.2 Exemplos Pendentes

No livro Teste Driven Development: By Example [BECK, 02], o autor fala sobre fazer uma lista de testes para um determinado objeto. Isso permite que um desenvolvedor determine os comportamentos da aplicao como um todo, auxiliando na abstrao e nas futuras dependncias que podem existir. Para que um teste no implementado interrompa o fluxo da sute de testes, podemos apenas marc-lo com pendente. Com o Rspec pode-se facilmente criar testes pendentes, basta apenas usar o mtodo it sem o bloco:

Describe Conta do it deve ter limite de 100 reais end

Figura 4.11 Exemplo Teste RSpec Pendente

Teria como sada:

Conta deve ter limite de 100 reais (PENDING: Not Yet Implemented) Pending: deve ter limite de 100 reais # Not Yet Implemented

Finished in 0.00191 seconds 3 examples, 0 failures, 1 pending

Figura 4.12 Sada Rspec Teste Pendente

Sempre que so adicionados testes pendentes lista de exemplos pendentes, ao executar o Rspec, so mostrados quantos testes comportamentais so necessrios descrever para terminar. Caso seja necessrio escrever algum teste que ser elaborado em outro momento, deve-se 41

escrever o titulo do teste e no corpo do mesmo colocar a notao pending.

describe Conta do context sendo nova do It deve ter saldo 0 do Pending(Implementar mais tarde)do end end end end

Figura 4.13 Teste Rspec Pendente com mensagem personalizada 4.4.3 Before, After, Specify, Let

Como existe nos testes unitrios o setup e o teardown, em Rspec pode-se utilizar mtodos que realizam a mesma funcionalidade. Estes testes so conhecidos como Before e After. Se for necessrio instanciar um objeto para ser usado em cada teste comportamental descrito no describe, deve-se faz-lo individualmente ou, simplesmente, declar-lo dentro de um bloco before. Caso precise limpar o ambiente depois de terminado o teste basta declarar algo em after. possvel ter dentro de um describe vrios mtodos it. utilizando um mtodo before ou after, isso prepara o objeto para ser utilizado em todos os mtodos it. Caso seja necessrio especificar apenas para um it, pode-se utilizar o before(:each) ou o after(:each). [CHE,2011] Quando as asseres conseguem expressar aquilo a que elas correspondem apenas ao ler o cdigo Ruby especificado, no necessrio utilizar o mtodo it. Neste caso, pode-se utilizar o seu apelido chamado specify. Com o specify, a prpria assero utilizada como descrio do comportamento descrito, conforme o exemplo a seguir:
describe BlogPost do before { @blog_post = BlogPost.new :title => 'foo' } it "should not be published" do @blog_post.should_not be_published end end

Figura 4.14 Teste Rspec com It para descrever o comportamento 42

describe BlogPost do let(:blog_post) { BlogPost.new :title => 'foo' } specify { blog_post.should_not be_published } end

Figura 4.15 Teste Rspec com let e Specify

Como possvel observar, a string no mtodo it simplesmente representa em ingls a mesma coisa que a assero dentro deste mtodo. Sendo assim, ao utilizar o conceito de DRY e evitar a duplicao de cdigo, pode-se escrever apenas a assero dentro do bloco esperado pelo mtodo speficy. possvel perceber ainda que o let foi usado no segundo exemplo. Este mtodo consegue ter um papel parecido com o before, mas carregando o objeto de uma forma mais legvel e performtica. [FERNA 11]

4.5 Cucumber

O Cucumber um framework de alto nvel para testes automatizados. Mais utilizado para testes de aceitao, ele permite descrever uma estria e implementar o cdigo de acordo com essa estria. Ele considerado um framework de alto nvel porque, diferentemente do Rspec, no utiliza apenas cdigo Ruby em sua descrio de funcionalidades, mas utiliza a linguagem plena como, por exemplo, o ingls. Por conveno, mais adequado utilizar o ingls para uma leitura universal do cdigo. O framework se preocupa em testar o comportamento da aplicao mais no nvel de usurio. Existe uma grande diferena de testar uma funcionalidade isolada com o Rspec e testar a funcionalidade com o Cucumber. Este ltimo faz algo muito parecido com o que antes era chamado de teste de caixa preta, ou seja, testar o comportamento da aplicao, como ela reage e qual sua resposta sem saber em certo qual o cdigo responsvel por este comportamento. Alguns desenvolvedores dizem que ele serve mais para auxiliar a comunicao do desenvolvedor com o cliente e vice-versa. Por ser texto claro, determinar uma funcionalidade no Cucumber para algum que no conhece linguagem de programao torna-se algo possvel. A forma como se pode organizar o pensamento de fcil entendimento para ambas as partes. correto afirmar que os testes com o framework no substituem os testes com o Rspec e os unitrios. Testes feitos com Rspec, mas que 43

testam uma funcionalidade separada so considerados testes de unidade, pois testam uma nica classe ou mtodo. [CHE 10] Como j foi mencionado, para criar qualquer tipo de funcionalidade devem ser seguir alguns passos finitos. Estes tambm podem ser chamados de User Stories. Em BDD, para determinarmos o escopo da nossa estria, utilizamos algumas palavras chaves: Dado que (o estado atual das coisas) Deseja-se fazer algo (a ao) Para que se consiga algo (o resultado ou objetivo) Para facilitar o entendimento de como o Cucumber trabalha com texto puro e o transforma em especificaes que devem ser implementadas, observa-se um exemplo de uma funcionalidade (cenrio) implementada:

Feature: Products registration In order to control my products As a system's user I want to be able to manage the products registration

Scenario: Creating a new product Given I visit the new product page When I fill the new product form with Foobar as description and 10.00 as the price And click on the 'Create' button Then the number of existent products should be increased by one And I should be sent to the new product's page

Figura 4.16 Exemplo de Cenrio em Cucumber Fonte: cassiomarques.wordpress.com.br

Como se pode observar, tem-se uma funcionalidade exigida pelo cliente que deve compor o sistema, ou seja, o sistema deve ser capaz de registrar um produto. Determinando a funcionalidade, so utilizados os passos que foram descritos anteriormente para compor a estria. Tem-se um breve resumo do que a funcionalidade faz: Para que possa controlar os produtos, um usurio do sistema deve ser capaz de gerenciar o cadastro de produtos. Cenrio: Dado que estou visitando a pgina de 44

novo produto, quando preencher o formulrio do produto com Foobar na descrio e 10 como preo, e clicar no boto criar, ento o nmero de produtos deve aumentar em um e deve-se ir para a pgina de novos produtos. Este arquivo deve ser salvo com a extenso feature para que o framework o entenda o como sendo uma funcionalidade. observado que na criao dessa funcionalidade utiliza-se algumas palavras chaves do framework: Feature: Define a funcionalidade do sistema. Pode conter um ou mais cenrios. Logo aps o titulo da feature deve-se escrever uma breve descrio sobre o que aquela funcionalidade far; Scenario: Define um possvel cenrio da aplicao. Nele feita descrio de uma das possveis user stories, alm de possibilitar testes como a aplicao deve se comportar nesse momento, ou seja, o que ela deve fazer e quais resultados deve exibir; Given: Usado para determinar o estado da aplicao no momento que o teste executado; When: Usado para especificar as aes a serem executadas; Then: Usado para especificar o resultado esperado. And: Usa-se como adendo, podendo unir vrios Given/When/Then. Para que os testes possam ser lidos pelo Cucumber, preciso seguir estritamente esses passos de criao das especificaes. Vale a pena ressaltar que o mesmo pode ser utilizado em vrios idiomas, inclusive em Portugus.

45

5. ESTUDO DE CASO

Este estudo de caso visa prtica dos conceitos abordados nesse material. Uma aplicao em Ruby on Rails ser construda baseada em testes com as ferramentas utilizadas como exemplo para composio dessa monografia.

5.1 Ambientao
Sabe-se que a Internet tem crescido sobremaneira nos ltimos tempos. Devido a esse espantoso crescimento, as aplicaes na Internet tem se popularizado em todo o mundo. Hoje no se fala mais com freqncia sobre criar aplicaes desktop que tenha um servidor e rode em apenas algumas mquinas em rede, mas utilizam-se termos como SaaS (Software as a Service) e Cloud Computing (computao em nuvem). Devido ao constante uso da internet como meio de unir pessoas em diversas parte do mundo, percebeu-se que poderia ser utilizado um software de coordenao de instrutores da polcia militar para agendar formaturas e cadastrar turmas.

5.2 PROERD
O Programa Educacional de Resistncia s Drogas (PROERD) da Polcia Militar do Estado do Rio de Janeiro constitui uma medida preventiva, complementar s aes de represso ao uso indevido e trfico de drogas no Estado do Rio de Janeiro, sendo uma forma de atuao da Corporao voltada para a preveno ao consumo de drogas e violncia contra e entre crianas e adolescentes.

5.2.1 Origem
O PROERD teve por base o Projeto D.A.R.E (Drug Abuse Resistance Education), inicialmente desenvolvido e aplicado pelo Departamento de Polcia e Distrito Escolar Unificado da Cidade de Los Angeles/EUA, adaptado realidade brasileira pelo Centro de Capacitao PROERD/PMERJ. Atravs de curso realizado no ano de 1992 no Rio de Janeiro por profissionais do projeto D.A.R.E., acima mencionado, deu-se incio as atividades do programa se estendendo por todo o pas, levando uma mensagem s nossas crianas de como podero resistir s drogas e violncias.

46

5.2.2 Propsito

O Programa Educacional de Resistncia s Drogas - PROERD consiste em um esforo cooperativo da Polcia Militar, Escola e Famlia para oferecer atividades educacionais em sala de aula, a fim de prevenir o abuso de drogas e violncia entre crianas e adolescentes. A nfase do plano de estudos est em auxiliar os estudantes a reconhecerem e resistirem s presses diretas ou indiretas que podero influenci-los a experimentar lcool, cigarro, maconha, inalantes, outras drogas ou se engajarem em atividades violentas. O Programa oferece estratgias preventivas para reforar os fatores de proteo, em especial os referentes famlia, escola e comunidade, facilitando o desenvolvimento de habilidades de resistncia em jovens que poderiam correr o risco de envolver-se com drogas e problemas de comportamento. Pesquisadores identificaram fatores protetores ligados famlia, escola e comunidade, os quais fortalecem essa resilincia nos jovens; em outras palavras, a capacidade de crescerem de forma independente e saudvel apesar de condies adversas. Esta estratgia concentra-se no desenvolvimento das mltiplas competncias, habilidades de comunicao, auto-estima, empatia, tomada de decises, resoluo de conflitos, objetivo de vida, independncia, alternativas positivas ao uso de drogas ou a outros comportamentos destrutivos.

5.3 Objetivo da aplicao


A aplicao tem como objetivo atender as necessidades da coordenao do curso, ou seja, o usurio deve ser capaz de cadastrar os instrutores e as turmas desses instrutores. Sabendo que o objetivo principal dessa aplicao, alm de atender a necessidade do cliente, demonstrar para ns como o percurso de testes de uma aplicao que comea do zero. No final da implementao do sistema, o sistema permite o cadastro de instrutores, escolas e turmas, especificar por cidade quais escolas e turmas pertencem a cada instrutor e ter a marcao de formaturas para as turmas de cada instrutor. Todo o sistema protegido por login e senha. O mesmo est hospedado em uma VPS e ter seu cdigo disponibilizado no github.

47

5.4 Implementao
5.4.1 Ferramentas

Para a elaborao do sistema ser utilizado o ambiente de desenvolvimento num sistema operacional MACOS X, utilizando como IDE (Integrated Development Environment) o TextMate. Ser utilizada a linguagem abordada nessa monografia, Ruby, com o framework Rails. Para efetuar os testes em alguns dos controladores da aplicao, sero utilizados o RSpec e o Cucumber. Basicamente ser criada a funcionalidade de login do sistema, junto com o cadastro de instrutores e turmas. O real objetivo dessa abordagem de um estudo de caso no para criar uma aplicao, tanto que alguns dados como diagramas do mesmo sero ocultados aqui. O objetivo aqui demonstrar com esse pequeno exemplo o uso prtico dos frameworks de teste estudados, alm de validar tudo o que foi dito nessa monografia. Sero iniciados testes de modelos, controladores e view com o RSpec, com os mesmos os testes sendo feitos com o Cucumber. Como o software possui vrias entidades e features, ser utilizada para exemplo a funcionalidade Turmas, como adicion-la com Rspec e cucumber.

5.4.2 - Testes com Rspec e Cucumber


Para que possa ser utilizado o cucumber e o rspec em um projeto rails, deve-se editar o Gemfile com as seguintes linhas:
group :development, :test do gem "rake", "0.8.7" gem "rspec-rails", "2.5.0", :group => [:development, :test] gem "factory_girl_rails", "1.1.beta1", :group => :test gem "cucumber-rails", "0.4.1", :group => :test gem "capybara", "0.4.1.2", :group => :test gem "database_cleaner", "0.6.7", :group => :test gem "launchy", "0.4.0", :group => :test gem "devise", "1.3.4" gem "shoulda" end

Figura 5.1 GemFile para testes

48

claro que para que exista o gemfile, um projeto rails deve ser criado. Para criar um projeto rails basta digitar o comando rails new nomedaaplicacao. Depois do mesmo criado e do gemfile com as linhas anteriores, roda-se o comando bundle install para baixar para a mquina todas as gems que foram especificadas no arquivo. Depois de baixadas as gems, pode iniciar o uso dos frameworks. Ser criado os testes para a classe Team.rb e ser feito TDD em cima desse passo a passo. Primeiramente deve rodar os comandos:
rails generate rspec:install rails generate cucumber:install

Figura 5.2: Comandos de instalao Aps ter instalado os frameworks, a aplicao j est pronta para utilizar os helpers e expectations. Sendo criados modelos atravs dos geradores do rails, automaticamente criado os specs do Rspec. Para dar inicio ao testes, deve-se criar por escolha do trabalho, uma feature do cucumber, basta criar um arquivo com a extenso feature.

Feature: teams registration In order to control the teams As a system's user I want to be able to manage the team registration Scenario: Given I am a user named "foo" with an email "user@test.com" and password "please" When I sign in as "user@test.com/please" Then I should be signed in And I visit the new team page When I fill the new team form with "Veiga de Almeida" as name And click on the 'Create' button And I should see the message Team created sucessfully

Figura 5.3 : team.feature

Aps a criao desse arquivo, ao ser executado o comando rake cucumber, o terminal retornar os seguintes passos:

49

Given /^I visit the new team page$/ do pending end When /^I fill the new team form with "(.*)" as name$/ do |name| pending end When /^click on the 'Create' button$/ do pending end When /^I should see the message Team created sucessfully$/ do pending end Given /^that I have created a team "([^"]*)"$/ do |team| pending end

Figura 5.4: Team steps Pendentes Esses so os passos que o cucumber retorna para que o desenvolvedor implemente as funcionalidades. Para que o teste possa passar com sucesso, devemos criar uma rota para visitar ao querer adicionar um novo Team. Para isso basta ir em routes.rb e adicionar o resources para team. Para preencher o formulrio, deve-se criar um formulrio new.html.erb, com os campos para preenchimento do nome da turma, e um boto chamado create. O redirecionamento ser feito pela action create para o ndex com um flash notice dizendo que foi criado com sucesso. Para efetuar todos esses passos, deve-se criar o controlador team_controller.rb e o modelo Team.rb. Sabendo o que deve ser feito basta adicionar os passos que esto no arquivo a seguir:
Given /^I visit the new team page$/ do visit('/teams/new') end When /^I fill the new team form with "(.*)" as name$/ do |name| @actual_count = Team.count fill_in "name", :with => name end When /^click on the 'Create' button$/ do click_button("Create") end When /^I should see the message Team created sucessfully$/ do Then %{I should see "Team created sucessfully"} end Given /^that I have created a team "([^"]*)"$/ do |team| Team.create(:name => "cool team") end

Figura 5.5: Team steps 50

class TeamsController < ApplicationController before_filter :authenticate_user! def index @teams = Team.all end def new @team = Team.new end def create @team = Team.new(params[:team]) if @team.save flash[:message] = "Team created sucessfully" redirect_to @team else redirect_to :action => 'new' end end def show @team = Team.find(params[:id]) end def edit @team = Team.find(params[:id]) end end

Figura 5.6: Controlador Team Os testes do rspec sero em cima do modelo aqui demonstrado por team.rb. Como foi feito o teste pelo cucumber antes, o modelo j existe devido a criao pelo gerador do rails. Utilizando o mesmo, o rspec j cria o arquivo de teste para tal modelo, chamado team_spec.rb. Basta utilizar o shoulda que est no gemfile como helper e adicionar tais validaes ao spec:

require 'spec_helper' describe Team do before(:each) do @team = Factory(:team) end it {should validate_presence_of :name} it {should validate_uniqueness_of :name} it {should belong_to :user } end

Figura 5.7: team_spec.rb O modelo deve ficar da seguinte forma:

51

class Team < ActiveRecord::Base validates_presence_of :name validates_uniqueness_of :name belongs_to :user end

Figura 5.8: Team model E nesse momento os testes devem estar todos passando. A entidade est devidamente testada, e os mtodos coberto por testes para garantir que fazem aquilo que propem que seja feito.

52

6. CONSIDERAES FINAIS
6.1 Concluses Existe uma variedade de novos sistemas surgindo no mercado e com o advento da Internet o uso de programas atravs do navegador tem se tornado a cada dia algo mais comum. Com a facilidade de criar um software com alguma linguagem gil para desenvolvimento web, a quantidade de aplicativos para computadores e dispositivos portteis aumentou exponencialmente nos ltimos cinco anos. Com o surgimento do framework Ruby on Rails e com todas as facilidades que o mesmo trouxe para o desenvolvimento de aplicativos, pode-se encontrar vrios aplicativos novos em toda a rede. Aplicativos tais que tomaram o mercado de uma maneira espantosa. O Twitter, por exemplo, pode ser mencionado como caso de sucesso. Ruby on Rails tambm prega a conduta de compartilhamento de cdigo entre a comunidade, pois ele prprio surgiu da iniciativa de um jovem em compartilhar seu framework pessoal com a comunidade. Disto pode-se tirar o motivo desse trabalho. Como gerenciar um framework utilizado por milhares de desenvolvedores e atualizado pelos mesmos sem que haja uma fuga do padro de cdigo ou de sua qualidade? A resposta clara e vem com o manifesto gil, o XP e o prprio framework. Testes automatizados no somente nos auxiliam a cuidar da esttica do cdigo, como tambm permite produzir cdigo compreensvel por seres humanos. A programao em par pregada pela programao extrema nos motiva a sempre escrever cdigo para que outra pessoa o entenda e que esse cdigo seja to simples a ponto de qualquer programador conseguir l-lo. O manifesto gil veio para mostrar para os engenheiros de software e para as grandes corporaes que para desenvolver software no era necessrio tantos passos complexos e desnecessrios, e que o cliente gostaria mesmo de ver o programa atendendo sua necessidade. Utilizando testes automatizados pode-se garantir que o software que esta sendo escrito realmente atende a necessidade estabelecida pelo cliente. Quando se escreve cdigo com teste, realmente este est terminado. Foi possvel ver como utilizar testes unitrios e como fazer TDD. TDD uma regra de vida do programador que pretende melhorar seu cdigo continuamente. O ciclo do TDD como uma doutrina a ser seguida e aperfeioada a cada dia. Foi observado tambm que a participao dos clientes na especificao e criao do software algo essencial. Quando utiliza-se BDD pode-se simplesmente, com o auxilio do cliente, 53

determinar funcionalidades e cenrios na prpria lngua nativa do cliente, o que garante que ser feito com que a aplicao corresponda igualitariamente especificao feita pelo proprietrio do software. O Cucumber e o Rspec so frameworks de BDD e que facilitam o uso dessa tecnologia em Ruby on Rails, comprovando o quo fcil e produtivo utilizar esta tecnologia para melhorar constantemente a produo do cdigo e desenvolvimento do software. Por fim, foram implementadas algumas funcionalidades de um software de exemplo para mostrar como deve-se trabalhar para a composio dos testes sendo eles unitrios, funcionais ou de integrao. Foram utilizados os frameworks mencionados nesta monografia e foi obtido sucesso nos testes e, conseqentemente, na implementao do software. Portanto esse trabalho servir como um facilitador no aprendizado de testes automatizados em Ruby on Rails para futuros programadores.

6.2 Trabalhos Futuros Como o sistema abordado nessa monografia no foi concludo, como trabalho futuro, pretende-se termin-lo para que o mesmo entre em produo e atenda a necessidade do cliente, to como sirva de portflio e consulta de com realizar testes em Ruby On Rails.

54

ANEXO A CODIGO FONTE


require 'spec_helper' describe HomeController do describe "GET 'index'" do it "should be successful" do get 'index' response.should be_success end end end

home_controller_spec.rb

require 'spec_helper' describe UsersController do before (:each) do @user = Factory(:user) sign_in @user end describe "GET 'show'" do it "should be successful" do get :show, :id => @user.id response.should be_success end it "should find the right user" do get :show, :id => @user.id assigns(:user).should == @user end

users_controller_spec.rb

55

require 'spec_helper' describe TeamsController do before (:each) do @user = Factory(:user) sign_in @user end it 'should have a new page' do get :new response.should be_success end it 'should have an index page' do get :index response.should be_success request.flash.should be_empty end it 'should create an team' do expect {post :create, :team => Factory.attributes_for(:team)}.to change(Team, :count).by(1) response.should redirect_to(Team.last) end context 'when manipulating teams' do let(:team) {Factory :team} it 'should show an team' do get :show, :id => team response.should be_success end it 'should be able to edit an team' do get :edit, :id => team response.should be_success end it 'should be able to successfully update an team' do put :update, :id => team, :team => {:name => "Estacio"} response.should be_redirect end it 'should be able to successfully delete an team' do delete :destroy, :id => team response.should redirect_to(teams_path) end end

Teams_controller_spec.rb

56

require 'spec_helper' describe Team do before(:each) do @team = Factory(:team) end it {should validate_presence_of :name} it {should validate_uniqueness_of :name} it {should belong_to :user } end end end

team_spec.rb
require 'spec_helper' describe User do before(:each) do @attr = { :name => "Example User", :email => "user@example.com", :password => "foobar", :password_confirmation => "foobar" } end it "should create a new instance given a valid attribute" do User.create!(@attr) end it "should require an email address" do no_email_user = User.new(@attr.merge(:email => "")) no_email_user.should_not be_valid end it "should accept valid email addresses" do addresses = %w[user@foo.com THE_USER@foo.bar.org first.last@foo.jp] addresses.each do |address| valid_email_user = User.new(@attr.merge(:email => address)) valid_email_user.should be_valid end end it "should reject invalid email addresses" do addresses = %w[user@foo,com user_at_foo.org example.user@foo.] addresses.each do |address| invalid_email_user = User.new(@attr.merge(:email => address)) invalid_email_user.should_not be_valid end end it "should reject duplicate email addresses" do User.create!(@attr) user_with_duplicate_email = User.new(@attr) user_with_duplicate_email.should_not be_valid end

57

it "should reject email addresses identical up to case" do upcased_email = @attr[:email].upcase User.create!(@attr.merge(:email => upcased_email)) user_with_duplicate_email = User.new(@attr) user_with_duplicate_email.should_not be_valid end describe "passwords" do before(:each) do @user = User.new(@attr) end it "should have a password attribute" do @user.should respond_to(:password) end it "should have a password confirmation attribute" do @user.should respond_to(:password_confirmation) end end describe "password validations" do it "should require a password" do User.new(@attr.merge(:password => "", :password_confirmation => "")). should_not be_valid end it "should require a matching password confirmation" do User.new(@attr.merge(:password_confirmation => "invalid")). should_not be_valid end it "should reject short passwords" do short = "a" * 5 hash = @attr.merge(:password => short, :password_confirmation => short) User.new(hash).should_not be_valid end end describe "password encryption" do before(:each) do @user = User.create!(@attr) end it "should have an encrypted password attribute" do @user.should respond_to(:encrypted_password) end

user_spec.rb 58

require 'factory_girl' Factory.define :user do |u| u.name 'Test User' u.email 'user@test.com' u.password 'please' end Factory.define :team do |t| t.name 'Veiga de Almeida' end

factories.rb

Feature: home As a user I want to see the teams link to go to the team list page Scenario: Go to the team list page Given I visit the home page When I click on Teams link Then should go to the team list page

home.feature

Feature: Teams In order to keep track of teams People should be able to Create a list of teams Scenario: List teams Given I am a user named "foo" with an email "user@test.com" and password "please" When I sign in as "user@test.com/please" Then I should be signed in Given that I have created a team "cool team" When I go to the teams page Then I should see "cool team"

teamlist.feature

59

Feature: Sign in In order to get access to protected sections of the site A user Should be able to sign in Scenario: User is not signed up Given I am not logged in And no user exists with an email of "user@test.com" When I go to the sign in page And I sign in as "user@test.com/please" Then I should see "Invalid email or password." And I go to the home page And I should be signed out Scenario: User enters wrong password Given I am not logged in And I am a user named "foo" with an email "user@test.com" and password "please" When I go to the sign in page And I sign in as "user@test.com/wrongpassword" Then I should see "Invalid email or password." And I go to the home page And I should be signed out Scenario: User signs in successfully with email Given I am not logged in And I am a user named "foo" with an email "user@test.com" and password "please" When I go to the sign in page And I sign in as "user@test.com/please" Then I should see "Signed in successfully." And I should be signed in When I return next time Then I should be already signed in

sign_in.feature

Feature: Show Users As a visitor to the website I want to see registered users listed on the homepage so I can know if the site has users Scenario: Viewing users Given I am a user named "foo" with an email "user@test.com" and password "please" When I go to the homepage Then I should see "User: foo"

user_show.feature

60

Feature: Sign out To protect my account from unauthorized access A signed in user Should be able to sign out Scenario: User signs out Given I am a user named "foo" with an email "user@test.com" and password "please" When I sign in as "user@test.com/please" Then I should be signed in And I sign out Then I should see "Signed out" When I return next time Then I should be signed out

sign_out.feature

Feature: Edit User As a registered user of the website I want to edit my user profile so I can change my username Scenario: I sign in and edit my account Given I am a user named "foo" with an email "user@test.com" and password "please" When I sign in as "user@test.com/please" Then I should be signed in When I follow "Edit account" And I fill in "Name" with "baz" And I fill in "Current password" with "please" And I press "Update" And I go to the homepage Then I should see "User: baz"

user_edit.feature
Feature: teams registration In order to control the teams As a system's user I want to be able to manage the team registration Scenario: Given I am a user named "foo" with an email "user@test.com" and password "please" When I sign in as "user@test.com/please" Then I should be signed in And I visit the new team page When I fill the new team form with "Veiga de Almeida" as name And click on the 'Create' button And I should see the message Team created sucessfully

team.feature 61

Feature: Sign up In order to get access to protected sections of the site A user Should be able to sign up Scenario: User signs up with valid data Given I am not logged in When I go to the sign up page And I fill in "Email" with "user@test.com" And I fill in "Password" with "please" And I fill in "Password confirmation" with "please" And I press "Sign up" Then I should see "Welcome! You have signed up successfully." Scenario: User signs up with invalid email Given I am not logged in When I go to the sign up page And I fill in "Email" with "invalidemail" And I fill in "Password" with "please" And I fill in "Password confirmation" with "please" And I press "Sign up" Then I should see "Email is invalid" Scenario: User signs up without password Given I am not logged in When I go to the sign up page And I fill in "Email" with "user@test.com" And I fill in "Password" with "" And I fill in "Password confirmation" with "please" And I press "Sign up" Then I should see "Password can't be blank" Scenario: User signs up without password confirmation Given I am not logged in When I go to the sign up page And I fill in "Email" with "user@test.com" And I fill in "Password" with "please" And I fill in "Password confirmation" with "" And I press "Sign up" Then I should see "Password doesn't match confirmation" Scenario: User signs up with password and password confirmation that doesn't match Given I am not logged in When I go to the sign up page And I fill in "Email" with "user@test.com" And I fill in "Password" with "please" And I fill in "Password confirmation" with "please1" And I press "Sign up" Then I should see "Password doesn't match confirmation"

sign_up.feature

62

Given /^I visit the new team page$/ do visit('/teams/new') end When /^I fill the new team form with "(.*)" as name$/ do |name| @actual_count = Team.count fill_in "name", :with => name end When /^click on the 'Create' button$/ do click_button("Create") end When /^I should see the message Team created sucessfully$/ do Then %{I should see "Team created sucessfully"} end Given /^that I have created a team "([^"]*)"$/ do |team| Team.create(:name => "cool team") end

teams_steps.rb
Given /^I visit the home page$/ do visit root_path end When /^I click on Teams link$/ do click_link "Teams List" end Then /^should go to the team list page$/ do visit teams_path end

home_steps.rb

63

Given /^no user exists with an email of "(.*)"$/ do |email| User.find(:first, :conditions => { :email => email }).should be_nil end Given /^I am a user named "([^"]*)" with an email "([^"]*)" and password "([^"]*)"$/ do |name, email, password| User.new(:name => name, :email => email, :password => password, :password_confirmation => password).save! end Given /^I am a new, authenticated user$/ do email = 'testing@man.net' login = 'Testing man' password = 'secretpass' Given %{I have one user "#{email}" with password "#{password}"} And %{I go to login} And %{I fill in "user_email" with "#{email}"} And %{I fill in "user_password" with "#{password}"} And %{I press "Sign in"} end Then /^I should be already signed in$/ do And %{I should see "Logout"} end Given /^I am signed up as "(.*)\/(.*)"$/ do |email, password| Given %{I am not logged in} When %{I go to the sign up page} And %{I fill in "Email" with "#{email}"} And %{I fill in "Password" with "#{password}"} And %{I fill in "Password confirmation" with "#{password}"} And %{I press "Sign up"} Then %{I should see "You have signed up successfully. If enabled, a confirmation was sent to your e-mail."} And %{I am logout} end Given /^I am logout$/ do visit('/users/sign_out') end When /^I sign in as "(.*)\/(.*)"$/ do |email, password| Given %{I am not logged in} When %{I go to the sign in page} And %{I fill in "Email" with "#{email}"} And %{I fill in "Password" with "#{password}"} And %{I press "Sign in"} end Then /^I should be signed in$/ do Then %{I should see "Signed in successfully."} end Then /^I sign out$/ do visit('/users/sign_out') end When /^I return next time$/ do And %{I go to the home page} end

64

Then /^I should be signed out$/ do And %{I should see "Sign up"} And %{I should see "Login"} And %{I should not see "Logout"} end Given /^I am not logged in$/ do visit('/users/sign_out') # ensure that at least end

user_steps.rb

65

REFERNCIAS BIBLIOGRFICAS
[BECK 04] BECK, Kent; Programao Extrema (XP) Explicada: Acolha as Mudanas. 1a Ed. Bookman, 2004. 184p. [FLAN 08] FLANAGAN, David; MATSUMOTO Yukihiro; The Ruby Programming Language.1a Ed. O'Reilly Media, 2008. [FOWL 05] FOWLER, Martin; Patterns Of Enterprise Architeture. 2005. [FERNA 10] FERNANDEZ, Obies; The Rails 3 Way.2a Ed. Addison-Wesley, 2010. [GUID 11] Ruby on Rails Guides.Disponvel em < http://guides.rubyonrails.org >.Acesso em 15/05/2011. [MANI 11] Manifesto gil Site. Disponvel em < http://manifestoagil.com.br >. Acessado em 15/05/2011 [PROERD 11] Proerd Site. Disponvel em < http://www.policiamilitar2.rj.gov.br/proerd.asp >. Acessado em 15/05/2011 [MART 09] MARTIN, Robert C.; Clean Code a HandBook of Agile Software Craftsmanship. Pearson, 2009. [FOWL 99] ______; BECK Kent; BRANT John; OPDYKE William; ROBERTS Don. Refactoring: Improving the Design of Existing Code. 2a Ed. Addison-Wesley, 1999. [THOM 04] THOMAS, David; FOWLER Chad, HUNT Andy; Programming Ruby: The Pragmatic Programmers' Guide. 2a Ed. Pragmatic Bookshelf, 2004. [FEAT 04] FEATHERS, Michael; Working Effectively with Legacy Code. 1a Ed. Prentice Hall, 2004 [BECK 02] BECK, Kent; Test Driven Development: By Example, 1a Ed. Addison-Wesley, 2002.

66

[FREE 09] FREEMAN, Steve; Pryce Nat; Growing Object-Oriented Software, Guided by Test; 1a Ed. Addison Wesley, 2009 [CHE 10] CHELIMSKY, David, et al. The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends. Pragmatic BookShelf, 2010. p.22 [RUBY 11] RUBY, Sam, THOMAS David, HANSSON David Heinemeier. Agile Web Development with Rails . 4a Ed. Pragmatic Bookshelf, 2011. [RAPP 11] RAPPIN, Noel. Rails Test Prescriptions. Pragmatic Programmers, 2011

67