Test-driven Development no Rails Começando seu projeto com o pé direito. 2007, Nando Vieira http://simplesideias.com.br



Documentos relacionados
Test-Driven Development no Rails: Unit Tests

Programação Web Aula 10 - Testes, Javascript, Ajax

Versão 0.1. Manual FoRc. Última Atualização: Maio/2007. Daniel Schmitz

Behaviour-Driven Development com RSpec e RSpec on Rails. Danilo Sato

Breve introdução. Uma breve introdução. Simplicidade e Poder. Rápido Dinâmico Robusto

Versão Manual FoRc. Última Atualização: Maio/2007. Daniel Schmitz

Exibindo o Catálogo (Tarefa C) Prof. Fellipe Aleixo (fellipe.aleixo@ifrn.edu.br)

Programação Orientada a Testes Rodrigo Rebouças de Almeida

Desenvolvimento Guiado por Testes

Lições Aprendidas sobre Testes

Entendendo Rails. Fabio Akita Surgeworks Brazil Rails Practice Manager

JSP: JAVA SERVER PAGES

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

Trilha Agile TDD e 20 coisas que você precisa saber

Desenvolvimento Dirigido por Testes (TDD)

JAVAWEB AULA 2 Prof. Daniela Pires Sumário

Programando em PHP. Conceitos Básicos

Luiz Arão Araújo Carvalho Bacharel em Ciência da Computação Desenvolvedor RedeSat-TO

Este software resolve todos esses problemas.adobe reader é um software free, para ler os arquivos pdf..

O CONCEITO DE TDD NO DESENVOLVIMENTO DE SOFTWARE

Começando com Ruby on

ASP Active Server Pages. ASP (Active Server Pages)

Construtor de sites SoftPixel GUIA RÁPIDO - 1 -

NetEye Guia de Instalação

LINGUAGEM DE PROGRAMAÇÃO WEB

Facebook Instruções de integração com PayPal

WEBDESIGN. Professor: Paulo Marcos Trentin - paulo@paulotrentin.com.br Escola CDI de Videira

JAVAWEB AULA 2 Prof. Daniela Pires Sumário

Scriptlets e Formulários

Introdução. Entendendo os Controles. Definindo um controle. Introdução MOCKDOMAIN() Testando uma classe de domínio mockdomain

TUTORIAL: MANTENDO O BANCO DE DADOS DE SEU SITE DENTRO DO DOMÍNIO DA USP USANDO O SSH!

Tutorial para hostear e/ou gerar missões para a GVV usando o BADC

Kobo Desktop. Manual do Usuário

II Semana de Tecnologia da Informação. Rails Framework

- Versão 1.0 Página 1

UNIVERSIDADE VEIGA DE ALMEIDA BACHARELADO EM SISTEMAS DE INFORMAÇÃO INTRODUÇÃO A TESTES AUTOMATIZADOS EM RUBY ON RAILS. Thiago Cifani Ayres Escola

VISUAL LIGHTBOX FERRAMENTA WEB DESIGN FABIANO KEIJI TAGUCHI

V1.1 SITE EM UM SITE 11/2015 MINUTOS APRENDA A PROGRAMAR IMAGINE FAZER O SEU PRIMEIRO PROGRAMA EM 180 SEGUNDOS

Linguagem de Programação III Aula 2 Revisão Parte II

RECURSOS DO WINDOWS FERRAMENTAS DO SISTEMA TAREFAS AGENDADAS SCANDISK DESFRAGMENTADOR DE DISCO LIMPEZA DE DISCO RESTAURAÇÃO DO SISTEMA

PASSO A PASSO: CRIAÇÃO DE PERSONAS

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

NetEye Guia de Instalação

Índice. 3 Capítulo 1: Visão Geral do Blog. 4 Capítulo 2: SEO. 5 Capítulo 3: Backend: Como Funciona. Visão Geral Plataforma Frontend Backend

Bruno Jurkovski Lucas Fialho Zawacki. Site do curso:

