Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Minicurso de TestesOnRails

2,840 views

Published on

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

Published in: Technology, Business

Minicurso de TestesOnRails

  1. 1. Mini-Curso TestesOnRails Desenvolvimento Orientado a Testes em Rails 1
  2. 2. 2
  3. 3. Disclaimer 3
  4. 4. http://www.railsrx.com 4
  5. 5. O que testar? Quando testar? Quanto testar? Quantos asserts por teste? Teste quebrado mudar teste ou código? 5
  6. 6. 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
  7. 7. Em teoria... 7
  8. 8. Testes
  9. 9. Desenvolver Testar
  10. 10. Desenvolver Testar
  11. 11. ?
  12. 12. ?
  13. 13. $? ?
  14. 14. $ cr iaç ão de sc ob er ta co rr eç ão
  15. 15. X
  16. 16. Testes Automáticos
  17. 17. Programa
  18. 18. Teste Programa
  19. 19. Teste Programa
  20. 20. Teste Programa
  21. 21. (...) 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 } (...)
  22. 22. (...) 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 } (...)
  23. 23. (...) 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 } (...)
  24. 24. (...) 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 } (...)
  25. 25. vale a pena ?
  26. 26. X
  27. 27. X
  28. 28. X
  29. 29. 10 30
  30. 30. 10 20 30 30
  31. 31. 10 20 30 30 30 30
  32. 32. 10 20 30 40 30 30 30 30
  33. 33. 10 20 30 40 50 30 30 30 30 30
  34. 34. 10 20 30 40 50 60 30 30 30 30 30 30
  35. 35. 10 20 30 40 50 60 70 30 30 30 30 30 30 30
  36. 36. 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"; } } }
  37. 37. 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"; } }
  38. 38. 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"; } }
  39. 39. 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"; } }
  40. 40. evolvability maintainability mantenabilidade manutenibilidade manutenabilidade capacidade de manutenção
  41. 41. Custo Tempo
  42. 42. Custo Tempo
  43. 43. Test Driven Development
  44. 44. GREEN
  45. 45. RED teste GREEN
  46. 46. RED código teste GREEN
  47. 47. RED código teste GREEN refactoring
  48. 48. RED GREEN
  49. 49. RED Plan GREEN
  50. 50. RED Plan Do GREEN
  51. 51. RED Plan Do GREEN Check
  52. 52. RED Plan Do Act GREEN Check
  53. 53. Design Evolutivo
  54. 54. ?
  55. 55. RED GREEN
  56. 56. Foco RED GREEN
  57. 57. Foco Ritmo RED GREEN
  58. 58. Foco Ritmo RED Disciplina GREEN
  59. 59. Foco Ritmo RED Disciplina Simplicidade GREEN
  60. 60. Ferramentas (Java)
  61. 61. Unidade
  62. 62. Bancos de Dados
  63. 63. Aceitação
  64. 64. Aplicações WEB Selenium
  65. 65. Performance (WEB)
  66. 66. Testes Testes Automáticos Desenvolvimento Orientado a Testes Design Evolutivo Ferramentas 46
  67. 67. 47
  68. 68. http://www.railsrx.com 48
  69. 69. Quando se fala de testes, fala-se de... Mudanças Corretude Direcionamento Robustez Design evolutivo Documentação 49
  70. 70. O que testar? caminho feliz caminhos alternativos erros conhecidos e esperados 50
  71. 71. 51
  72. 72. TestesOnRails 52
  73. 73. 53
  74. 74. Kiwitter 54
  75. 75. $ 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
  76. 76. 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
  77. 77. 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
  78. 78. kiwitter $ rake db:migrate (in ...maredeagilidade_ceara/labs/rails_test/kiwitter) == CreateUsers: migrating ======================================== -- create_table(:users) -> 0.0082s == CreateUsers: migrated (0.0094s) ================================= 58
  79. 79. Unit Functional Integration Performance Tests 59
  80. 80. 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
  81. 81. kiwitter $ rake test:units Started ........FE Finished in 1.181401 seconds. 61
  82. 82. ........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
  83. 83. ........FE 2) Error: test_should_display_user_greetings( UsersHelperTest): ArgumentError: wrong number of arguments (1 for 0) 63
  84. 84. Rails environments test development production 64
  85. 85. 65
  86. 86. Fixtures 66
  87. 87. 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
  88. 88. 68
  89. 89. http://ar.rubyonrails.org/classes/Fixtures.html 69
  90. 90. 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
  91. 91. 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
  92. 92. ios ár n it s U s t e Te 72
  93. 93. Test::Unit::TestCase ActiveSupport::TestCase + Rails Unit Tests 73
  94. 94. Rails Unit Tests 1. fixtures 2. setup 3. test/unit/*_test.rb 4. teardown 74
  95. 95. 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
  96. 96. http://ruby-doc.org/stdlib/ 76
  97. 97. http://api.rubyonrails.org/ 77
  98. 98. 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
  99. 99. Kiwitter 79
  100. 100. Kiwitter 80
  101. 101. 81
  102. 102. 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
  103. 103. 83
  104. 104. 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
  105. 105. 85
  106. 106. 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
  107. 107. 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
  108. 108. 88
  109. 109. 89
  110. 110. 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
  111. 111. 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
  112. 112. 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
  113. 113. 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
  114. 114. Quem espera false? 94
  115. 115. 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
  116. 116. Refactoring 96
  117. 117. 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
  118. 118. 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
  119. 119. Fixtures mecanismo para criação de massa de dados de testes 99
  120. 120. 100
  121. 121. 101
  122. 122. 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
  123. 123. Labs Testes unitários como TDD para criação (post) de mensagens (update) por um usuário 103
  124. 124. Testes Funcionais 104
  125. 125. HTTP Req ? 105
  126. 126. Test::Unit::TestCase ActiveSupport::TestCase + ActiveController::TestCase + Rails Functional Tests 106
  127. 127. 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
  128. 128. 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
  129. 129. 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
  130. 130. Não testa rotas! *Sempre* enviar parâmetros HTTP como string 110
  131. 131. st atus assert_ response ‘c onteúdo’ assert_t emplate ionam ento redirec t asser t_redirec 111
  132. 132. 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
  133. 133. Unit Tests Functional Tests 113
  134. 134. Kiwitter 114
  135. 135. Kiwitter 115
  136. 136. 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
  137. 137. 117
  138. 138. 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
  139. 139. 119
  140. 140. 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
  141. 141. 121
  142. 142. 122
  143. 143. 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
  144. 144. 124
  145. 145. 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
  146. 146. 126
  147. 147. 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
  148. 148. 128
  149. 149. 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
  150. 150. 130
  151. 151. 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
  152. 152. 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
  153. 153. Testes de Integração 133
  154. 154. Req Controller 1 Req Controller 2 Req Controller 3 ? 134
  155. 155. Testes de Integração Testes de Aceitação 135
  156. 156. Integração desenvolvedores X linguagem ruby Aceitação clientes linguagem natural 136
  157. 157. TD não participa do ciclo de 137
  158. 158. {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
  159. 159. 139
  160. 160. kiwitter $ script/generate integration_test post_updates exists test/integration/ create test/integration/post_updates_test.rb 140
  161. 161. 141
  162. 162. 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
  163. 163. Lab? 143
  164. 164. Testes da View 144
  165. 165. assert_select 145
  166. 166. Tradeoff 146
  167. 167. 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
  168. 168. 148
  169. 169. 149
  170. 170. 150
  171. 171. 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
  172. 172. 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
  173. 173. Testes dos View Helpers 153
  174. 174. 154
  175. 175. 155
  176. 176. 156
  177. 177. 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
  178. 178. 8 tests, 9 assertions, 0 failures, 0 errors 158
  179. 179. Bom senso 159
  180. 180. Testes de Rotas 160
  181. 181. 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
  182. 182. Labs View View Helper Routes 162
  183. 183. Mock Objects 163
  184. 184. Quem não tem cão... 164
  185. 185. ...caça com gato. 165
  186. 186. Objeto real indisponível ou de difícil acesso. Reprodução de cenários complexos. 166
  187. 187. 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
  188. 188. Stu 168
  189. 189. 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
  190. 190. 170
  191. 191. 17 tests, 28 assertions, 0 failures, 0 errors 171
  192. 192. 17 tests, 26 assertions, 1 failures, 0 errors 172
  193. 193. Moc 173
  194. 194. 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
  195. 195. 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
  196. 196. 9 tests, 13 assertions, 0 failures, 0 errors 176
  197. 197. mocks returns raises any_instance with pattern matches 177
  198. 198. User.any_instance.expects(:login).returns(nil) user.login deve ser executado apenas uma única vez 178
  199. 199. 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
  200. 200. http://flexmock.rubyforge.org http://mocha.rubyforge.org http://double-ruby.rubyforge.org http://rspec.info 180
  201. 201. Labs Stubs e Mocks 181
  202. 202. http://thoughtbot.com/projects/shoulda 182
  203. 203. context setup do @u = .... end should “alguma coisa” do assert.... end end 183
  204. 204. $ 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
  205. 205. require ‘shoulda‘ 185
  206. 206. http://dev.thoughtbot.com/shoulda/ 186
  207. 207. assert_accepts assert_contains assert_does_not_contain assert_rejects assert_same_elements http://dev.thoughtbot.com/shoulda/classes/Shoulda/Assertions.html 187
  208. 208. assert_bad_value assert_good_value assert_save assert_valid http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActiveRecord/Assertions.html 188
  209. 209. assert_did_not_send_email assert_sent_email http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActionMailer/Assertions.html 189
  210. 210. 190
  211. 211. 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
  212. 212. 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
  213. 213. Lab 193
  214. 214. 194 “ RSpec is the original Behaviour Driven Development framework for Ruby. http://rspec.info
  215. 215. Test Driven * corretude qualidade < 100% = 100% rebola a ordem não no mato importa 195
  216. 216. testes passado descrição de algo pronto X especificação futuro descrição de algo inexistente 196
  217. 217. $ 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
  218. 218. 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
  219. 219. 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
  220. 220. describe funcionalidade it “should do A” do ... end it “should do B” do actual.should expected end ... end 200
  221. 221. 201
  222. 222. 202
  223. 223. 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
  224. 224. 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
  225. 225. 205
  226. 226. 206
  227. 227. $ 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
  228. 228. $ 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
  229. 229. 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
  230. 230. script/generate rspec_scaffold update user:references message:text script/generate migration update_user_join 210
  231. 231. Mais testes gerados que o tradicional Test::Unit 211
  232. 232. alta especialização 212
  233. 233. Model Spec 213
  234. 234. Controller Spec 214
  235. 235. Controller Spec response.should response.should_not { be_success be_redirect redirect_to(url ou hash) render_template(‘users/home’) 215
  236. 236. View Spec 216
  237. 237. 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
  238. 238. 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
  239. 239. Routing Spec ... 219
  240. 240. Helper Spec 220
  241. 241. { spec spec:controllers spec:helpers spec:integration rake spec:lib spec:models spec:plugins spec:views 221
  242. 242. kiwitter_rspec $ rake spec:models .. Finished in 1.703168 seconds 2 examples, 0 failures 222
  243. 243. Lab 223
  244. 244. faker Faker (...) is used to easily generate fake data http://faker.rubyforge.org 224
  245. 245. 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
  246. 246. require ‘faker‘ 226
  247. 247. Maida McDermott April Metz Rowena Jakubowski Anita Lueilwitz Alena Ferry 227
  248. 248. 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
  249. 249. 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
  250. 250. 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
  251. 251. http://cukes.info 231
  252. 252. 232
  253. 253. DSL Rails Test Rails Code 233
  254. 254. DSL features scenarios Rails Test steps Rails Code 233
  255. 255. $ 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
  256. 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 | 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
  257. 257. 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
  258. 258. 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
  259. 259. 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
  260. 260. 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
  261. 261. DSL Rails Test Rails Code 240
  262. 262. Teste de aceitação gerado pelo Cucumber 241
  263. 263. modificado para o kiwitter 242
  264. 264. 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
  265. 265. ... 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
  266. 266. DSL Rails Test Rails Code 245
  267. 267. Feature steps gerados pelo script/generate feature 246
  268. 268. ... 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
  269. 269. 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
  270. 270. 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
  271. 271. 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
  272. 272. 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
  273. 273. 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
  274. 274. When I press post TODO (Cucumber::Pending) features/manage_users_and_updates.feature:9:in `When I press post' 253
  275. 275. 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
  276. 276. Then the message should be registered TODO (Cucumber::Pending) features/manage_users_and_updates.feature:10:in `Then the message should be registered' ? 255
  277. 277. webrat http://github.com/brynary/webrat/tree/master 256
  278. 278. 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
  279. 279. http://www.zenspider.com/ZSS/Products/ZenTest/ 258
  280. 280. http://www.michaelleung.us/koujou 259
  281. 281. http://eigenclass.org/hiki/rcov 260
  282. 282. $ 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
  283. 283. $ rcov --version rcov 0.8.1.2 2007-11-22 262
  284. 284. 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
  285. 285. 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
  286. 286. 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 +----------------------------------------------------+-------+-------+--------+
  287. 287. 266
  288. 288. Q&A

×