Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pirâmide de Teste

2c5f73ce08b339317d69892fd6db84db?s=47 Randson
January 26, 2017

Pirâmide de Teste

2c5f73ce08b339317d69892fd6db84db?s=128

Randson

January 26, 2017
Tweet

More Decks by Randson

Other Decks in Programming

Transcript

  1. Pirâmide de Testes Domine a arte de entregar software com

    qualidade.
  2. Randson Oliveira twitter.com/rands0n github.com/rands0n speakerdeck.com/rands0n

  3. O que veremos? Por que fazer testes? Qualidade de testes

    Mocks e Stubs Alguns exemplos a mais…
  4. Por que fazer testes? Manter o projeto em níveis saudáveis

    Ajudar na qualidade externa Ajudar na qualidade interna
  5. Qualidade de testes Como posso avaliar se meu teste ou

    suíte está com qualidade?
  6. Corretude O teste está verificando o comportamento correto do meu

    código?
  7. describe Stack do describe '#push' do it 'puts an element

    at the top of the Stack' do stack = Stack.new stack.push 1 stack.push 2 expect(stack.top).to eq 1 end end end describe Stack do describe '#push' do it 'puts an element at the top of the Stack' do stack = Stack.new stack.push 1 stack.push 2 expect(stack.top).to eq 2 end end end Teste errado Teste correto
  8. Adequação do tipo de teste O teste foi feito com

    o tipo mais adequado? Aceitação, integração ou unitário?
  9. Aceitação Testa um requisito funcional, normalmente feito pela UI

  10. São sobre o domínio do problema(regras de negócio), não sobre

    o domínio de UI
  11. feature 'Users make the To do complete' do scenario 'update

    todos as completed' do sign_in create_todo 'Buy me a beer' find('.todos li', text: 'Buy me a beer').click_on 'Mark complete' expect(page).to have_css('.todos li.completed', text: 'Buy me a beer') end end
  12. feature 'Users make the To do complete' do scenario 'update

    todos as completed' do sign_in create_todo 'Buy me a beer' find('.todos li', text: 'Buy me a beer').click_on 'Mark complete' expect(page).to have_css('.todos li.completed', text: 'Buy me a beer') end end Domínio do problema Domínio de UI Domínio de UI
  13. feature 'Users make the To do complete' do scenario 'update

    todos as completed' do sign_in create_todo 'Buy me a beer' mark_complete 'Buy me a beer' expect(page).to have_completed_todo 'Buy me a beer' end end
  14. feature 'Users make the To do complete' do scenario 'update

    todos as completed' do sign_in create_todo 'Buy me a beer' mark_complete 'Buy me a beer' expect(page).to have_completed_todo 'Buy me a beer' end end Domínio do problema Domínio do problema
  15. Escreva exemplos de uso do seu código, não testes

  16. Integração Está entre o teste de aceitação e o unitário,

    testa o comportamento de 2 ou mais objetos juntos
  17. Unitário Testa o comportamento de apenas um objeto

  18. describe Stack do describe '#push' do it 'puts an element

    at the top of the Stack' do stack = Stack.new stack.push 1 stack.push 2 expect(stack.top).to eq 2 end end describe '#pop' do it 'remove an element at the final of the Stack' do stack = Stack.new stack.push 1 stack.push 2 stack.push 3 stack.pop expect(stack.last).to eq 2 end end end
  19. Pirâmide de Testes Guia de estratégia de testes baseados na

    natureza do tipo de teste
  20. Aceitação Integração Unitário + Frágil + Lento + Garantia de

    qualidade externa + Rápido - Frágil - Garantia de qualidade externa
  21. Clareza Está claro para entender do que o teste se

    trata?
  22. xUnit Tente estruturar seu teste nas 4 fases do padrão

    http://xunitpatterns.com
  23. Setup Coloca o sistema no estado necessário

  24. Exercise Interage com o objeto sob teste

  25. Verify Verifica o comportamento esperado

  26. Teardown Coloca o sistema no estado anterior do teste

  27. describe Stack do describe '#push' do it 'puts an element

    at the top of the Stack' do stack = Stack.new stack.push 1 stack.push 2 expect(stack.top).to eq 2 end end end
  28. describe Stack do describe '#push' do it 'puts an element

    at the top of the Stack' do stack = Stack.new stack.push 1 stack.push 2 expect(stack.top).to eq 2 end end end Setup Exercise Verify
  29. Clareza = Causa e consequência O teste é claro quando

    é fácil de entender a relação de causa e consequência entre as fases do xUnit
  30. Setup Dado o seguinte estado do meu sistema

  31. Exercise Quando aplico tal mudança nele

  32. Verify Então consigo verificar tal comportamento nele

  33. describe Game, 'in the final phase' do context 'when player

    hits the target' do it 'congratulates the player' do @game = Game.new @game.phase = :final @game.hit_the_target expect(@game.output).to eq 'Congratulations!' end it 'set the score to the player' do @game = Game.new @game.phase = :final @game.hit_the_target expect(@game.score).to eq 100 end end end
  34. describe Game, 'in the final phase' do context 'when player

    hits the target' do it 'congratulates the player' do @game = Game.new @game.phase = :final @game.hit_the_target expect(@game.output).to eq 'Congratulations!' end it 'set the score to the player' do @game = Game.new @game.phase = :final @game.hit_the_target expect(@game.score).to eq 100 end end end DRY
  35. O teste está claro?

  36. describe Game, 'in the final phase' do context 'when player

    hits the target' do before do @game = Game.new @game.phase = :final @game.hit_the_target end it 'congratulates the player' do expect(@game.output).to eq 'Congratulations!' end it 'set the score to the player' do expect(@game.score).to eq 100 end end end DRY
  37. describe Game, 'in the final phase' do context 'when player

    hits the target' do before do @game = Game.new @game.phase = :final @game.hit_the_target end it 'congratulates the player' do expect(@game.output).to eq 'Congratulations!' end it 'set the score to the player' do expect(@game.score).to eq 100 end end end
  38. O teste está claro? Em que estado o objeto game

    precisa estar setado como 100? O que tem que ser feito no objeto para ele setar o score para 100?
  39. it 'set the score to the player' do expect(@game.score).to eq

    100 end
  40. Uso excessivo de DRY nos testes prejudica a clareza

  41. DRY não deve ser aplicado em testes do mesmo modo

    que é aplicado em produção
  42. Favoreça clareza sobre DRY

  43. Mocks & Stubs It’s all about dependencies

  44. SUT e Collaborator SUT: System Under Test DOC: Dependent On

    Component (Collaborator)
  45. SETUP EXERCISE TEARDOWN VERIFY SUT DOC Teste rodando

  46. Teste doubles Um objeto que substitui o DOC real

  47. SETUP EXERCISE TEARDOWN VERIFY SUT DOC Teste doubles doubles

  48. Tipos de test doubles Existem vários tipos de testes doubles,

    entre eles estão: - Mocs - Stubs - Spy - Fake - Dummy Object
  49. Porque precisamos de Mock?

  50. None
  51. Uso de mocks seguindo seu propósito

  52. None
  53. Criadores do conceito de mock

  54. Especificando o Secret of Life

  55. describe SecretOfLife do it 'prints the number of the life'

    do end end
  56. describe SecretOfLife do it 'prints the number of the life'

    do computer = SecretOfLife.new computer.print_the_answer expect(STDOUT.read).to eq 42 end end
  57. describe SecretOfLife do it 'prints the number of the life'

    do computer = SecretOfLife.new computer.print_the_answer expect(STDOUT.read).to eq 42 end end IOError: not opened for reading from (irb):1:in `read' from (irb):1
  58. Interface Discovery Especificando uma API de dependência

  59. describe SecretOfLife do it 'prints the number of the life'

    do end end SecretOfLife Printer print(42)
  60. describe SecretOfLife do it 'prints the number of the life'

    do printer = double('printer')' computer = SecretOfLife.new(printer) expect(printer).to receive(:print).with('42') computer.print_the_answer end end
  61. describe SecretOfLife do it 'prints the number of the life'

    do printer = double('printer') computer = SecretOfLife.new(printer) expect(printer).to receive(:print).with('42') computer.print_the_answer end end Test double
  62. describe SecretOfLife do it 'prints the number of the life'

    do printer = double('printer') computer = SecretOfLife.new(printer) expect(printer).to receive(:print).with('42') computer.print_the_answer end end Test double Injeção de dependência
  63. describe SecretOfLife do it 'prints the number of the life'

    do printer = double('printer') computer = SecretOfLife.new(printer) expect(printer).to receive(:print).with('42') computer.print_the_answer end end Test double Injeção de dependência Mock do test double
  64. Fases do xUnit Mudança de fases quando usamos mock

  65. describe SecretOfLife do it 'prints the number of the life'

    do printer = double('printer') computer = SecretOfLife.new(printer) expect(printer).to receive(:print).with('42') computer.print_the_answer end end Setup Verify Exercise
  66. Estado X Comportamento Diferenças de exercises entre estado e comportamento

  67. Tradicional Verificação pelo estado final do Objeto

  68. Objeto Objeto Objeto

  69. Com Mocks Verifica a iteração entre os objetos

  70. Objeto Objeto Objeto

  71. describe SecretOfLife do it 'prints the number of the life'

    do printer = double('printer')' computer = SecretOfLife.new(printer) expect(printer).to receive(:print).with('42') computer.print_the_answer end end describe Stack do describe '#push' do it 'puts an element at the top of the Stack' do stack = Stack.new stack.push 1 stack.push 2 expect(stack.top).to eq 1 end end end Verify Verify
  72. O que é um mock?

  73. Mock é um teste double usado na fase do verify

  74. Mockar um objeto é programá- lo para verificar se ele

    recebeu as mensagens corretas do SUT
  75. Criado originalmente para ser usado na com a tecnica de

    interface discovery
  76. O que é um Stub?

  77. Stub é um test double usado na fase de setup

  78. Stubar um objeto é programá- lo para retornar uma resposta

    de um certo método
  79. describe Account do it 'log the user on the system'

    do user = double('user')' allow(user).to receive(:log_in) .with(:name => 'rands0n', :password => '12345') .and_return true account = Account.new(user).log_in expect(account.is_logged?).to be_true end end
  80. describe Account do it 'log the user on the system'

    do user = double('user')' allow(user).to receive(:log_in) .with(:name => 'rands0n', :password => '12345') .and_return true account = Account.new(user).log_in expect(account.is_logged?).to be_true end end Estubando o objeto user
  81. describe Account do it 'log the user on the system'

    do user = double('user')' allow(user).to receive(:log_in) .with(:name => 'rands0n', :password => '12345') .and_return true account = Account.new(user).log_in expect(account.is_logged?).to be_true end end Stub: fase de setup
  82. Concluindo - Qualidade de Testes - Mocks vs Stubs

  83. Qualidade de Testes

  84. Prefira clareza ao invés de DRY nos testes

  85. Organize sua suite segundo a pirâmide de testes

  86. Mocks vs Stubs

  87. Stubs são para a fase de setup, mocks são para

    a verify
  88. describe SecretOfLife do it 'prints the number of the life'

    do printer = double('printer')' computer = SecretOfLife.new(printer) expect(printer).to receive(:print).with('42') computer.print_the_answer end end Verify describe Account do it 'log the user on the system' do user = double('user')' allow(user).to receive(:log_in) .with(:name => 'rands0n', :password => '12345') .and_return true account = Account.new(user).log_in expect(account.is_logged?).to be_true end end Setup
  89. Mocks foram feitos com o propósito de fazer design com

    a técnica de interface discovery
  90. Quando alguém falar "mockar", provavelmente ele/ela quis dizer "stubar"

  91. Algumas coisas a mais - Paper para entender a origem

    dos mocks: Mock roles, not Objects - Livro sobre testes avançados: Growing object-oriented software guided by testes
  92. Obrigado! :) twitter.com/rands0n github.com/rands0n speakerdeck.com/rands0n