JSP: JAVA SERVER PAGES

Práticas de Desenvolvimento de Software

NOVIDADES DO JAVA PARA PROGRAMADORES C

Nos Trilhos com RAILS. Sylvestre Mergulhão

Passo-a-Passo para Criação de Conta no site Griaule e Download do Programa SDK e da Licença Fingerprint SDK 2009

Introdução ao TDD. Dionatan Moura. #guma10anos Abril de about.me/dionatanmoura

Desenvolvimento Dirigido por Testes (TDD)

PJCUS-361 CONTRATO COM CÓDIGO DE BARRAS

API REST Alimentação/Retorno

Parte I Tutorial Wi Fi 2.0 Arduino Exemplo usado: Webserver

A ferramenta que você necessitava para seu Buffet Infantil.

GUIA MUDANÇA E FORMATAÇÃO DE SERVIDOR - SLIM

mkdir /srv/www/default/html/calculadora/imagens mkdir /srv/www/default/html/calculadora/blocos

Guia de Instalação SIAM. Internet Information Services - IIS 5.1 no Windows XP Pro

43 11 Relatórios, Listagens e Exportações para Excel, TXT e HTML

Tutorial de Conversão Xvid/Divx para DVD com legendas embutidas Versão 1.00 Julho / 2005 por m0l0c0

XP extreme Programming, uma metodologia ágil para desenvolvimento de software. Equipe WEB Cercomp

Como instalar o Kobo Desktop para Windows Como instalar o Kobo Desktop para Mac Como classificar a sua biblioteca...

Table of Contents. PowerPoint XP

TUTORIAL WEEBLY. 2-Crie um cadastro (lembrando que palavra passe é a senha). Após preencher o formulário, clique em Sign Up. It s Free!

Tutorial Básico. Instalando e testando o Ruby on Rails no Windows

Sistemas Distribuídos Métodos de Invocação Remota II. Prof. MSc. Hugo Souza

Fox Gerenciador de Sistemas

15. OLHA QUEM ESTÁ NA WEB!

NOVO MODELO DE ATUALIZAÇÃO FOCCO Atualização automática com o FoccoUPDATE

Parte I. Demoiselle Mail

Capítulo 6. Delphi x Web x WebBroker. Primeiro Exemplo (Hello World)

Em 2 minutos de leitura você aprenderá facilmente a: Montar seu perfil Buscar colaboradores e comunidades Utilizar recursos

Testes de Software. Por quê testar? 3/28/2011. Andrew Diniz da Costa. Manter alta qualidade. Prevenir e encontrar defeitos

Testes de Software. Anne Caroline O. Rocha TesterCertified BSTQB NTI UFPB. Anne Caroline O. Rocha Tester Certified BSTQB NTI UFPB

4 O Workflow e a Máquina de Regras

Universo Online. Loja de Aplicativos - API v1.0 [05/2012]

Perguntas Freqüentes (FAQs)

GUIA INTEGRA SERVICES E STATUS MONITOR

Acessando um Banco de Dados

Passo a Passo. WebSphere Message Broker. Fluxo como WebService

DWEB. Design para Web. HTML5 - Marcação de formulário. Curso Superior de Tecnologia em Design Gráfico

Satélite. Manual de instalação e configuração. CENPECT Informática cenpect@cenpect.com.br

Auxiliar de instalação (Português Brasileiro) Primeiros passos

[MANUAL DE INTEGRAÇÃO PARA SITES DE MEMBROS]


Construindo portais com Plone. Módulo 3 Templates

Escrito por Daniel Donda Qui, 06 de Novembro de :21 - Última atualização Qui, 06 de Novembro de :47

Como atualizar os preços da ABCFarma.

Laboratório de Redes de Computadores e Sistemas Operacionais

Como criar uma conta gratuita e subir uma foto no Windows Azure

Material Didático sobre Robocode Tema: Criando Nosso Primeiro Robô

