RSpec - Desenvolvimento Baseado em Teste

1.416 visualizações

Publicada em

0 comentários
4 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

Sem downloads
Visualizações
Visualizações totais
1.416
No SlideShare
0
A partir de incorporações
0
Número de incorporações
6
Ações
Compartilhamentos
0
Downloads
57
Comentários
0
Gostaram
4
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Um objeto recebe mensagem de outro objeto e reage a esta mensagem VALOR ou EXCECAO\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • O RSpec sempre informará quantos exemplos pendentes ainda existem\nQuão perto você está de finalizar seu exemplo\n
  • \n
  • A execução para na linha “pending” e você evita de COMENTAR o código para não executar qq\n
  • A execução para na linha “pending” e você evita de COMENTAR o código para não executar qq\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • RSpec - Desenvolvimento Baseado em Teste

    1. 1. DesenvolvimentoBaseado em TestesRSpec - 1.ª parteEduardo Mendesedumendes@gmail.com
    2. 2. @dudumendesFerramentas para TDD
    3. 3. @dudumendesTeste Unitário prepararCiclo do TDD Componente   “resetar” testado  de   executar maneira   isolada validar
    4. 4. @dudumendesCiclo do TDD Escreva um teste ANTES de escrever um código a ser testado Escreva um código que apenas faça compilar o teste e observe o teste funcionando Refatore para o formato mais simples possível
    5. 5. @dudumendesTeste Unitário prepararCiclo do TDDFrameworks xUnit Componente  Baseado em “resetar” testado  de   executarasserções maneira   isolada validar
    6. 6. @dudumendesclass TestNumeroSimples < Test::Unit::TestCase def test_simples assert_equal(4, NumeroSimples.new(2).add(4)) assert_equal(6, NumeroSimples.new(2).multiply(3)) end end
    7. 7. @dudumendesdef testeAssertivo assertTrue(valores.contains("um") || valores.contains("dois") || valores.contains("tres"))end
    8. 8. @dudumendes JUnit in ActionxUnits e DSLs começaram a surgir alternativas que possuíam mais legibilidade utilização de DSLs uma tendência das linguagens scripts é aproximar a programação da linguagem natural, facilitando o entendimento contraponto aos xUnits
    9. 9. @dudumendesHamcrest JUnit in ActionFramework para declarações“critérios de correspondência (match)”Matchers (ex: hasItem, equalTo, anyOf) Informam se um determinado objeto casa ou não com algum critério podem descrever o critério
    10. 10. @dudumendesNo momento RED JUnit in Action As mensagens de RED bar são mais amigáveis
    11. 11. @dudumendesOrientação a Objetos Orientação a objetos diz mais respeito à comunicação entre os objetos do que às suas propriedades e comportamentos
    12. 12. @dudumendesSistema OOÉ um conjunto de objetos que colaboram entre si
    13. 13. @dudumendesProblemasQuando se passa a testar a estrutura dos objetosao invés do que eles fazemÉ preciso pensar nas interações entre pessoas e sistemas os próprios objetosÉ preciso pensar no comportamento
    14. 14. @dudumendesO Design EmergenteBenefícios do TDD Qualidade de código Fraco acoplamento Alta Coesão
    15. 15. @dudumendesRSpec
    16. 16. @dudumendesInstalação gem install rspec
    17. 17. @dudumendesInstalação rspec --help
    18. 18. @dudumendesInstalação rspec arquivo/pasta_de_spec
    19. 19. @dudumendesRSpec“RSpec is testing tool for the Ruby programminglanguageBorn under the bannerof Behaviour-Driven Development,it is designed to make Test-Driven Development aproductive and enjoyable experience.” Fonte: http://rspec.info/
    20. 20. @dudumendesRSpecCriado por Steven Baker, 2005Na época já existia a ideia e praticantes de TDDJuntou o que tinha ouvido de BDD com Aslak Hellsoy eDave Stels
    21. 21. @dudumendesRSpec describe it expect should
    22. 22. @dudumendesdescribeÉ o método utilizadopara agrupar os describe “titulo” dotestes a seremexecutados end os “exemplos” testam os comportamentos dos objetos
    23. 23. @dudumendesit no RSpec, os testes são chamados de it “descrição do comportamento” do exemplos end it é o método que declara o exemplo descreve o comportamento do exemplo
    24. 24. @dudumendesexpectmétodo que verificaum critério, uma expect(valor_obtido).to valor_esperadoexpectativa
    25. 25. @dudumendesRSpec Hello World
    26. 26. @dudumendesRegra de Ouro do TDD “Nunca codifique uma funcionalidade nova sem um teste falhando”
    27. 27. @dudumendes ligador_spec.rbdescribe Ligador do it "deve dizer Hello turma! quando receber a mensagem saudar" do ligador = Ligador.new saudacao = ligador.saudar expect(saudacao).to eql "Hello turma!" endend
    28. 28. @dudumendesrspec ligador_spec.rb
    29. 29. @dudumendesNameError: uninitialized constant Ligador
    30. 30. @dudumendesclass Ligador def saudar "Hello turma!" endend
    31. 31. @dudumendesrspec ligador_spec.rb
    32. 32. @dudumendesLigador deve dizer Hello turma!quando receber a mensagem saudarFinished in 0.00062 seconds1 example, 0 failures
    33. 33. @dudumendesDicionário RSpecSubject Code / Sujeito Código que possui o comportamento a ser especificadoExpectation / Expectativas Expressão que representa o comportamento esperado do Subject CodeCode Example / Exemplo de código Exemplo executável de como o Subject Code pod ser utilizado e seu comportamento esperado em determinado contextoExample Group / Grupo de exemplos Um grupo de exemplos de códigoSpec Um arquivo que contém um ou mais grupos de exemplos
    34. 34. @dudumendesComparandoAssertions ExpectationTest method Code exampleTest case Example Group
    35. 35. @dudumendesRSpecDescreve uma conversação O RSpec é um DSL capaz de descrever o comportamentos dos objetos Aproxima as descrições destes comportamentos à linguagem natural Uma conversação
    36. 36. @dudumendesDescribeDescreve um objetoDescreva Mas como Ela “deve iniciar Clientes e servidores devem entender cliente e “uma com zero de HTTP e os navegadores servidor se Conta” comunicam? saldo” devem conhecer HTML
    37. 37. @dudumendesdescribe "Uma nova Conta" do it "deve iniciar com 0 de saldo" do conta = Conta.new expect(conta.saldo).to be 0 endend
    38. 38. @dudumendesO método describeArgumentos quantos argumentos forem necessários normalmente: 1 ou 2 descreve o objeto em um estado específico, ou um conjunto de comportamentos esperados do mesmo o 1.º pode ser uma referência a uma classe ou string o 2.º, opcional, deve ser uma string
    39. 39. @dudumendesO método describeshow me the code describe “Um Usuario” { ... } => Um Usuario describe Usuario { ... } =>Usuario describe Usuario, “sem papeis atribuidos” { ... } =>Usuario sem papeis atribuidos
    40. 40. @dudumendesdescribe Usuario dodescribe “sem papel atribuido” do it "nao deve acessar conteudo protegido" do ... endendend
    41. 41. @dudumendesO método contextalias de describe context “sem papel atribuido” { ... } =>sem papel atribuido torna o código mais legível describe -> objetos, comportamentos context -> contextos em que objetos deve ser exercitados
    42. 42. @dudumendesdescribe Usuario do context “sem papel atribuido” do it "nao deve acessar conteudo protegido" do ... end endend
    43. 43. @dudumendesIto comportamento que será exercitado Descreva Mas como Ela “deve iniciar Clientes e servidores devem entender cliente e “uma com zero de HTTP e os navegadores servidor se Conta” comunicam? saldo” devem conhecer HTML
    44. 44. @dudumendesO método itArgumentos uma string e um hash opcional string uma sentença com o comportamento do código que será exercitado pode vários em um describe se um bloco de código não for passado, o exemplo será marcado como pendente
    45. 45. @dudumendesdescribe Pilha do describe "#peek" do it "deve retornar o elemento do topo" do pilha = Pilha.new pilha.push :item expect(pilha.peek).to be :item end it "nao deve remover o elemento do topo" do pilha = Pilha.new pilha.push :item expect(pilha.items.length).to be 1 end end
    46. 46. @dudumendesrspec spec/pilha_spec.rb --format documentation Pilha #peek deve retornar o elemento do topo nao deve remover o elemento do topo
    47. 47. @dudumendesrspec spec/pilha_spec.rb --format documentation Pilha #peek retorna o elemento do topo nao remove o elemento do topo
    48. 48. @dudumendesdescribe Pilha do describe "#peek" do it "deve retornar o elemento do topo" do pilha = Pilha.new pilha.push :item expect(pilha.peek).to be :item end it "nao deve remover o elemento do topo" do pilha = Pilha.new pilha.push :item expect(pilha.items.length).to be 1 end end
    49. 49. @dudumendesdescribe Pilha do pilha = Pilha.new pilha.push :item describe "#peek" do it "deve retornar o elemento do topo" do expect(pilha.peek).to be :item end it "nao deve remover o elemento do topo" do expect(pilha.items.length).to be 1 end endend
    50. 50. @dudumendesPostergando exemplos
    51. 51. @dudumendesTDD por Kent Beck Projeto Teste Teste Implementa
    52. 52. @dudumendesTDD por Kent Beck Projeto crie uma lista de teste anote e identifique os testes seja conciso: uma classe ou métodoposteriormente, é possível adicionar mais testes
    53. 53. @dudumendesPostergando exemplos“crie uma lista de teste” “anote e identifique os testes” O RSpec pode auxiliar a tarefa de identificação de “exemplos” A sua lista pode ser formada pelos exemplos em um spec 03 maneiras exemplos sem blocos exemplos desabilitados por pending envolver o código do exemplo com pending, para ser notificado quando estiverem FIXED
    54. 54. @dudumendesExemplo sem blocoContexto Você quer criar sua lista de comportamentos a serem exercitadosSolução Coloque somente a descrição do exemplo para montar sua lista O RSpec avisará que o exemplo está pendente
    55. 55. @dudumendesdescribe TvAberta do it "deve ser gratuita" do ... end it "deve possuir os canais abertos" do ... end it "nao deve incluir os canais fechados"end
    56. 56. @dudumendesTvAberta deve ser gratuita deve possuir os canais abertos nao deve incluir os canais fechados (PENDING: Not yet implemented)
    57. 57. @dudumendesO método pending Contexto Você tem um exemplo falhando que ainda não tem como passar Depende de algo ainda não resolvido Solução marque o exemplo com o método pending o bloco é executado, mas para na linha onde o pending foi declarado na saída haverá o aviso de pendência
    58. 58. @dudumendesdescribe TvAberta do it "deve ser gratuita" do ... end it "deve possuir os canais abertos" do ... end it "nao deve incluir os canais fechados" it "deve possuir closed caption" do pending "esperando correcao de codigo" TvAberta.closed_caption endend
    59. 59. @dudumendesTvAberta deve ser gratuita deve possuir os canais abertos nao deve incluir os canais fechados (PENDING: Not yet implemented) deve possuir closed caption (PENDING: esperando correcao de codigo)Pending: TvAberta nao deve incluir os canais fechados # Not yet implemented # ./spec/tv_aberta_spec.rb:13 TvAberta deve possuir closed caption # esperando correcao de codigo # ./spec/tv_aberta_spec.rb:15
    60. 60. @dudumendesO método pendingcom corpo Contexto Você tem um exemplo em que um bug foi detectado Você gostaria que o código executasse mesmo com a pendência Solução crie um bloco com pending o bloco é executado se o erro ocorrer, o RSpec executa como um pending normal caso contrário ele avisa que o exemplo está sem problemas (FIXED) Após a detecção da correção, é possível livrar o bloco do pending
    61. 61. @dudumendesdescribe "um array vazio" do it "deve ser vazio" do pending("bug informado 18987") do expect([]).to be_empty end endend
    62. 62. @dudumendesum array vazio deve ser vazio (FAILED - 1)Failures: 1) um array vazio deve ser vazio FIXED Expected pending bug informado 18987 to fail. No Error was raised. # ./spec/array_spec.rb:3:in `block (2 levels) in <top (required)>
    63. 63. @dudumendesdescribe "um array vazio" do it "deve ser vazio" do expect([]).to be_empty endend
    64. 64. @dudumendesHooks
    65. 65. @dudumendes04 fases preparar Componente   “resetar” testado  de   executar maneira   isolada validar
    66. 66. Hooks @dudumendes Exemplo Before After
    67. 67. @dudumendesmétodos before / aftermétodos before e after equivalem às fases de preparar e resetar, respectivamentemétodos que executam antes e depois de cadaexemplo ou antes e depois de grupo de exemplos
    68. 68. @dudumendesmétodo before(:each)exemplo Contexto alguns exemplos podem exercitar funcionalidades específicas de um mesmo objeto ao iniciar cada exemplo este objeto deveria se encontrar no mesmo estado Solução coloque o código de configuração em um bloco before(:each) Nota o padrão do método before é o :each pode-se utilizar somente o before
    69. 69. @dudumendesdescribe Calculadora do describe "somar 3 e 4" do it "deve ser igual a 7" do calc = Calculadora.new expect(calc.somar(3,4)).to eql 7 end end describe "subtrair 4 - 1" do it "deve ser igual a 3" do calc = Calculadora.new expect(calc.subtrair(4,1)).to eql 3 end endend
    70. 70. @dudumendesdescribe Calculadora do before(:each) do @calc = Calculadora.new end describe "somar 3 e 4" do it "deve ser igual a 7" do expect(@calc.somar(3,4)).to eql 7 end end describe "subtrair 4 - 1" do it "deve ser igual a 3" do expect(@calc.subtrair(4,1)).to eql 3 end endend
    71. 71. @dudumendesdescribe Calculadora do before do @calc = Calculadora.new end describe "somar 3 e 4" do it "deve ser igual a 7" do expect(@calc.somar(3,4)).to eql 7 end end describe "subtrair 4 - 1" do it "deve ser igual a 3" do expect(@calc.subtrair(4,1)).to eql 3 end endend
    72. 72. @dudumendesmétodo before(:each)extraia tudo o que for de configuração dos exemplospara um método beforeutilize nestes blocos variáveis de instância
    73. 73. @dudumendesmétodo before(:all)Comportamento o código englobado por before(:all) executa apenas 01 vez antes de todos os exemplos do grupoCuidado componentes devem ser testados de maneira isolada estados compartilhados por exemplos podem gerar comportamentos inesperados não recomendado para variáveis de instância
    74. 74. @dudumendesmétodos after(:each/:all)after(:each) executa após cada exemplo normalmente utilizado para restaurar o estado do ambienteafter(:all) executa após um grupo de exemplos
    75. 75. @dudumendes before(:each) do @calc = Calculadora.new end after(:each) do @calc = nil end
    76. 76. @dudumendes before(:each) do puts “executando before” @calc = Calculadora.new end after(:each) do puts “executando after” @calc = nil end
    77. 77. @dudumendesmétodos around(:each)Contexto um código deve ser executado antes e depois de cada exemploSolução utilização de aroundPode falhar, e pode não executar o códigocorrespondente ao after
    78. 78. @dudumendes around do |example| faca_algo_antes example.run faca_algo_depois end
    79. 79. @dudumendesExceçõesthrow -> raisetry -> begincatch -> rescuefinally -> ensure
    80. 80. @dudumendes around do |example| begin faca_algo_antes example.run ensure faca_algo_depois end end
    81. 81. @dudumendesExpectations
    82. 82. @dudumendesExpectationsSão a alternativa para as tradicionais asserçõesVerificam se o sujeito do exemplo casa com umcomportamento definido na expectativa
    83. 83. @dudumendesbe OK se o subject for avaliado como true expect(true).to be true expect(1).to be 1 expect(1).to be > 0 expect(1).to be < 2 expect(1).to be >= 1 expect(1).to be <= 2 expect(true).not_to be true expect(1).not_to be > 2
    84. 84. @dudumendesbe_true be_false OK se o subject for avaliado como trueexpect(true).to be_trueexpect(1).to be_trueexpect(false).not_to be_trueexpect(nil).not_to be_true OK se o subject for avaliado como false expect(false).to be_false expect(0).to be_false expect(true).not_to be_false expect(nil).not_to be_false
    85. 85. @dudumendesbe_nil OK se o subject for avaliado como nil expect(nil).to be_nil expect(false).not_to be nil
    86. 86. @dudumendesbe_a be_anbe_kind_of be_a_kind_ofOK se a classe do subject for uma subclasse da expectativa expect(usuario).to be_a(Objeect) expect(usuario).not_to be_a(Pessoa) expect(pessoa).not_to be_an(Integer)
    87. 87. @dudumendeseq, eql, equal, ==, === alo = “alo turma!” Logica alo.should == “alo turma!” OK se é o mesmo valor expect(alo).to eql(alo) OK se é o mesmo valor expect(alo).to equal(alo) OK se é o mesmo objeto expect(alo).to_not equal(“alo turma”) OK se não é o mesmo objeto alo.should === alo OK se é o mesmo objeto alo.should_not === Objec.new OK se não é o mesmo objeto
    88. 88. @dudumendesincludeOK se o subject inclui todos os elementos da expectativa expect([1, 2, 3]).to include(1) expect([1, 2, 3]).to include(1,3) expect(1..3).to include(1) expect(1..3).to include(1, 2, 3) expect("alo turma").to include("lo tu") expect([1,2,3]).not_to include(4) expect("alo turma").not_to include("ali")
    89. 89. @dudumendesmatchOK se o subject casar com a expressão regular da expectativa expect("alo turma").match(/alo/) expect("alo turma").match(/ali/)
    90. 90. @dudumendesraise_error OK se o bloco lançar a exceção da expectativa expect { raise ArgumentError }.to raise_error expect { raise ArgumentError }.to raise_error(ArgumentError)expect { raise ArgumentError, “nome invalido”}.to raise_error(ArgumentError, "nome invalido")expect { raise ArgumentError, “nome invalido”}.to raise_error(ArgumentError, /nome invalido/)
    91. 91. @dudumendesExercício
    92. 92. @dudumendesConversão de romanos paraarábicosDesenvolver em TDD uma funcionalidade que convertaum número romano qualquer em número arábicoO que é importante saber?
    93. 93. @dudumendesRomanos Alguns caracteres possuem valoresI = 1V = 5X = 10L = 50
    94. 94. @dudumendesRomanos Alguns caracteres podem se repetir I, X, C, M Outros não V, L, D
    95. 95. @dudumendesRomanos Algumas combinações de caracteres retornam a soma dos elementosII = 2II = I + I = 1 + 1 = 2CCC = 100 + 100 + 100 = 300
    96. 96. @dudumendesRomanos Outras combinações de caracteres retornam a subtração dos elementosIV = 5 - 1 = 4XL = 50 - 10 = 40CXLIV = 100 + (50 - 10) + (5 - 1)
    97. 97. @dudumendesRomanos Algumas combinações não são possíveisIIIICCCCXXXX
    98. 98. @dudumendesRomanosEntregáveis:SpecE a Classe RomanosParser
    99. 99. @dudumendesDicas
    100. 100. @dudumendesDicasExemplos devem ser curtos e diretos devem testar uma funcionalidade específicaComo testar testar um pouco e codificar um pouco
    101. 101. @dudumendesDicas Exercite o mais simples primeiro referências e retornos vazios coleções vazias casos básicos de recursividade valores limites utilize tanto quanto possível expect()to be/eql
    102. 102. @dudumendesDicas Utilize o parâmetro de mensagem principalmente quando o teste não é tão claro Mantenha os testes pequenos coloque somente as expectativas necessárias para testar uma funcionalidade Mantenha cada teste independente do outro Evite puts
    103. 103. @dudumendesBibliografia ASTELS, David. Test-Driven Development: A Pratical Guide. Prentice Hall, 2003. CHELIMSKY, David. The RSpec Book. PragBook, 2011. FREEMAN, Steve; PRYCE, Nat. Growing Object- Oriented Software, Guiaded by Tests. Addison-Wesley. VIEIRA, Fernando. Guia Rápido de RSpec.

    ×