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.

Boas práticas de Automação de Testes

6,285 views

Published on

Apresentação realizada no Agile Brazil 2012 por Camilo Ribeiro e Carlos Palhares

Published in: Technology
  • Be the first to comment

Boas práticas de Automação de Testes

  1. 1. Boas Práticas de Automação de Testes
  2. 2. Camilo Ribeiro Sr. QA Consultant na ThoughtWorks Developer e Devops nos fins de semana Blogger www.bugbang.com.br about.me/camiloribeiro @camiloribeiro github.com/camiloribeiro http://join.thoughtworks.com/profiles/camilo-ribeiroPrivate and Confidential. © 2011 ThoughtWorks, Ltd. All rights reserved.
  3. 3. Carlos Palhares Development Consultant na ThoughtWorks Developer nos finais de semana cpalhares@thoughtworks.com xjunior.me twitter.com/xjunior github.com/xjuniorPrivate and Confidential. © 2011 ThoughtWorks, Ltd. All rights reserved.
  4. 4. ~ 2.000Twers 25 escritórios 11 países 1 culturahttp://social-impact.thoughtworks.com/Private and Confidential. © 2011 ThoughtWorks, Ltd. All rights reserved.
  5. 5. Por que automatizar?
  6. 6. Record and Replay
  7. 7. require watir-webdriverbrowser = Watir::Browser.new :firefoxbrowser.goto "http://google.com.br"browser.text_field(:name => q).set(Automação Rocks!)browser.button(:name => btnG).clicksleep 1if browser.text.include? The Bug Bang Theory 2.0puts Sucesselse puts failendbrowser.close
  8. 8. require watir-webdriverbrowser = Watir::Browser.new :firefoxbrowser.goto "http://google.com.br"browser.text_field(:name => q).set(Automação Rocks!)browser.button(:name => btnG).clicksleep 1if browser.text.include? The Bug Bang Theory 2.0puts Sucesselse puts failendbrowser.close
  9. 9. Record and Replay
  10. 10. Bare Sleep
  11. 11. //pseudo-codeclick_login_button();fill_user(“Mario”);
  12. 12. //pseudo-codeclick_login_button();fill_user(“Mario”);Erro: Campo “user” não encontrado
  13. 13. //pseudo-codeclick_login_button();sleep(3000)fill_user(“Mario”);
  14. 14. Testes LentosTestes Irreais
  15. 15. Bare Sleep
  16. 16. Keep Pooling / Implicit Wait Time
  17. 17. //pseudo-code click_login_button(); TIMEOUT.times do break if user_field.present? sleep 1 end fill_user(“Mario”);http://martinfowler.com/articles/nonDeterminism.html
  18. 18. require selenium-webdriverdriver = Selenium::WebDriver.for :firefoxdriver.manage.timeouts.implicit_wait = TIMEOUTclick_login_buttonelement = driver.find_element(:id => ”user")http://seleniumhq.org/docs/04_webdriver_advanced.html
  19. 19. Lack of Isolation
  20. 20. Teste 1 – Verifica Soma dos produtos cadastrados: Produto A = 100,00 Produto B = 50,00 Soma produtos = 150,00 Teste 2 – Cadastra um novo produto: Cadastra Produto C = 200,00 Verifica se existe um produto chamado “Produto C”http://martinfowler.com/articles/nonDeterminism.html
  21. 21. Ordem dos testes: Verificando soma dos produtos Cadastrando novo produto
  22. 22. Produtos Verificando soma dos produtos A soma dos produtos deve ser 150 Cadastrando novo produto Devo cadastrar o produto C
  23. 23. Ordem dos testes: Cadastrando novo produto Verificando soma dos produtos
  24. 24. Produtos Cadastrando novo produto Devo cadastrar o produto C Verificando soma dos produtos A soma dos produtos deve ser 150ExpectationNotMetError: expected: 4Experado = 150,00Resultado = 350,00
  25. 25. Testes isolados
  26. 26. Cenário: Cadastrar produtos Dado que eu estou na página de cadastro de produtos Quando eu cadastro o produto “C” E salvo Então eu devo ver o produto cadastradoCenário: Verificar soma dos produtos Dado que os produtos A e B estão cadastrados Quando eu solicito ver o valor total dos produtos Então eu devo ver o valor total como 150,00
  27. 27. Ordem dos testes: Verificando soma dos produtos Cadastrando novo produto
  28. 28. Cenário: Verificar soma dos produtos Dado que os produtos A e B estão cadastrados Quando eu solicito ver o valor total dos produtos Então eu devo ver o valor total como 150,00Cenário: Cadastrar produtos Dado que eu estou na página de cadastro de produtos Quando eu cadastro o produto “C” E salvo Então eu devo ver o produto cadastrado
  29. 29. Ordem dos testes: Cadastrando novo produto Verificando soma dos produtos
  30. 30. Cenário: Cadastrar produtos Dado que eu estou na página de cadastro de produtos Quando eu cadastro o produto “C” E salvo Então eu devo ver o produto cadastradoCenário: Verificar soma dos produtos Dado que os produtos A e B estão cadastrados Quando eu solicito ver o valor total dos produtos Então eu devo ver o valor total como 150,00
  31. 31. Given When Then
  32. 32. Given I have an amazing chocolate (and I love it!)
  33. 33. When I eat the chocolate (Uhmm *.*)
  34. 34. Then there is no more chocolate :(
  35. 35. Clean up your mess
  36. 36. DRY – Don’t Repeat Yourself(and don’t reinvent the wheel)
  37. 37. Data-Driven Testing
  38. 38. http://xunitpatterns.com/Data-Driven%20Test.html
  39. 39. var lado1 = 10var lado2 = 10var lado3 = 10mathService.isTriangulo(lado1, lado2, lado3).should().beTruth()mathService.tipoTriangulo(lado1, lado2, lado3).should().be(‘equilatero’)var lado1 = 3var lado2 = 4var lado3 = 5mathService.isTriangulo(lado1, lado2, lado3).should().beTruth()mathService.tipoTriangulo(lado1, lado2, lado3).should().be(‘isóceles’)var lado1 = 4var lado2 = 4var lado3 = 5mathService.isTriangulo(lado1, lado2, lado3).should().beTruth()mathService.tipoTriangulo(lado1, lado2, lado3).should().be(‘escaleno’)…
  40. 40. var arquivo = File.read(“dados.csv”)arquivo.each do var lado1 = arquivo[‘lado 1’] var lado2 = arquivo[‘lado 2’] var lado3 = arquivo[‘lado 3’] var tipoTriangulo = arquivo[‘tipo esperado’] mathService.isTriangulo(lado1, lado2, lado3).should().beTruth() var tipoRetornado = mathService.tipoTriangulo(lado1, lado2, lado3) tipoRetornado.should().be(tipoTriangulo)end
  41. 41. Factory Pattern
  42. 42. http://blog.fossmo.net/post/What-is-the-factory-method-pattern.aspx
  43. 43. FactoryGirl.define do factory :candidate do name Candidato Fulano de Tal short_name Fulano Legal role Vereadorend factory :candidate_without_role, :parent => :candidate do after(:build) do |candidate| candidate.role = nil end endhttps://github.com/thoughtworks/voto-como-vamos
  44. 44. Separation Of Concerns
  45. 45. require watir-webdriver browser = Watir::Browser.new :firefox browser.goto "http://google.com.br" browser.text_field(:name => q).set(Automação Rocks!) browser.button(:name => btnG).click sleep 1 if browser.text.include? The Bug Bang Theory 2.0 puts Sucess else puts fail end browser.closehttp://www.bugbang.com.br/?p=2108
  46. 46. Mais vinte testes por favor 
  47. 47. require watir-webdriver browser = Watir::Browser.new :firefox browser.goto "http://google.com.br" browser.text_field(:name => q).set(Automação Rocks!) browser.button(:name => btnG).click if browser.text.include? The Bug Bang Theory 2.0 puts Sucess else puts fail end browser.close browser = Watir::Browser.new :firefox browser.goto "http://google.com.br" browser.text_field(:name => q).set(Selenium history) browser.button(:name => btnG).click if browser.text.include? ThoughtWorks puts Sucess else puts fail end browser.close browser = Watir::Browser.new :firefox browser.goto "http://google.com.br" browser.text_field(:name => q).set(Desafio Selenium) browser.button(:name => btnG).click if browser.text.include? sembugs.blogspot.com.br puts Sucess else puts fail end browser.closehttp://www.bugbang.com.br/?p=2108
  48. 48. Page-Object Model
  49. 49. Test FlowPage 1 Page 2 ………… Page N
  50. 50. module Search class HomePage @url = “www.google.com” @search_field = “q” @search_button = “search” def input_search(value) @browser.text_field(:name => @search_field).set value end def run_search @browser.button(:class => @search_button).click return ResultPage.new end def visit @browser endendhttp://www.bugbang.com.br/?p=2108
  51. 51. module Search class HomePage Elementos da página como atributos @url = “www.google.com” @search_field = “q” @search_button = “search” def input_search(value) @browser.text_field(:name => @search_field).set value end def run_search @browser.button(:class => @search_button).click return ResultPage.new end def visit @browser endendhttp://www.bugbang.com.br/?p=2108
  52. 52. module Search class HomePage @url = “www.google.com” @search_field = “q” @search_button = “search” def input_search(value) @browser.text_field(:name => @search_field).set value end def run_search @browser.button(:class => @search_button).click return ResultPage.new end Comportamentos como contrato def visit @browser endendhttp://www.bugbang.com.br/?p=2108
  53. 53. @page = Search.HomePage.new @page.visit @page.input_search(“xjunior.me”) @resultPage = @page.search @first = @resultPage.results.first @first.title.should eq(“Carlos Palhares”)http://www.bugbang.com.br/?p=2108
  54. 54. Lendo e aprendendo 
  55. 55. Resumindo…* Codigo de teste também é código; - (quase) todas as boas práticas se aplicam* Don’t Repeat yourself!* Código de teste deve ser uma represetaçãoautomática da interação do usuário - Seu sistema pode não dar feedback suficiente
  56. 56. Dúvidas?
  57. 57. We are hiring! http://join.thoughtworks.com/
  58. 58. Muito Obrigado!!! Envie o seu Feedback e dúvidas para: cribeiro@thoughtworks.com cpalhares@thoughtworks.comPrivate and Confidential. © 2011 ThoughtWorks, Ltd. All rights reserved.

×