ETEC DR. EMÍLIO HENRNANDEZ AGUILAR PROGRAMAÇÃO DE COMPUTADORES II PROFESSOR RAFAEL BARRETO DELPHI FORMULÁRIO COM ABAS E BUSCAS DE REGISTROS

Criando Banco de Dados, Tabelas e Campos através do HeidiSQL. Prof. Vitor H. Migoto de Gouvêa Colégio IDESA 2011

Conceitos de Ajax Exemplos de uso do Ajax no braço, muitos exemplos, muito código (HTML, CSS, JavaScript, PHP, XML, JSON)

Software de Gerência de Dados de Música. Data Manager para Windows. Guia do Usuário

COMO INVESTIR PARA GANHAR DINHEIRO

Transcrição:

Test-driven Development no Rails Começando seu projeto com o pé direito 2007, Nando Vieira http://simplesideias.com.br

O que iremos ver? slides = Array.new slides << O que é TDD? slides << Por que testar slides << Um pequeno exemplo slides << TDD no Rails slides << Fixtures slides << Testes unitários slides << Testes funcionais slides << Testes de integração slides << Mocks & Stubs slides << Dúvidas?

O que é TDD? Test-driven Development ou Desenvolvimento Guiado por Testes Uma técnica de desenvolvimento de software Ficou conhecida como um aspecto do XP

O que é TDD? Kent Beck (TDD by Example, 2003): 1. Escreva um teste que falhe antes de escrever qualquer código 2. Elimine toda duplicação (refactoring) 3. Resposta rápida a pequenas mudanças 4. Escreva seus próprios testes

O que é TDD? Processo: 1. Escreva o teste 2. Veja os testes falharem 3. Escreva o código 5. Refatore o código 4. Veja os testes passarem

Porque testar Isso não me impediu de cometer a tresloucada loucura de publicar minha aplicação utilizando Rails 1.2.3 apenas um dia após o lançamento deles. Devo estar ficando doido mesmo. Ou isso ou tenho testes. Thiago Arrais Motiro, no Google Groups Ruby-Br

Porque testar Você: escreverá códigos melhores escreverá códigos mais rapidamente identificará erros mais facilmente não usará F5 nunca mais!

