Minicurso de TestesOnRails
Upcoming SlideShare
Loading in...5
×
 

Minicurso de TestesOnRails

on

  • 3,660 views

Slides do minicurso de Testes em Rails realizado no Maré de Agilidade de Fortaleza/CE.

Slides do minicurso de Testes em Rails realizado no Maré de Agilidade de Fortaleza/CE.

Statistics

Views

Total Views
3,660
Slideshare-icon Views on SlideShare
3,150
Embed Views
510

Actions

Likes
11
Downloads
125
Comments
1

8 Embeds 510

http://blog.seatecnologia.com.br 162
http://maredeagilidade.blogspot.com 115
http://www.natanaelpantoja.com 81
http://maredeagilidade.blogspot.com.br 64
http://portfoliodomourdok.wordpress.com 44
http://www.seatecnologia.com.br 41
http://www.slideshare.net 2
https://www.seatecnologia.com.br 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Pouco tempo e muito conte&#xFA;do <br /> Turma heterog&#xEA;nea <br /> Cada um segue seu ritmo <br /> Pouca teoria e muita pr&#xE1;tica
  • Comecemos falando de testes
  • Se voc&#xEA; falar com qualquer pessoa comum sobre testes, ela associar&#xE1; &#xE0; realiza&#xE7;&#xE3;o de rotinas de verifica&#xE7;&#xE3;o de algo anteriormente constru&#xED;do.
  • Se voc&#xEA; falar com qualquer pessoa comum sobre testes, ela associar&#xE1; &#xE0; realiza&#xE7;&#xE3;o de rotinas de verifica&#xE7;&#xE3;o de algo anteriormente constru&#xED;do.
  • O problema, entretanto, &#xE9; grande tempo entre a constru&#xE7;&#xE3;o e a verifica&#xE7;&#xE3;o.
  • O problema, entretanto, &#xE9; grande tempo entre a constru&#xE7;&#xE3;o e a verifica&#xE7;&#xE3;o.
  • O problema, entretanto, &#xE9; grande tempo entre a constru&#xE7;&#xE3;o e a verifica&#xE7;&#xE3;o.
  • A medida que o tempo passa, manuten&#xE7;&#xF5;es ficam mais caras.
  • E a&#xED;, o cen&#xE1;rio mais comum, e come&#xE7;ar a guerra fria entre os que constroem e os que verificam.
  • Convergindo na pior afirma&#xE7;&#xE3;o de qualquer membro de equipe: &#x201C;n&#xE3;o &#xE9; problema meu&#x201D;
  • Como forma de aliviar, dentre outras coisas, essa disputa entre desenvolvedores e testadores, foi proposta uma metodologia de desenvolvimento chamada TDD.
  • Quando se faz teste, al&#xE9;m do c&#xF3;digo programa em si, deve-se escrever outro c&#xF3;digo que verifique o programa que, quando &#xE9; executado....
  • Quando se faz teste, al&#xE9;m do c&#xF3;digo programa em si, deve-se escrever outro c&#xF3;digo que verifique o programa que, quando &#xE9; executado....
  • ...pode passar...
  • Eu tenho um c&#xF3;digo e v&#xE1;rios testes que o suportam.
  • Eu tenho um c&#xF3;digo e v&#xE1;rios testes que o suportam.
  • Eu tenho um c&#xF3;digo e v&#xE1;rios testes que o suportam.
  • Eu tenho um c&#xF3;digo e v&#xE1;rios testes que o suportam.
  • Eu tenho um c&#xF3;digo e v&#xE1;rios testes que o suportam.
  • Eu tenho um c&#xF3;digo e v&#xE1;rios testes que o suportam.
  • Eu tenho um c&#xF3;digo e v&#xE1;rios testes que o suportam.
  • Eu tenho um c&#xF3;digo e v&#xE1;rios testes que o suportam.
  • O impacto de qualquer modifica&#xE7;&#xE3;o no c&#xF3;digo....
  • ...&#xE9; imediatamente apontado por seus testes.
  • Testes automaticos tratam de algo t&#xE3;o importante que mal sabemos traduzir....
  • Controla o crescimento do custo das mudan&#xE7;as que, tradicionalmente, &#xE9; descontrolado.
  • Iterativo vs Incremental <br /> Iterativo!??! S&#xF3; na constru&#xE7;&#xE3;o. <br /> Big Design Upfront vs Design Evolutivo
  • Iterativo vs Incremental <br /> Iterativo!??! S&#xF3; na constru&#xE7;&#xE3;o. <br /> Big Design Upfront vs Design Evolutivo
  • Big design upf-ront
  • Mudan&#xE7;as: rastreamento autom&#xE1;tico de impactos de modifica&#xE7;&#xF5;es <br /> Robustez: evitar apps fr&#xE1;geis cujos bugs sempre voltam <br /> Direcionamento: &#x201C;s&#xED;ndrome da folha em branco&#x201D;
  • Vamos fazer um Twitter.
  • Quando se cria uma app Rails, v&#xE1;rios testes s&#xE3;o automaticamente gerados...
  • Para execu&#xE7;&#xE3;o dos teste, utiliza-se instru&#xE7;&#xF5;es rake.
  • Quando se executa os tese
  • Toda execu&#xE7;&#xE3;o de testes no Rails utiliza o seu ambiente de testes, sem impactar na base de desenvolvimento ou nos dados de produ&#xE7;&#xE3;o.
  • Fixtures &#xE9; o mecanismo do Rails para cria&#xE7;&#xE3;o da massa de testes.
  • Na verdade, Fixtures &#xE9; uma t&#xE9;cnica n&#xE3;o exclusiva do Rails
  • ...discutida at&#xE9; em livros...
  • Testes unit&#xE1;rios do Rails s&#xE3;o compostos por recursos b&#xE1;sicos de testes do Ruby mais recursos espec&#xED;ficos do Rails
  • O funcionamento dos testes unit&#xE1;rios seguem a regra geral, com detalhe para o passo 3.
  • V&#xE1;rias asser&#xE7;&#xF5;es v&#xEA;m do Ruby Test::Unit::TestCase
  • Do Ruby...
  • Do Rails...
  • Teste gerado pelo Rails.
  • Criemos um teste pra checar o ActiveRecord (apenas para fins did&#xE1;ticos)
  • Oops, tudo funcionou de cara. Mas claro, o ActiveRecord j&#xE1; est&#xE1; pronto!
  • Fa&#xE7;amos um novo teste.
  • TODO: <br /> u.valid? <br /> u.errors.invalid?(:email) <br /> mensagem de erro no assert <br /> associacao <br /> yml <br /> helper
  • Implementar funcionalidade de Login.
  • Defini&#xE7;&#xE3;o do m&#xE9;todo &#x2018;signin&#x2019;
  • O m&#xE9;todo signin retorna &#x2018;null&#x2019;, mas o teste espera &#x2018;true&#x2019;
  • Teste espera &#x2018;false&#x2019; mas c&#xF3;digo retorna &#x2018;true&#x2019;
  • Agora sim. Ficou mais claro qual teste est&#xE1; falhando.
  • N&#xE3;o encontrou no banco qualquer registro com login = &#x201C;alegomes&#x201D; e password = &#x201C;ale123&#x201D;
  • Dicas: <br /> - Criar scaffold de updates
  • Resumo dos testes funcionais: teste enviar requisi&#xE7;&#xE3;o HTTP ao controller e verifica se a resposta enviada coincide com a resposta esperada.
  • Testes unit&#xE1;rios do Rails s&#xE3;o compostos por recursos b&#xE1;sicos de testes do Ruby mais recursos espec&#xED;ficos do Rails
  • Novidades
  • Asser&#xE7;&#xF5;es
  • Teste pode passar, mas pode n&#xE3;o existir rota definidar pra ele. <br /> <br /> Uma par&#xE2;metro n&#xE3;o string pode fazer o teste passar, mas n&#xE3;o funcionar&#xE1; para o usu&#xE1;rio, pois o browser sempre manda string.
  • assert_response {200,300...} ou {:success, :redirect, :missing, :error} <br /> assert_template &#x201C;index&#x201D; (n&#xE3;o checa o conte&#xFA;do!) <br /> assert_redirect n&#xE3;o segue o redirecionamento
  • Exemplos
  • N&#xE3;o repita os mesmos testes nos dois lugares.
  • Pra cada controlador...
  • ...tem-se seu respectivo teste.
  • Testes funcionais gerados pelo scaffold n&#xE3;o est&#xE3;o passando.
  • A requisi&#xE7;&#xE3;o post est&#xE1; passando um usu&#xE1;rio sem informar nenhum atributo, contrariando nossa valida&#xE7;&#xE3;o.
  • Agora sim!
  • Prossigamos com a funcionaldiade de login.
  • Gera&#xE7;&#xE3;o de um novo controlador de sess&#xF5;es, respons&#xE1;vel pelo login e logout do usu&#xE1;rio.
  • Teste funcional criado para o novo controller.
  • Mais de perto.... Esta &#xE9; a forma mais comum de se testar um controlador: <br /> <br /> assert_response <br /> assert_not_nil <br /> assert_template
  • Teste funcional criado falhando na linha 8: <br /> <br /> assert_not_nil assigns(:user)
  • Controlador invocando Model para autentica&#xE7;&#xE3;o do usu&#xE1;rio e disponibiliza&#xE7;&#xE3;o da inst&#xE2;ncia @user pra camada View.
  • Falha agora no assert da linha 13: <br /> <br /> assert_template "users/home"
  • Se o usu&#xE1;rio tiver sido autenticado com sucesso, redirecione-o para sua p&#xE1;gina home.
  • Nosso teste est&#xE1; inconsistente! Em um momento, ele verifica o retorno de sucesso (200) da requisi&#xE7;&#xE3;o. Em outro, ele checa se a requisi&#xE7;&#xE3;o gerou um redirecionamento de p&#xE1;gina (300).
  • Mudan&#xE7;a no teste de &#x2018;assert_response :success&#x2019; para &#x2018;assert_response :redirect&#x2019;
  • ATEN&#xC7;&#xC3;O! O redirect n&#xE3;o implica no render do template de destino. Logo, n&#xE3;o podemos usar assert_template com redirect.
  • Mudan&#xE7;as no teste: <br /> - Substitui&#xE7;&#xE3;o do assert_template por assert_redirect_to <br /> - Elimina&#xE7;&#xE3;o do &#x2018;assert_response :redirect&#x2019;, cuja verifica&#xE7;&#xE3;o j&#xE1; &#xE9; impl&#xED;cita no assert_redirected_to
  • Fa&#xE7;a um monte de chamadas a v&#xE1;rios controladores e verifique o resultado.
  • Tratam de conceitos diferentes.

Minicurso de TestesOnRails Minicurso de TestesOnRails Presentation Transcript

  • Mini-Curso TestesOnRails Desenvolvimento Orientado a Testes em Rails 1
  • 2
  • Disclaimer 3
  • http://www.railsrx.com 4
  • O que testar? Quando testar? Quanto testar? Quantos asserts por teste? Teste quebrado mudar teste ou código? 5
  • Contextualização Testes, Testes Automatizados, Desenvolvimento Orientado a Testes, Design Evolutivo, Ferramentas de Teste TestesOnRails Unit, Functionals, Integration,View,View Helpers, Routes, Performance, Mocks Shoulda, RSpec, RSpec-Rails, faker, Cucumber, Koujou 6
  • Em teoria... 7
  • Testes
  • Desenvolver Testar
  • Desenvolver Testar
  • ?
  • ?
  • $? ?
  • $ cr iaç ão de sc ob er ta co rr eç ão
  • X
  • Testes Automáticos
  • Programa
  • Teste Programa
  • Teste Programa
  • Teste Programa
  • (...) public void meuTeste() { int par1 = 1; int par2 = 1; int result = Classe.soma(par1,par1); assertEquals(2, result); } (...) (...) public int soma(int a, int b) { // código } (...)
  • (...) public void meuTeste() { int par1 = 1; Preparação int par2 = 1; int result = Classe.soma(par1,par1); assertEquals(2, result); } (...) (...) public int soma(int a, int b) { // código } (...)
  • (...) public void meuTeste() { int par1 = 1; int par2 = 1; int result = Classe.soma(par1,par2); assertEquals(2, result); Exercício } (...) (...) public int soma(int a, int b) { // código } (...)
  • (...) public void meuTeste() { int par1 = 1; int par2 = 1; int result = Classe.soma(par1,par1); } assertEquals(2, result); Verificação (...) (...) public int soma(int a, int b) { // código } (...)
  • vale a pena ?
  • X
  • X
  • X
  • 10 30
  • 10 20 30 30
  • 10 20 30 30 30 30
  • 10 20 30 40 30 30 30 30
  • 10 20 30 40 50 30 30 30 30 30
  • 10 20 30 40 50 60 30 30 30 30 30 30
  • 10 20 30 40 50 60 70 30 30 30 30 30 30 30
  • public class Romanos { public static String parse(int entrada) { StringBuilder resultado = new StringBuilder(); if (entrada <= 3) { for (int i = 0; i < entrada; i++) resultado.append("I"); return resultado.toString(); } else if (entrada == 4) { return "IV"; } else if(entrada == 5){ return "V"; } else if (entrada < 9){ resultado.append("V"); return resultado.toString(); }else if (entrada == 9){ return "IX"; }else{ return "X"; } } }
  • public static String parse(int entrada) { public static String parse(int entrada) { else if (entrada == 4) { return "IV"; public static String parse(int entrada) { else if (entrada == 4) { } else if(entrada == 5){ return "IV"; return "V"; else if (entrada == 4) { } else if(entrada == 5){ } return "IV"; return "V"; } else if(entrada == 5){ } } return "V"; } } } public class Romanos { public static String parse(int entrada) { StringBuilder resultado = new StringBuilder(); public static String parse(int entrada) { if (entrada <= 3) { for (int i = 0; i < entrada; i++) public static String parse(int entrada) { else if (entrada == 4) { resultado.append("I"); return "IV"; return resultado.toString(); else if (entrada == 4) { } else if(entrada == 5){ } return "IV"; return "V"; } else if(entrada == 5){ } else if (entrada == 4) { return "V"; return "IV"; } } } else if(entrada == 5){ return "V"; } } else if (entrada < 9){ resultado.append("V"); return resultado.toString(); }else if (entrada == 9){ return "IX"; }else{ return "X"; } } } public static String parse(int entrada) { public static String parse(int entrada) { else if (entrada == 4) { else if (entrada == 4) { return "IV"; return "IV"; } else if(entrada == 5){ } else if(entrada == 5){ return "V"; return "V"; } } } } public static String parse(int entrada) { else if (entrada == 4) { return "IV"; } else if(entrada == 5){ return "V"; } }
  • public static String parse(int entrada) { public static String parse(int entrada) { else if (entrada == 4) { return "IV"; public static String parse(int entrada) { else if (entrada == 4) { } else if(entrada == 5){ return "IV"; return "V"; else if (entrada == 4) { } else if(entrada == 5){ } return "IV"; return "V"; } else if(entrada == 5){ } } return "V"; } } } public class Romanos { public static String parse(int entrada) { StringBuilder resultado = new StringBuilder(); public static String parse(int entrada) { if (entrada <= 3) { for (int i = 0; i < entrada; i++) public static String parse(int entrada) { else if (entrada == 4) { resultado.append("I"); return "IV"; return resultado.toString(); else if (entrada == 4) { } else if(entrada == 5){ } return "IV"; return "V"; } else if(entrada == 5){ } else if (entrada == 4) { return "V"; return "IV"; } } } else if(entrada == 5){ return "V"; } } else if (entrada < 9){ resultado.append("V"); return resultado.toString(); }else if (entrada == 9){ return "IX"; }else{ return "X"; } } } public static String parse(int entrada) { public static String parse(int entrada) { else if (entrada == 4) { else if (entrada == 4) { return "IV"; return "IV"; } else if(entrada == 5){ } else if(entrada == 5){ return "V"; return "V"; } } } } public static String parse(int entrada) { else if (entrada == 4) { return "IV"; } else if(entrada == 5){ return "V"; } }
  • public static String parse(int entrada) { public static String parse(int entrada) { else if (entrada == 4) { return "IV"; public static String parse(int entrada) { else if (entrada == 4) { } else if(entrada == 5){ return "IV"; return "V"; else if (entrada == 4) { } else if(entrada == 5){ } return "IV"; return "V"; } else if(entrada == 5){ } } return "V"; } } } public class Romanos { public static String parse(int entrada) { StringBuilder resultado = new StringBuilder(); public static String parse(int entrada) { if (entrada <= 3) { for (int i = 0; i < entrada; i++) public static String parse(int entrada) { else if (entrada == 4) { resultado.append("I"); return "IV"; return resultado.toString(); else if (entrada == 4) { } else if(entrada == 5){ } return "IV"; return "V"; } else if(entrada == 5){ } else if (entrada == 4) { return "V"; return "IV"; } } } else if(entrada == 5){ return "V"; } } else if (entrada < 9){ resultado.append("V"); return resultado.toString(); }else if (entrada == 9){ return "IX"; }else{ return "X"; } } } public static String parse(int entrada) { public static String parse(int entrada) { else if (entrada == 4) { else if (entrada == 4) { return "IV"; return "IV"; } else if(entrada == 5){ } else if(entrada == 5){ return "V"; return "V"; } } } } public static String parse(int entrada) { else if (entrada == 4) { return "IV"; } else if(entrada == 5){ return "V"; } }
  • evolvability maintainability mantenabilidade manutenibilidade manutenabilidade capacidade de manutenção
  • Custo Tempo
  • Custo Tempo
  • Test Driven Development
  • GREEN
  • RED teste GREEN
  • RED código teste GREEN
  • RED código teste GREEN refactoring
  • RED GREEN
  • RED Plan GREEN
  • RED Plan Do GREEN
  • RED Plan Do GREEN Check
  • RED Plan Do Act GREEN Check
  • Design Evolutivo
  • ?
  • RED GREEN
  • Foco RED GREEN
  • Foco Ritmo RED GREEN
  • Foco Ritmo RED Disciplina GREEN
  • Foco Ritmo RED Disciplina Simplicidade GREEN
  • Ferramentas (Java)
  • Unidade
  • Bancos de Dados
  • Aceitação
  • Aplicações WEB Selenium
  • Performance (WEB)
  • Testes Testes Automáticos Desenvolvimento Orientado a Testes Design Evolutivo Ferramentas 46
  • 47
  • http://www.railsrx.com 48
  • Quando se fala de testes, fala-se de... Mudanças Corretude Direcionamento Robustez Design evolutivo Documentação 49
  • O que testar? caminho feliz caminhos alternativos erros conhecidos e esperados 50
  • 51
  • TestesOnRails 52
  • 53
  • Kiwitter 54
  • $ rails kiwitter create create app/controllers create app/helpers create app/models create app/views/layouts create config/environments create config/initializers create config/locales (...) create log/server.log create log/production.log create log/development.log create log/test.log 55
  • kiwitter $ script/generate scaffold user login:string email:string password:string exists app/models/ exists app/controllers/ exists app/helpers/ create app/views/users exists app/views/layouts/ (...) create test/unit/user_test.rb create test/fixtures/users.yml create db/migrate create db/migrate/20090729120900_create_users.rb 56
  • kiwitter $ script/server => Booting WEBrick => Rails 2.3.3 application starting on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server [2009-07-29 09:29:22] INFO WEBrick 1.3.1 [2009-07-29 09:29:22] INFO ruby 1.8.7 (2009-06-12) [powerpc-darwin9] [2009-07-29 09:29:22] INFO WEBrick::HTTPServer#start: pid=54915 port=3000 57
  • kiwitter $ rake db:migrate (in ...maredeagilidade_ceara/labs/rails_test/kiwitter) == CreateUsers: migrating ======================================== -- create_table(:users) -> 0.0082s == CreateUsers: migrated (0.0094s) ================================= 58
  • Unit Functional Integration Performance Tests 59
  • kiwitter $ rake -T rake test rake test:benchmark rake test:functionals rake test:integration rake test:plugins rake test:profile rake test:recent rake test:uncommitted rake test:units 60
  • kiwitter $ rake test:units Started ........FE Finished in 1.181401 seconds. 61
  • ........FE 1) Failure: test_should_sign_in_only_when_vali d_credentials_are_given(UserTest) [/ test/unit/user_test.rb:25]: <nil> is not true. 62
  • ........FE 2) Error: test_should_display_user_greetings( UsersHelperTest): ArgumentError: wrong number of arguments (1 for 0) 63
  • Rails environments test development production 64
  • 65
  • Fixtures 66
  • Test fixture refers to the fixed state used as a baseline for running tests in software testing. The purpose of a test fixture is to ensure that there is a well known and fixed environment in which tests are run so that results are repeatable. Some people call this the test context. http://en.wikipedia.org/wiki/Test_fixture 67
  • 68
  • http://ar.rubyonrails.org/classes/Fixtures.html 69
  • Inicialização da base database.yml Identificação dos arquivos de testes test/**/*.rb Para cada teste identificação dos métodos de testes 70
  • Para cada método de teste test “should xxx yyy” 1. carrega fixtures test/fixtures/users.yml 2. executa setup 3. executa o teste .....FE 4. executa teardown 5. “descarrega” fixtures rollback ou delete 71
  • ios ár n it s U s t e Te 72
  • Test::Unit::TestCase ActiveSupport::TestCase + Rails Unit Tests 73
  • Rails Unit Tests 1. fixtures 2. setup 3. test/unit/*_test.rb 4. teardown 74
  • Test::Unit::TestCase assert assert_not_same assert_block assert_nothing_raised assert_equal assert_nothing_thrown assert_in_delta assert_operator assert_instance_of assert_raise assert_kind_of assert_raises assert_match assert_respond_to assert_nil assert_same assert_no_match assert_send assert_not_equal assert_throws assert_not_nil 75
  • http://ruby-doc.org/stdlib/ 76
  • http://api.rubyonrails.org/ 77
  • assert assert_nothing_thrown assert_block assert_operator assert_equal assert_raise assert_in_delta assert_raises assert_instance_of assert_respond_to assert_kind_of assert_same assert_match assert_send assert_nil assert_throws assert_no_match build_message assert_not_equal flunk assert_not_nil use_pp= assert_not_same assert_difference assert_nothing_raised assert_no_difference 78
  • Kiwitter 79
  • Kiwitter 80
  • 81
  • kiwitter $ rake test:units ... /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/ 1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/ unit/helpers/users_helper_test.rb" "test/unit/ user_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/ lib/rake/rake_test_loader Started . Finished in 0.201504 seconds. 1 tests, 1 assertions, 0 failures, 0 errors 82
  • 83
  • kiwitter $ rake test:units /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/ lib/rake/rake_test_loader.rb" "test/unit/helpers/users_helper_test.rb" "test/ unit/user_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/ rake_test_loader Started .F Finished in 0.378072 seconds. 1) Failure: test_should_require_login(UserTest) [/test/unit/user_test.rb:16]: <nil> is not true. 2 tests, 2 assertions, 1 failures, 0 errors rake aborted! Command failed with status (1): [/opt/local/bin/ruby -I"lib:test" "/opt/loc...] (See full trace by running task with --trace) 84
  • 85
  • kiwitter $ rake test:units /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/ gems/1.8/gems/rake-0.8.7/lib/rake/ rake_test_loader.rb" "test/unit/helpers/ users_helper_test.rb" "test/unit/user_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/ rake-0.8.7/lib/rake/rake_test_loader Started .. Finished in 0.178493 seconds. 2 tests, 2 assertions, 0 failures, 0 errors 86
  • Labs Desenvolver Orientado a Testes Validação de obrigatoriedade de senha e email Validação de unicidade do login Validação formato do email 87
  • 88
  • 89
  • kiwitter $ rake test:units /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/ rake_test_loader.rb" "test/unit/helpers/users_helper_test.rb" "test/unit/user_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader Started ..E Finished in 0.322179 seconds. 1) Error: test_should_sign_in_only_when_valid_credentials_are_given(UserTest): NoMethodError: undefined method `signin' for #<Class:0x1a761f0> /test/unit/user_test.rb:22:in `test_should_sign_in_only_when_valid_credentials_are_given' 3 tests, 2 assertions, 0 failures, 1 errors rake aborted! Command failed with status (1): [/opt/local/bin/ruby -I"lib:test" "/opt/loc...] (See full trace by running task with --trace) 90
  • 1) Error: test_should_sign_in_only_when_valid_credentials_are_given(UserTest): ArgumentError: wrong number of arguments (2 for 0) /test/unit/user_test.rb:22:in `signin' /test/unit/user_test.rb:22:in `test_should_sign_in_only_when_valid_credentials_are_given' 3 tests, 2 assertions, 0 failures, 1 errors 91
  • 1) Failure: test_should_sign_in_only_when_valid_credentials_are_given(UserTest) [/test/unit/user_test.rb:22]: <nil> is not true. 3 tests, 3 assertions, 1 failures, 0 errors 92
  • 1) Failure: test_should_sign_in_only_when_valid_credentials_are_given(UserTest) [/test/unit/user_test.rb:23]: <false> is not true. 3 tests, 4 assertions, 1 failures, 0 errors 93
  • Quem espera false? 94
  • 1) Failure: test_should_sign_in_only_when_valid_credentials_are_given(UserT est) [/test/unit/user_test.rb:22]: <nil> is not true. 3 tests, 3 assertions, 1 failures, 0 errors 1) Failure: test_should_sign_in_only_when_valid_credentials_are_given(UserT est) [/test/unit/user_test.rb:23]: <false> is not true. 3 tests, 4 assertions, 1 failures, 0 errors Problema quando se tem vários asserts num mesmo test case. 95
  • Refactoring 96
  • kiwitter $ rake test:units /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/ rake_test_loader.rb" "test/unit/helpers/users_helper_test.rb" "test/unit/user_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader Started .FF.. Finished in 0.421486 seconds. 1) Failure: test_should_not_sign_in_when_invalid_password_is_given(UserTest) [/test/unit/ user_test.rb:27]: <false> is not true. 2) Failure: test_should_not_sign_in_when_invalid_username_is_given(UserTest) [/test/unit/ user_test.rb:31]: <false> is not true. 5 tests, 5 assertions, 2 failures, 0 errors rake aborted! Command failed with status (1): [/opt/local/bin/ruby -I"lib:test" "/opt/loc...] (See full trace by running task with --trace) 97
  • 1) Failure: test_should_sign_in_only_when_valid_credentials_are_given(U serTest) [/test/unit/user_test.rb:23]: <nil> is not true. 5 tests, 5 assertions, 1 failures, 0 errors 98
  • Fixtures mecanismo para criação de massa de dados de testes 99
  • 100
  • 101
  • kiwitter $ rake test:units /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/ gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/unit/ helpers/users_helper_test.rb" "test/unit/user_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/ lib/rake/rake_test_loader Started ..... Finished in 0.367962 seconds. 5 tests, 5 assertions, 0 failures, 0 errors 102
  • Labs Testes unitários como TDD para criação (post) de mensagens (update) por um usuário 103
  • Testes Funcionais 104
  • HTTP Req ? 105
  • Test::Unit::TestCase ActiveSupport::TestCase + ActiveController::TestCase + Rails Functional Tests 106
  • ActiveController::TestCase Métodos Mock Objects “Hashes” get @controller session post @request cookies put @response flash delete assigns xhr @response.body session[:user_id] 107
  • ActiveController::TestCase assert_dom_equal assert_select assert_dom_not_equal assert_select_email assert_valid assert_select_encoded assert_redirected_to assert_select_rjs assert_response css_select assert_template response_from_page_or_rjs assert_generates unescape_rjs assert_recognizes assert_no_tag assert_routing assert_tag 108
  • 1. setup params = {:project_id => @project.id.to_s, :task_id => @task.id.to_s} session = {:user_id => 12345} 2. teste <método http> <método do controller> <params> <session> <flash> get :index post :create params session put :update {:notice => “Task updated”} delete ... 109
  • Não testa rotas! *Sempre* enviar parâmetros HTTP como string 110
  • st atus assert_ response ‘c onteúdo’ assert_t emplate ionam ento redirec t asser t_redirec 111
  • assert_response 200 assert_response 404 assert_response :success assert_response :missing assert_template “index” assert_template “users/new” assert_redirect_to :controller => task, :id => 3 assert_redirect_to new_task_url assert_redirect_to @task 112
  • Unit Tests Functional Tests 113
  • Kiwitter 114
  • Kiwitter 115
  • kiwitter $ rake test:functionals /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/ rake/rake_test_loader.rb" "test/functional/users_controller_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/ rake_test_loader Started F...... Finished in 0.618077 seconds. 1) Failure: test_should_create_user(UsersControllerTest) [/test/functional/ users_controller_test.rb:16]: "User.count" didn't change by 1. <3> expected but was <2>. 7 tests, 9 assertions, 1 failures, 0 errors rake aborted! Command failed with status (1): [/opt/local/bin/ruby -I"lib:test" "/opt/loc...] (See full trace by running task with --trace) 116
  • 117
  • kiwitter $ rake test:functionals /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/ gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/ functional/users_controller_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/ lib/rake/rake_test_loader Started ....... Finished in 0.883527 seconds. 7 tests, 10 assertions, 0 failures, 0 errors 118
  • 119
  • kiwitter $ script/generate controller sessions new exists app/controllers/ exists app/helpers/ create app/views/sessions exists test/functional/ exists test/unit/helpers/ create app/controllers/sessions_controller.rb create test/functional/sessions_controller_test.rb create app/helpers/sessions_helper.rb create test/unit/helpers/sessions_helper_test.rb create app/views/sessions/new.html.erb 120
  • 121
  • 122
  • kiwitter $ rake test:functionals /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/ rake_test_loader.rb" "test/functional/sessions_controller_test.rb" "test/functional/ users_controller_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader Started F....... Finished in 0.842942 seconds. 1) Failure: test_should_authenticate_user(SessionsControllerTest) [/test/functional/ sessions_controller_test.rb:8]: <nil> expected to not be nil. assert_not_nil 8 tests, 12 assertions, 1 failures, 0 errors assigns(:user) rake aborted! Command failed with status (1): [/opt/local/bin/ruby -I"lib:test" "/opt/loc...] (See full trace by running task with --trace) 123
  • 124
  • kiwitter $ rake test:functionals /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/ lib/rake/rake_test_loader.rb" "test/functional/sessions_controller_test.rb" "test/functional/users_controller_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/ rake_test_loader Started F....... Finished in 0.57468 seconds. assert_template "users/home" 1) Failure: test_should_authenticate_user(SessionsControllerTest) [/test/functional/ sessions_controller_test.rb:13]: expecting <"users/home"> but rendering with <"sessions/create.html.erb"> 8 tests, 13 assertions, 1 failures, 0 errors rake aborted! Command failed with status (1): [/opt/local/bin/ruby -I"lib:test" "/opt/loc...] (See full trace by running task with --trace) 125
  • 126
  • kiwitter $ rake test:functionals /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/ rake/rake_test_loader.rb" "test/functional/sessions_controller_test.rb" "test/ functional/users_controller_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/ rake_test_loader Started F....... inconsistência Finished in 0.610806 seconds. 1) Failure: test_should_authenticate_user(SessionsControllerTest) [/test/functional/ sessions_controller_test.rb:9]: Expected response to be a <:success>, but was <302> 8 tests, 11 assertions, 1 failures, 0 errors rake aborted! Command failed with status (1): [/opt/local/bin/ruby -I"lib:test" "/opt/loc...] (See full trace by running task with --trace) 127
  • 128
  • kiwitter $ rake test:functionals /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/ rake/rake_test_loader.rb" "test/functional/sessions_controller_test.rb" "test/ functional/users_controller_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/ rake_test_loader Started redirect não implica na F....... renderização da página de Finished in 0.99891 seconds. destino 1) Failure: test_should_authenticate_user(SessionsControllerTest) [/test/functional/ sessions_controller_test.rb:13]: expecting <"users/home"> but rendering with <""> 8 tests, 13 assertions, 1 failures, 0 errors rake aborted! Command failed with status (1): [/opt/local/bin/ruby -I"lib:test" "/opt/loc...] (See full trace by running task with --trace) 129
  • 130
  • kiwitter alegomes$ rake test:functionals /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/ gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/ functional/sessions_controller_test.rb" "test/functional/ users_controller_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/ lib/rake/rake_test_loader Started ........ Finished in 0.547148 seconds. 8 tests, 12 assertions, 0 failures, 0 errors 131
  • Labs Testar/implementar autenticação de usuário inválido @user não deve ser criada usuário deve ser redirecionado para página de login Testar/implementar post de mensagem 132
  • Testes de Integração 133
  • Req Controller 1 Req Controller 2 Req Controller 3 ? 134
  • Testes de Integração Testes de Aceitação 135
  • Integração desenvolvedores X linguagem ruby Aceitação clientes linguagem natural 136
  • TD não participa do ciclo de 137
  • {post, get, delete...}_via_redirect segue todos os redirects follow_redirect! segue apenas um redirect redirect? verifica se a última req foi redirect https! faz com que todas as reqs pareçam HTTPs host! altera o servidor da app 138
  • 139
  • kiwitter $ script/generate integration_test post_updates exists test/integration/ create test/integration/post_updates_test.rb 140
  • 141
  • kiwitter $ rake test:integration /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/ gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/ integration/post_updates_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/ lib/rake/rake_test_loader Started . Finished in 0.255598 seconds. 1 tests, 2 assertions, 0 failures, 0 errors 142
  • Lab? 143
  • Testes da View 144
  • assert_select 145
  • Tradeoff 146
  • assert_select("form") verifica a existência da tag <form> <span>Maré de Agilidade</span> assert_select("span", "Maré de Agilidade") assert_select("span", /Agilidade/) 147
  • 148
  • 149
  • 150
  • kiwitter $ rake test:integration /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/ gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/ integration/post_updates_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/ lib/rake/rake_test_loader Started . Finished in 0.943481 seconds. 1 tests, 3 assertions, 0 failures, 0 errors 151
  • 1) Failure: test_should_post_an_update(PostUpdatesTest) [/test/ integration/post_updates_test.rb:15]: Expected at least 1 element matching "div#welcome_messageeeeeeeee", found 0. <false> is not true. 1 tests, 3 assertions, 1 failures, 0 errors 152
  • Testes dos View Helpers 153
  • 154
  • 155
  • 156
  • kiwitter $ rake test:units /opt/local/bin/ruby -I"lib:test" "/opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/ rake_test_loader.rb" "test/unit/helpers/sessions_helper_test.rb" "test/unit/helpers/ updates_helper_test.rb" "test/unit/helpers/users_helper_test.rb" "test/unit/ update_test.rb" "test/unit/user_test.rb" Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader Started .......E Finished in 0.510089 seconds. 1) Error: test_should_display_user_greetings(UsersHelperTest): NoMethodError: undefined method `display_greetings' for #<UsersHelperTest: 0x1ba7e84> /test/unit/helpers/users_helper_test.rb:10:in `test_should_display_user_greetings' 8 tests, 8 assertions, 0 failures, 1 errors rake aborted! Command failed with status (1): [/opt/local/bin/ruby -I"lib:test" "/opt/loc...] (See full trace by running task with --trace) 157
  • 8 tests, 9 assertions, 0 failures, 0 errors 158
  • Bom senso 159
  • Testes de Rotas 160
  • ActionController::Assertions::RoutingAssertions assert_generates assert_generates "/items", :controller => "items", :action => "index" assert_recognizes assert_recognizes {:controller => 'items', :action => 'create'}, {:path => 'items', :method => :post} assert_routing assert_routing '/home', :controller => 'home', :action => 'index' http://api.rubyonrails.org/classes/ActionController/Assertions/RoutingAssertions.html 161
  • Labs View View Helper Routes 162
  • Mock Objects 163
  • Quem não tem cão... 164
  • ...caça com gato. 165
  • Objeto real indisponível ou de difícil acesso. Reprodução de cenários complexos. 166
  • Mocks Aren't Stubs The term 'Mock Objects' has become a popular one to describe special case objects that mimic real objects for testing. Most language environments now have frameworks that make it easy to create mock objects. What's often not realized, however, is that mock objects are but one form of special case test object, one that enables a different style of testing. In this article I'll explain how mock objects work, how they encourage testing based on behavior verification, and how the community around them uses them to develop a different style of testing. http://www.martinfowler.com/articles/mocksArentStubs.html 167
  • Stu 168
  • Objeto falso que retorna um valor predeterminado para uma chamada de método objeto.stubs(:metodo).and_returns("alguma coisa") “ignore a implementacao real de objeto.metodo e retorne ‘alguma coisa’” se objeto.metodo for invocado retornará "alguma coisa" se objeto.metodo NÃO for invocado nada acontecerá 169
  • 170
  • 17 tests, 28 assertions, 0 failures, 0 errors 171
  • 17 tests, 26 assertions, 1 failures, 0 errors 172
  • Moc 173
  • semelhante ao stub, com uma diferença objeto.stubs(:metodo).adn_returns("alguma coisa") se objeto.metodo for invocado retornará "alguma coisa" se objeto.metodo NÃO for invocado o teste falhará 174
  • 1) Failure: test_mock_example(UserTest) [/test/unit/user_test.rb:35]: not all expectations were satisfied unsatisfied expectations: - expected exactly once, not yet invoked: #<Mock:0x1884090>.email(any_parameters) satisfied expectations: - expected exactly once, already invoked once: #<Mock:0x1884090>.login(any_parameters) 9 tests, 12 assertions, 1 failures, 0 errors rake aborted! 175
  • 9 tests, 13 assertions, 0 failures, 0 errors 176
  • mocks returns raises any_instance with pattern matches 177
  • User.any_instance.expects(:login).returns(nil) user.login deve ser executado apenas uma única vez 178
  • user.expects(:login).once user.expects(:login).twice user.expects(:login).at_least_once user.expects(:login).at_most_once user.expects(:login).at_least(3) user.expects(:login).at_most(3) user.expects(:login).times(5) user.expects(:login).times(4..6) user.expects(:login).never 179
  • http://flexmock.rubyforge.org http://mocha.rubyforge.org http://double-ruby.rubyforge.org http://rspec.info 180
  • Labs Stubs e Mocks 181
  • http://thoughtbot.com/projects/shoulda 182
  • context setup do @u = .... end should “alguma coisa” do assert.... end end 183
  • $ sudo gem install thoughtbot-shoulda --source=http://gems.github.com Password: Successfully installed thoughtbot-shoulda-2.10.2 1 gem installed Installing ri documentation for thoughtbot-shoulda-2.10.2... Installing RDoc documentation for thoughtbot-shoulda-2.10.2... http://wiki.github.com/thoughtbot/shoulda/installation 184
  • require ‘shoulda‘ 185
  • http://dev.thoughtbot.com/shoulda/ 186
  • assert_accepts assert_contains assert_does_not_contain assert_rejects assert_same_elements http://dev.thoughtbot.com/shoulda/classes/Shoulda/Assertions.html 187
  • assert_bad_value assert_good_value assert_save assert_valid http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActiveRecord/Assertions.html 188
  • assert_did_not_send_email assert_sent_email http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActionMailer/Assertions.html 189
  • 190
  • should_change should_render_without_layout should_not_change should_respond_with should_assign_to should_respond_with_content_type should_filter_params should_return_from_session should_not_assign_to should_route should_not_set_the_flash should_set_session should_redirect_to should_set_the_flash_to should_render_template should_render_a_form should_render_with_layout should_render_page_with_metadata http://dev.thoughtbot.com/shoulda/classes/Shoulda/Macros.html http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActionController/Macros.html http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActionView/Macros.html 191
  • should_allow_mass_assignment_of should_have_named_scope should_allow_values_for should_have_one should_belong_to should_have_readonly_attributes should_ensure_length_at_least should_not_allow_mass_assignment_of should_ensure_length_in_range should_not_allow_values_for should_ensure_length_is should_only_allow_numeric_values_for should_ensure_value_in_range should_protect_attributes should_have_and_belong_to_many should_require_acceptance_of should_have_class_methods should_require_attributes should_have_db_column should_require_unique_attributes should_have_db_columns should_validate_acceptance_of should_have_index should_validate_numericality_of should_have_indices should_validate_presence_of should_have_instance_methods should_validate_uniqueness_of should_have_many http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActiveRecord/Macros.html 192
  • Lab 193
  • 194 “ RSpec is the original Behaviour Driven Development framework for Ruby. http://rspec.info
  • Test Driven * corretude qualidade < 100% = 100% rebola a ordem não no mato importa 195
  • testes passado descrição de algo pronto X especificação futuro descrição de algo inexistente 196
  • $ sudo gem install rspec Password: ************************************************** Thank you for installing rspec-1.2.8 Please be sure to read History.rdoc and Upgrade.rdoc for useful information about this release. ************************************************** Successfully installed rspec-1.2.8 1 gem installed Installing ri documentation for rspec-1.2.8... Installing RDoc documentation for rspec-1.2.8... (...) 197
  • kiwitter_rspec $ script/generate rspec exists lib/tasks create lib/tasks/rspec.rake create script/autospec create script/spec create script/spec_server exists spec create spec/rcov.opts create spec/spec.opts create spec/spec_helper.rb 198
  • kiwitter_rspec $ rake -T rake spec rake spec:plugin_doc rake spec:clobber_rcov rake spec:plugins rake spec:controllers rake spec:plugins:rspec_on_rails rake spec:db:fixtures:load rake spec:rcov rake spec:doc rake spec:server:restart rake spec:helpers rake spec:server:start rake spec:integration rake spec:server:status rake spec:lib rake spec:server:stop rake spec:models rake spec:views 199
  • describe funcionalidade it “should do A” do ... end it “should do B” do actual.should expected end ... end 200
  • 201
  • 202
  • should_not should have_at_most should be_true be_instance_of have_exactly should be_false should_not helper should be_nil be_an_instance_of should include should should be_close should_not include be_[arbitrary_predicate] should_not be_close inspect_object should_not be_nil be_instance_of should match should_not be_kind_of should_not match be_[arbitrary_predicate] should change should raise_error be_a should_not change should_not raise_error should be_kind_of should eql should respond_to should be_a_kind_of should_not eql should_not respond_to should_not be_kind_of should equal should satisfy should_not should_not equal should_not satisfy be_a_kind_of should exist simple_matcher be_an should_not exist should throw_symbol should be_instance_of should have should_not should should_not have throw_symbol be_an_instance_of should have_at_least wrap_expectation http://rspec.rubyforge.org/rspec/1.2.8/classes/Spec/Matchers.html 203
  • expected.XXXXX? expected.should be_XXXXX expected.should be_a_XXXXX expected.should be_an_XXXXX expected.should have_key(:k) expected.has_key?(:k) expected.should have(10).items expected.should have(10).laranjas expected.should have(10).filhos 204
  • 205
  • 206
  • $ sudo gem install rspec-rails Password: ************************************************** Thank you for installing rspec-rails-1.2.7.1 If you are upgrading, do this in each of your rails apps that you want to upgrade: $ ruby script/generate rspec Please be sure to read History.rdoc and Upgrade.rdoc for useful information about this release. ************************************************** Successfully installed rspec-rails-1.2.7.1 1 gem installed Installing ri documentation for rspec-rails-1.2.7.1... Installing RDoc documentation for rspec-rails-1.2.7.1... (...) 207
  • $ rails kiwitter_rspec create create app/controllers create app/helpers create app/models create app/views/layouts create config/environments create config/initializers create config/locales create db create doc (...) 208
  • kiwitter_rspec $ script/generate rspec_scaffold user login:string password:string email:string (...) create spec/controllers/ create spec/routing/ create spec/models/ create spec/helpers/ create spec/fixtures/ create spec/views/users create spec/integration/ (...) create spec/views/users/new.html.erb_spec.rb create spec/views/users/show.html.erb_spec.rb create spec/integration/users_spec.rb create db/migrate create db/migrate/20090802144903_create_users.rb route map.resources :users 209
  • script/generate rspec_scaffold update user:references message:text script/generate migration update_user_join 210
  • Mais testes gerados que o tradicional Test::Unit 211
  • alta especialização 212
  • Model Spec 213
  • Controller Spec 214
  • Controller Spec response.should response.should_not { be_success be_redirect redirect_to(url ou hash) render_template(‘users/home’) 215
  • View Spec 216
  • View Spec Test::Unit RSpec assigns(@user) assigns[:user] session[:user_id] session[:user_id] cookies[“user_id”] cookies[“user_id”] flash[:notice] flash[:notice] 217
  • View Spec { be_valid have_rjs response.should have_tag response.should_not have_text have_text send_email response.should have_tag “xxx” do ... end { with_encoded with_tag without_tag http://rspec.rubyforge.org/rspec-rails/1.2.7.1/classes/Spec/Rails/Matchers.html 218
  • Routing Spec ... 219
  • Helper Spec 220
  • { spec spec:controllers spec:helpers spec:integration rake spec:lib spec:models spec:plugins spec:views 221
  • kiwitter_rspec $ rake spec:models .. Finished in 1.703168 seconds 2 examples, 0 failures 222
  • Lab 223
  • faker Faker (...) is used to easily generate fake data http://faker.rubyforge.org 224
  • kiwitter $ sudo gem install faker Password: Successfully installed faker-0.3.1 1 gem installed Installing ri documentation for faker-0.3.1... Installing RDoc documentation for faker-0.3.1... 225
  • require ‘faker‘ 226
  • Maida McDermott April Metz Rowena Jakubowski Anita Lueilwitz Alena Ferry 227
  • puts Faker::Internet.email mia_schmidt@quigleycrist.ca nicolette@king.uk isaac@schmitt.info cade_buckridge@spinkajaskolski.com laurine@klein.name puts Faker::Address.zip_code 11695 72143 21715-9288 15719-7873 90548-7155 228
  • puts Faker::Lorem.paragraphs(2) Rerum quos hic et. Autem harum ea asperiores consequatur libero et. Ipsum cumque dicta optio voluptate. Et quia officia minus iure vitae. Ducimus delectus unde neque odio voluptas inventore minima. Fugiat nihil error incidunt nihil quo natus omnis. Quis consequatur aut totam ad. Doloribus nihil officiis nobis rerum tempora. Nam eos mollitia delectus assumenda veritatis. Itaque voluptatem repudiandae odit provident error ut. Perspiciatis est facilis sit quis et qui vel. Hic corrupti recusandae aliquid possimus. Et error ad ut voluptatem non labore. Accusantium non tempore aut assumenda architecto enim. Quasi eos et dicta. Tempore quia optio eos pariatur fugiat. Est neque molestias aliquid et. Dolor cum nemo tempora. Eum ratione esse quam magni officiis dolor. Earum maxime sit eaque optio laboriosam tempora voluptatibus. Quo illum ipsa sit. Ea sequi id et sunt nemo quibusdam maxime. Ab voluptate nesciunt maxime rerum iure explicabo in. Sed quidem dignissimos est officia necessitatibus sed qui. Similique odit qui id nostrum corporis autem quas enim. Sunt placeat eum architecto tempora non. Est libero aut repellat mollitia. Quisquam non quia et id est repellat qui aspernatur. Animi ut sit quaerat. Dignissimos enim esse autem qui sed aut optio a. Debitis facilis aut eaque alias exercitationem quia impedit. Maiores vitae id odio est inventore. Aut accusamus et et vel sint. Quo ducimus dolor nemo quia libero autem. Assumenda est voluptas debitis in libero. Illo sit deleniti tenetur nisi. Reiciendis et odit fugiat velit hic. Quo nisi deserunt sit. 229
  • http://faker.rubyforge.org/rdoc Array rand shuffle Faker::Address city city_prefix city_suffix secondary_address street_address street_name street_suffix uk_country uk_county uk_postcode us_state us_state_abbr zip_code Faker::Company bs catch_phrase name suffix Faker::Internet domain_name domain_suffix domain_word email free_email user_name Faker::Lorem paragraph paragraphs sentence sentences words Faker::Name first_name last_name name prefix suffix Faker::PhoneNumber phone_number 230
  • http://cukes.info 231
  • 232
  • DSL Rails Test Rails Code 233
  • DSL features scenarios Rails Test steps Rails Code 233
  • $ sudo gem install cucumber Password: Successfully installed term-ansicolor-1.0.4 Successfully installed polyglot-0.2.6 Successfully installed treetop-1.3.0 Successfully installed diff-lcs-1.1.2 Successfully installed builder-2.1.2 Successfully installed cucumber-0.3.92 6 gems installed Installing ri documentation for term-ansicolor-1.0.4... Installing ri documentation for polyglot-0.2.6... Installing ri documentation for treetop-1.3.0... (...) Installing RDoc documentation for diff-lcs-1.1.2... Installing RDoc documentation for builder-2.1.2... Installing RDoc documentation for cucumber-0.3.92... 234
  • kiwitter $ script/plugin install git://github.com/brynary/webrat.git Initialized empty Git repository in .../kiwitter/vendor/plugins/webrat/.git/ remote: Counting objects: 275, done. remote: Compressing objects: 100% (236/236), done. remote: Total 275 (delta 36), reused 170 (delta 20) Receiving objects: 100% (275/275), 5.07 MiB | 154 KiB/s, done. Resolving deltas: 100% (36/36), done. From git://github.com/brynary/webrat * branch HEAD -> FETCH_HEAD = Webrat - Ruby Acceptance Testing for Web applications ... == Description Webrat lets you quickly write expressive and robust acceptance tests for a Ruby web application. 235
  • kiwitter $ sudo gem install nokogiri Building native extensions. This could take a while... Successfully installed nokogiri-1.3.3 1 gem installed Installing ri documentation for nokogiri-1.3.3... Installing RDoc documentation for nokogiri-1.3.3... 236
  • kiwitter $ script/generate cucumber create features/step_definitions create features/step_definitions/webrat_steps.rb create config/environments/cucumber.rb create features/support create features/support/env.rb create features/support/paths.rb exists lib/tasks create lib/tasks/cucumber.rake create script/cucumber 237
  • Feature: caso de uso/estória em teste In order objetivo da funcionalidade Stakeholder o que o stakeholder deseja Background Given pré-condições And mais pré-condições | login | email | password | | alegomes | alegomes@gmail.com | ale123 | | luciana | lu@brasilia.net | xuxu | Scenario: cenário/fluxo em teste Given pré-condições When ação do usuário Then resultado da ação do usuário 238
  • kiwitter $ script/generate feature users_and_updates exists features/step_definitions create features/manage_users_and_updates.feature create features/step_definitions/users_and_updates_steps.rb 239
  • DSL Rails Test Rails Code 240
  • Teste de aceitação gerado pelo Cucumber 241
  • modificado para o kiwitter 242
  • kiwitter $ rake features /opt/local/bin/ruby -I "/opt/local/lib/ruby/gems/1.8/gems/cucumber-0.3.92/lib:lib" "/opt/local/lib/ ruby/gems/1.8/gems/cucumber-0.3.92/bin/cucumber" --format pretty features/ manage_users_and_updates.feature Feature: Post update messages In order to make my life widely public As a User I want to post short messages describing what I am doing Scenario: Post new messages # features/manage_users_and_updates.feature:6 Given I am at users home page # features/manage_users_and_updates.feature:7 And I have entered a text message up to 140 chars # features/manage_users_and_updates.feature:8 When I press post # features/manage_users_and_updates.feature:9 Then the message should be registered # features/manage_users_and_updates.feature:10 1 scenario (1 undefined) 4 steps (4 undefined) 0m0.653s ... 243
  • ... You can implement step definitions for undefined steps with these snippets: Given /^I am at users home page$/ do pending end Given /^I have entered a text message up to 140 chars$/ do pending end When /^I press post$/ do pending end Then /^the message should be registered$/ do pending end 244
  • DSL Rails Test Rails Code 245
  • Feature steps gerados pelo script/generate feature 246
  • ... You can implement step definitions for undefined steps with these snippets: Given /^I am at users home page$/ do pending end Given /^I have entered a text message up to 140 chars$/ do pending end When /^I press post$/ do pending end Then /^the message should be registered$/ do pending end 247
  • kiwitter $ rake features /opt/local/bin/ruby -I "/opt/local/lib/ruby/gems/1.8/gems/cucumber-0.3.92/lib:lib" "/opt/ local/lib/ruby/gems/1.8/gems/cucumber-0.3.92/bin/cucumber" --format pretty features/ manage_users_and_updates.feature Feature: Post update messages In order to make my life widely public As a User I want to post short messages describing what I am doing Scenario: Post new messages Given I am at users home page TODO (Cucumber::Pending) features/manage_users_and_updates.feature:7:in `Given I am at users home page' And I have entered a text message up to 140 chars When I press post Then the message should be registered 1 scenario (1 pending) 4 steps (3 skipped, 1 pending) 0m0.134s 248
  • Given I am at users home page TODO (Cucumber::Pending) features/manage_users_and_updates.feature:7:in `Given I am at users home page' Given /^I am at users home page$/ do visit "users/home" end 249
  • kiwitter $ rake features ... Scenario: Post new messages users_controller.home Given I am at users home page And I have entered a text message up to 140 chars TODO (Cucumber::Pending) features/manage_users_and_updates.feature:8:in `And I have entered a text message up to 140 chars' When I press post Then the message should be registered 1 scenario (1 pending) 4 steps (2 skipped, 1 pending, 1 passed) 0m0.260s 250
  • And I have entered a text message up to 140 chars TODO (Cucumber::Pending) features/manage_users_and_updates.feature:8:in `And I have entered a text message up to 140 chars' 251
  • kiwitter $ cucumber features/manage_users_and_updates.feature Feature: Post update messages In order to make my life widely public As a User I want to post short messages describing what I am doing Scenario: Post new messages users_controller.home Given I am at users home page And I have entered a text message up to 140 chars When I press post TODO (Cucumber::Pending) features/manage_users_and_updates.feature:9:in `When I press post' Then the message should be registered 1 scenario (1 pending) 4 steps (1 skipped, 1 pending, 2 passed) 0m0.305s 252
  • When I press post TODO (Cucumber::Pending) features/manage_users_and_updates.feature:9:in `When I press post' 253
  • kiwitter $ cucumber features/manage_users_and_updates.feature Feature: Post update messages In order to make my life widely public As a User I want to post short messages describing what I am doing Scenario: Post new messages users_controller.home Given I am at users home page And I have entered a text message up to 140 chars When I press post Then the message should be registered TODO (Cucumber::Pending) features/manage_users_and_updates.feature:10:in `Then the message should be registered' 1 scenario (1 pending) 4 steps (1 pending, 3 passed) 0m0.282s 254
  • Then the message should be registered TODO (Cucumber::Pending) features/manage_users_and_updates.feature:10:in `Then the message should be registered' ? 255
  • webrat http://github.com/brynary/webrat/tree/master 256
  • kiwitter $ script/plugin install git://github.com/brynary/webrat.git Initialized empty Git repository in .../kiwitter/vendor/plugins/webrat/.git/ remote: Counting objects: 275, done. remote: Compressing objects: 100% (236/236), done. remote: Total 275 (delta 36), reused 170 (delta 20) Receiving objects: 100% (275/275), 5.07 MiB | 125 KiB/s, done. Resolving deltas: 100% (36/36), done. From git://github.com/brynary/webrat * branch HEAD -> FETCH_HEAD (= Webrat - Ruby Acceptance Testing for Web applications - http://gitrdoc.com/brynary/webrat - http://groups.google.com/group/webrat - http://webrat.lighthouseapp.com/ - http://github.com/brynary/webrat - #webrat on Freenode (...) 257
  • http://www.zenspider.com/ZSS/Products/ZenTest/ 258
  • http://www.michaelleung.us/koujou 259
  • http://eigenclass.org/hiki/rcov 260
  • $ sudo gem install rcov Password: Building native extensions. This could take a while... Successfully installed rcov-0.8.1.2.0 1 gem installed Installing ri documentation for rcov-0.8.1.2.0... Installing RDoc documentation for rcov-0.8.1.2.0... 261
  • $ rcov --version rcov 0.8.1.2 2007-11-22 262
  • kiwitter $ ./script/plugin install --force http://svn.codahale.com/rails_rcov + ./MIT-LICENSE + ./README + ./tasks/rails_rcov.rake http://agilewebdevelopment.com/plugins/rails_rcov 263
  • kiwitter $ rake -T | grep rcov rake doc:plugins:rails_rcov rake test:profile:clobber_rcov rake spec:clobber_rcov rake test:profile:rcov rake spec:rcov rake test:recent:clobber_rcov rake test:benchmark:clobber_rcov rake test:recent:rcov rake test:benchmark:rcov rake test:test:clobber_rcov rake test:functionals:clobber_rcov rake test:test:rcov rake test:functionals:rcov rake test:uncommitted:clobber_rcov rake test:integration:clobber_rcov rake test:uncommitted:rcov rake test:integration:rcov rake test:units:clobber_rcov rake test:plugins:clobber_rcov rake test:units:rcov rake test:plugins:rcov 264
  • kiwitter $ rake test:units:rcov 10 tests, 13 assertions, 1 failures, 1 errors +----------------------------------------------------+-------+-------+--------+ | File | Lines | LOC | COV | +----------------------------------------------------+-------+-------+--------+ |.../ruby/1.8/gems/sqlite3-ruby-1.2.5/lib/sqlite3.rb | 1 | 1 | 100.0% | |...gems/sqlite3-ruby-1.2.5/lib/sqlite3/constants.rb | 49 | 44 | 97.7% | |.../gems/sqlite3-ruby-1.2.5/lib/sqlite3/database.rb | 721 | 340 | 40.3% | |...3-ruby-1.2.5/lib/sqlite3/driver/native/driver.rb | 219 | 180 | 48.3% | |....8/gems/sqlite3-ruby-1.2.5/lib/sqlite3/errors.rb | 68 | 58 | 84.5% | |...8/gems/sqlite3-ruby-1.2.5/lib/sqlite3/pragmas.rb | 271 | 190 | 45.8% | |...gems/sqlite3-ruby-1.2.5/lib/sqlite3/resultset.rb | 180 | 114 | 72.8% | |...gems/sqlite3-ruby-1.2.5/lib/sqlite3/statement.rb | 231 | 128 | 50.0% | |...ems/sqlite3-ruby-1.2.5/lib/sqlite3/translator.rb | 109 | 64 | 20.3% | |...1.8/gems/sqlite3-ruby-1.2.5/lib/sqlite3/value.rb | 57 | 44 | 29.5% | |app/controllers/application_controller.rb | 48 | 21 | 23.8% | |app/controllers/sessions_controller.rb | 32 | 9 | 22.2% | |app/controllers/updates_controller.rb | 85 | 60 | 13.3% | |app/controllers/users_controller.rb | 89 | 63 | 14.3% | |app/helpers/application_helper.rb | 3 | 2 | 100.0% | |app/helpers/sessions_helper.rb | 3 | 2 | 100.0% | |app/helpers/updates_helper.rb | 2 | 2 | 100.0% | |app/helpers/users_helper.rb | 8 | 5 | 40.0% | |app/models/update.rb | 5 | 4 | 100.0% | |app/models/user.rb | 8 | 6 | 100.0% | +----------------------------------------------------+-------+-------+--------+ |Total | 2189 | 1337 | 46.3% | 265 +----------------------------------------------------+-------+-------+--------+
  • 266
  • Q&A