Um pequeno exemplo test_calculator.rb class TestCalculator < Test::Unit::TestCase def setup @calc = Calculator.new def teardown @calc = nil def test_sum assert_equal(2, @calc.sum(1, 1), "1 + 1 = 2") def test_subtract assert_equal(1, @calc.subtract(2, 1), 2-1 = 1") def test_multiply assert_equal(4, @calc.multiply(2, 2), 2 x 2 = 4") def test_divide assert_equal(2, @calc.sum(4, 2), 4 / 2 = 2") assert_raise(zerodivisionerror) { @calc.divide(2, 0) }

Um pequeno exemplo test_calculator.rb class TestCalculator < Test::Unit::TestCase def setup @calc = Calculator.new def teardown @calc = nil def test_sum assert_equal(2, @calc.sum(1, 1), "1 + 1 = 2") def test_subtract assert_equal(1, @calc.subtract(2, 1), 2-1 = 1") def test_multiply assert_equal(4, @calc.multiply(2, 2), 2 x 2 = 4") def test_divide assert_equal(2, @calc.sum(4, 2), 4 / 2 = 2") assert_raise(zerodivisionerror) { @calc.divide(2, 0) }

Um pequeno exemplo test_calculator.rb class TestCalculator < Test::Unit::TestCase def setup @calc = Calculator.new def teardown @calc = nil def test_sum assert_equal(2, @calc.sum(1, 1), "1 + 1 = 2") def test_subtract assert_equal(1, @calc.subtract(2, 1), 2-1 = 1") def test_multiply assert_equal(4, @calc.multiply(2, 2), 2 x 2 = 4") def test_divide assert_equal(2, @calc.sum(4, 2), 4 / 2 = 2") assert_raise(zerodivisionerror) { @calc.divide(2, 0) }

Um pequeno exemplo test_calculator.rb class TestCalculator < Test::Unit::TestCase def setup @calc = Calculator.new def teardown @calc = nil def test_sum assert_equal(2, @calc.sum(1, 1), "1 + 1 = 2") def test_subtract assert_equal(1, @calc.subtract(2, 1), 2-1 = 1") def test_multiply assert_equal(4, @calc.multiply(2, 2), 2 x 2 = 4") def test_divide assert_equal(2, @calc.sum(4, 2), 4 / 2 = 2") assert_raise(zerodivisionerror) { @calc.divide(2, 0) }

Um pequeno exemplo test_calculator.rb class TestCalculator < Test::Unit::TestCase def setup @calc = Calculator.new def teardown @calc = nil def test_sum assert_equal(2, @calc.sum(1, 1), "1 + 1 = 2") def test_subtract assert_equal(1, @calc.subtract(2, 1), 2-1 = 1") def test_multiply assert_equal(4, @calc.multiply(2, 2), 2 x 2 = 4") def test_divide assert_equal(2, @calc.sum(4, 2), 4 / 2 = 2") assert_raise(zerodivisionerror) { @calc.divide(2, 0) }

Um pequeno exemplo test_calculator.rb class TestCalculator < Test::Unit::TestCase def setup @calc = Calculator.new def teardown @calc = nil def test_sum assert_equal(2, @calc.sum(1, 1), "1 + 1 = 2") def test_subtract assert_equal(1, @calc.subtract(2, 1), 2-1 = 1") def test_multiply assert_equal(4, @calc.multiply(2, 2), 2 x 2 = 4") def test_divide assert_equal(2, @calc.sum(4, 2), 4 / 2 = 2") assert_raise(zerodivisionerror) { @calc.divide(2, 0) }

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 execute os testes: def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 execute os testes: todos eles devem falhar $~ ruby test_calculator.rb Loaded suite test Started EEEE Finished in 0.0 seconds. 1) Error: test_divide(testcalculator): NameError: uninitialized constant TestCalculator::Calculator test.rb:24:in `setup'... 4 tests, 0 assertions, 0 failures, 4 errors

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 execute os testes: todos eles devem falhar $~ ruby test_calculator.rb Loaded suite test Started EEEE Finished in 0.0 seconds. 1) Error: test_divide(testcalculator): NameError: uninitialized constant TestCalculator::Calculator test.rb:24:in `setup'... 4 tests, 0 assertions, 0 failures, 4 errors 4 erros: nosso código não passou no teste

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 escreva o primeiro método: def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 escreva o primeiro método: rode os testes $~ ruby test_calculator.rb Loaded suite test Started EEE. Finished in 0.0 seconds. 1) Error: test_divide(testcalculator): NoMethodError: undefined method `divide' for #<Calculator: 0x2e2069c> test.rb:44:in `test_divide... 4 tests, 1 assertions, 0 failures, 3 errors

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 escreva o primeiro método: rode os testes $~ ruby test_calculator.rb Loaded suite test Started EEE. Finished in 0.0 seconds. 1) Error: test_divide(testcalculator): NoMethodError: undefined method `divide' for #<Calculator: 0x2e2069c> test.rb:44:in `test_divide... 4 tests, 1 assertions, 0 failures, 3 errors 1 asserção: nosso código passou no teste

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 escreva o método seguinte: def subtract(n1, n2) n2 - n1 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n2 - n1 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 escreva o método seguinte: rode os testes $~ ruby test_calculator.rb Loaded suite test Started EF.E Finished in 0.0 seconds. 1) Failure: test_subtract(testcalculator) [test.rb:35]: 2-1 = 1. <1> expected but was <-1>.... 4 tests, 1 assertions, 1 failures, 2 errors

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n2 - n1 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 escreva o método seguinte: rode os testes $~ ruby test_calculator.rb Loaded suite test Started EF.E Finished in 0.0 seconds. 1) Failure: test_subtract(testcalculator) [test.rb:35]: 2-1 = 1. <1> expected but was <-1>.... 4 tests, 1 assertions, 1 failures, 2 errors 1 falha: nosso código não passou no teste

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n2 - n1 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 escreva o método seguinte: rode os testes $~ ruby test_calculator.rb Loaded suite test Started EF.E Finished in 0.0 seconds. 1) Failure: test_subtract(testcalculator) [test.rb:35]: 2-1 = 1. <1> expected but was <-1>.... 4 tests, 1 assertions, 1 failures, 2 errors 1 falha: nosso código não passou no teste devia ser n1 - n2

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 corrija o método que falhou: def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 corrija o método que falhou: rode os testes $~ ruby test_calculator.rb Loaded suite test Started E..E Finished in 0.0 seconds. 1) Error: test_divide(testcalculator): NoMethodError: undefined method `divide' for #<Calculator: 0x2e2069c> test.rb:44:in `test_divide... 4 tests, 2 assertions, 0 failures, 2 errors

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 corrija o método que falhou: rode os testes $~ ruby test_calculator.rb Loaded suite test Started E..E Finished in 0.0 seconds. 1) Error: test_divide(testcalculator): NoMethodError: undefined method `divide' for #<Calculator: 0x2e2069c> test.rb:44:in `test_divide... 4 tests, 2 assertions, 0 failures, 2 errors 2 asserções: nosso código passou no teste

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 continue o processo: def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 continue o processo: execute os testes $~ ruby test_calculator.rb... 4 tests, 3 assertions, 0 failures, 1 errors def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 continue o processo: execute os testes $~ ruby test_calculator.rb... 4 tests, 3 assertions, 0 failures, 1 errors só mais um: ufa! def divide(n1, n2) n1 / n2

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 escreva o último método: def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 escreva o último método: execute os testes $~ ruby test_calculator.rb Loaded suite test Started... Finished in 0.0 seconds. 4 tests, 5 assertions, 0 failures, 0 errors

Um pequeno exemplo calculator.rb class Calculator def sum(n1, n2) n1 + n2 def subtract(n1, n2) n1 - n2 def multiply(n1, n2) n1 * n2 def divide(n1, n2) n1 / n2 escreva o último método: execute os testes $~ ruby test_calculator.rb Loaded suite test Started... Finished in 0.0 seconds. 4 tests, 5 assertions, 0 failures, 0 errors 5 asserções, nenhuma falha/erro: código perfeito!

TDD no Rails Testar uma aplicação no Rails é muito simples Os testes ficam no diretório test Os arquivos de testes são criados para você Apenas um comando: rake test Dados de testes: fixtures Testes unitários, funcionais, integração e performance Mocks & Stubs

Fixtures Conteúdo inicial do modelo Ficam sob o diretório test/fixtures SQL, CSV ou YAML Modelo Artist Tabela artists Fixture artists.yml

Fixtures test/fixtures/artists.yml nofx: id: 1 name: NOFX url: http://nofxofficialwebsite.com created_at: <%= Time.now.strftime(:db) %> millencolin: id: 2 name: Millencolin url: http://millencolin.com created_at: <%= 3.days.ago.strftime(:db) %>

Testes unitários Testes unitários validam modelos Ficam sob o diretório test/unit Arquivo gerado pelo Rails: <model>_test.rb script/generate model Artist test/unit/artist_test.rb

Testes unitários test/unit/artist_test.rb require File.dirname( FILE ) + '/../test_helper' class ArtistTest < Test::Unit::TestCase fixtures :artists # Replace this with your real tests. def test_truth assert true

Testes unitários test/unit/artist_test.rb require File.dirname( FILE ) + '/../test_helper' class ArtistTest < Test::Unit::TestCase fixtures :artists def test_should_require_name artist = create(:name => nil) assert_not_nil artist.errors.on(:name), ":name should have had an error" assert!artist.valid?, "artist should be invalid" private def create(options={}) Artist.create({ :name => 'Death Cab For Cutie', :url => 'http://deathcabforcutie.com' }.merge(options))

Testes unitários app/models/artist.rb class Artist < ActiveRecord::Base execute os testes:

Testes unitários app/models/artist.rb class Artist < ActiveRecord::Base execute os testes: rake test:units $~ rake test:units Loaded suite test Started F Finished in 0.094 seconds. 1) Failure: test_should_require_name(artisttest) [./test/ unit/artist_test.rb:8]: :name should have had an error. <nil> expected to not be nil. 1 tests, 1 assertions, 1 failures, 0 errors

Testes unitários app/models/artist.rb class Artist < ActiveRecord::Base execute os testes: rake test:units $~ rake test:units Loaded suite test Started F Finished in 0.094 seconds. 1) Failure: test_should_require_name(artisttest) [./test/ unit/artist_test.rb:8]: :name should have had an error. <nil> expected to not be nil. 1 tests, 1 assertions, 1 failures, 0 errors o teste falhou: era esperado!

Testes unitários app/models/artist.rb class Artist < ActiveRecord::Base validates_presence_of :name adicione a validação:

Testes unitários app/models/artist.rb class Artist < ActiveRecord::Base validates_presence_of :name adicione a validação: execute os testes $~ rake test:units Loaded suite test Started. Finished in 0.062 seconds. 1 tests, 2 assertions, 0 failures, 0 errors

Testes unitários app/models/artist.rb class Artist < ActiveRecord::Base validates_presence_of :name adicione a validação: execute os testes $~ rake test:units Loaded suite test Started. Finished in 0.062 seconds. 1 tests, 2 assertions, 0 failures, 0 errors nenhuma falha: voila!

Testes funcionais Testes funcionais validam controles Ficam sob o diretório test/functional Template e/ou requisição Arquivo gerado pelo Rails: <controller>_test.rb script/generate controller artists test/functional/artists_controller_test.rb

Testes funcionais test/functional/artists_controller_test.rb require File.dirname( FILE ) + '/../test_helper require artists_controller # Re-raise errors caught by the controller. class ArtistsController; def rescue_action(e) raise e ; class ArtistsControllerTest < Test::Unit::TestCase def setup @controller = ArtistsController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new # Replace this with your real tests. def test_truth assert true

Testes funcionais test/functional/artists_controller_test.rb... class ArtistsControllerTest < Test::Unit::TestCase def setup @controller = ArtistsController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new def test_index_page get index_path assert_response :success assert_template index assert_select h1, Bands that sound like... assert_select form, {:count => 1, :method} => get do assert_select input#name, :count => 1 assert_select input[type=submit], :count => 1

Testes funcionais test/functional/artists_controller_test.rb... class ArtistsControllerTest < Test::Unit::TestCase def setup @controller = ArtistsController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new def test_index_page get index_path assert_response :success assert_template index requisição: verificando a resposta assert_select h1, Bands that sound like... assert_select form, {:count => 1, :method} => get do assert_select input#name, :count => 1 assert_select input[type=submit], :count => 1 template: verificando o markup

Testes funcionais ~$ rake test:functionals Loaded suite test Started E Finished in 0.094 seconds. execute os testes: 1) Error: test_index_page(artistscontrollertest): ActionController::UnknownAction: No action responded to index..../test/functional/artists_controller_test.rb:15:in `test_index_page' 1 tests, 0 assertions, 0 failures, 1 errors

Testes funcionais ~$ rake test:functionals Loaded suite test Started E Finished in 0.094 seconds. execute os testes: eles devem falhar 1) Error: test_index_page(artistscontrollertest): ActionController::UnknownAction: No action responded to index..../test/functional/artists_controller_test.rb:15:in `test_index_page' 1 tests, 0 assertions, 0 failures, 1 errors

Testes funcionais ~$ rake test:functionals Loaded suite test Started E Finished in 0.094 seconds. execute os testes: eles devem falhar 1) Error: test_index_page(artistscontrollertest): ActionController::UnknownAction: No action responded to index..../test/functional/artists_controller_test.rb:15:in `test_index_page' 1 tests, 0 assertions, 0 failures, 1 errors 1 erro: ele já era esperado

Testes funcionais ~$ rake test:functionals Loaded suite test Started E Finished in 0.094 seconds. execute os testes: eles devem falhar 1) Error: test_index_page(artistscontrollertest): action: nós ainda não a criamos ActionController::UnknownAction: No action responded to index..../test/functional/artists_controller_test.rb:15:in `test_index_page' 1 tests, 0 assertions, 0 failures, 1 errors 1 erro: ele já era esperado

Testes funcionais ~$ rake test:functionals Loaded suite test Started E Finished in 0.094 seconds. crie o template index.rhtml: 1) Failure: test_index_page(artistscontrollertest) [selector_assertions.rb:281:in `assert_select'./test/functional/artists_controller_test.rb:19:in `test_index_page']: Expected at least 1 elements, found 0. <false> is not true. 1 tests, 3 assertions, 1 failures, 0 errors

Testes funcionais ~$ rake test:functionals Loaded suite test Started E Finished in 0.094 seconds. crie o template index.rhtml: execute os testes 1) Failure: test_index_page(artistscontrollertest) [selector_assertions.rb:281:in `assert_select'./test/functional/artists_controller_test.rb:19:in `test_index_page']: Expected at least 1 elements, found 0. <false> is not true. 1 tests, 3 assertions, 1 failures, 0 errors

Testes funcionais ~$ rake test:functionals Loaded suite test Started E Finished in 0.094 seconds. crie o template index.rhtml: execute os testes 1) Failure: test_index_page(artistscontrollertest) [selector_assertions.rb:281:in `assert_select'./test/functional/artists_controller_test.rb:19:in `test_index_page']: Expected at least 1 elements, found 0. <false> is not true. 1 tests, 3 assertions, 1 failures, 0 errors 1 erro: ele já era esperado

Testes funcionais ~$ rake test:functionals Loaded suite test Started E Finished in 0.094 seconds. crie o template index.rhtml: execute os testes 1) Failure: test_index_page(artistscontrollertest) [selector_assertions.rb:281:in `assert_select'./test/functional/artists_controller_test.rb:19:in `test_index_page']: Expected at least 1 elements, found 0. <false> is not true. 1 tests, 3 assertions, 1 failures, 0 errors template: nenhum código HTML 1 erro: ele já era esperado

Testes funcionais app/views/artists/index.rhtml <h1>bands that sound like...</h1> <% form_tag 'view', {:method => :get} do %> <p> <%= text_field_tag :name %> <%= submit_tag View' %> </p> <% %> código HTML:

Testes funcionais app/views/artists/index.rhtml <h1>bands that sound like...</h1> <% form_tag 'view', {:method => :get} do %> <p> <%= text_field_tag :name %> <%= submit_tag View' %> </p> <% %> código HTML: execute os testes ~$ rake test:functionals Loaded suite test Started. Finished in 0.094 seconds. 1 tests, 9 assertions, 0 failures, 0 errors

Testes funcionais app/views/artists/index.rhtml <h1>bands that sound like...</h1> <% form_tag 'view', {:method => :get} do %> <p> <%= text_field_tag :name %> <%= submit_tag View' %> </p> <% %> código HTML: execute os testes ~$ rake test:functionals Loaded suite test Started. Finished in 0.094 seconds. 1 tests, 9 assertions, 0 failures, 0 errors yep: tudo certo! erros: nenhum para contar história

Testes de integração Testes de integração validam (duh) a integração entre diferentes controllers Ficam sob o diretório test/integration Rails não gera arquivo automaticamente: você escolhe! script/generate integration_test artist_stories test/integraton/artist_stories_test.rb

Testes de integração test/integration/artist_stories_test.rb require File.dirname( FILE ) + '/../test_helper' class ArtistStoriesTest < ActionController::IntegrationTest # fixtures :your, :models # Replace this with your real tests. def test_truth assert true

Testes de integração test/integration/artist_stories_test.rb require File.dirname( FILE ) + '/../test_helper' class ArtistStoriesTest < ActionController::IntegrationTest fixtures :artists, :albums def test_user_viewing_artist_and_album # user accessing index page get "/" assert_response :success assert_template "index" # searching for an artist get artist_search_path(artists(:millencolin).slug) assert_response :redirect assert_redirected_to "/artists/#{artists(:millencolin).slug}" # viewing album "life on a plate" get album_path(albums(:life_on_a_plate)) assert_response :success assert_template "view"

Testes de integração test/integration/artist_stories_test.rb require File.dirname( FILE ) + '/../test_helper' class ArtistStoriesTest < ActionController::IntegrationTest fixtures :artists, :albums def test_user_viewing_artist_and_album # user accessing index page get "/" assert_response :success assert_template "index" controller: / # searching for an artist get artist_search_path(artists(:millencolin).slug) assert_response :redirect assert_redirected_to "/artists/#{artists(:millencolin).slug}" controller: /artists/search # viewing album "life on a plate" get album_path(albums(:life_on_a_plate)) assert_response :success assert_template "view" controller: /albums/

Testes de integração Testes funcionais em um nível mais alto: DSL Leitura mais fácil, impossível! Use o método open_session open_session do session # Do everything you need!

Testes de integração test/integration/artist_stories_test.rb class ArtistStoriesTest < ActionController::IntegrationTest fixtures :artists, :albums def test_artist_story artist = artists(:millencolin) user = new_session user.search_artist artist user.view_album artist.albums.first private def new_session open_session do session def session.search_artist(artist) get search_artist(artist.name) assert_response :redirect assert_redirected_to artist_path(artist.slug) def session.view_album(album) get album_path(album.slug) assert_response :success assert_template 'view'

Testes de integração test/integration/artist_stories_test.rb class ArtistStoriesTest < ActionController::IntegrationTest fixtures :artists, :albums def test_artist_story artist = artists(:millencolin) user = new_session user.search_artist artist user.view_album artist.albums.first private def new_session open_session do session def session.search_artist(artist) get search_artist(artist.name) assert_response :redirect assert_redirected_to artist_path(artist.slug) def session.view_album(album) get album_path(album.slug) assert_response :success assert_template 'view' user = new_session user.search_artist artist user.view_album artist.albums.first

Testes de integração test/integration/artist_stories_test.rb class ArtistStoriesTest < ActionController::IntegrationTest fixtures :artists, :albums def test_artist_story artist = artists(:millencolin) user = new_session user.search_artist artist user.view_album artist.albums.first private def new_session open_session do session def session.search_artist(artist) get search_artist(artist.name) assert_response :redirect assert_redirected_to artist_path(artist.slug) def session.view_album(album) get album_path(album.slug) assert_response :success assert_template 'view' user = new_session user.search_artist artist user.view_album artist.albums.first melhor, impossível!

Mocks & Stubs Códigos que eliminam o acesso a um recurso Ficam sob o diretório test/mocks/test Deve ter o mesmo nome do arquivo e estrutura da classe/módulo que você quer substituir RAILS_ROOT/lib/launch_missile.rb test/mocks/<rails_env>/launch_missile.rb

Mocks & Stubs lib/feed.rb require open-uri class Feed def load(url) open URI.parse(url).read

Mocks & Stubs lib/feed.rb require open-uri class Feed def load(url) open URI.parse(url).read não é o ideal: a) pode ser lento; b) pode não estar disponível; c) imagine se fosse transação de pagamento!

Mocks & Stubs test/mocks/test/feed.rb require open-uri class Feed def load(url) File.new( #{RAILS_ROOT}/test/fixtures/feed.xml ).read

Mocks & Stubs test/mocks/test/feed.rb require open-uri class Feed def load(url) File.new( #{RAILS_ROOT}/test/fixtures/feed.xml ).read muito mais fácil e rápido: faça quantos pagamentos quiser!

Dúvidas?