3. @dudumendes
Teste Unitário preparar
Ciclo do TDD
Componente
“resetar” testado
de
executar
maneira
isolada
validar
4. @dudumendes
Ciclo 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. @dudumendes
Teste Unitário preparar
Ciclo do TDD
Frameworks xUnit
Componente
Baseado em “resetar” testado
de
executar
asserções maneira
isolada
validar
6. @dudumendes
class 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
8. @dudumendes
JUnit in Action
xUnits 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. @dudumendes
Hamcrest JUnit in Action
Framework 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
11. @dudumendes
Orientação a Objetos
Orientação a objetos diz mais respeito à
comunicação entre os objetos do que às
suas propriedades e comportamentos
13. @dudumendes
Problemas
Quando se passa a testar a estrutura dos objetos
ao invés do que eles fazem
É preciso pensar nas interações entre
pessoas e sistemas
os próprios objetos
É preciso pensar no comportamento
19. @dudumendes
RSpec
“RSpec is testing tool for the Ruby programming
language
Born under the banner
of Behaviour-Driven Development,
it is designed to make Test-Driven Development a
productive and enjoyable experience.”
Fonte: http://rspec.info/
20. @dudumendes
RSpec
Criado por Steven Baker, 2005
Na época já existia a ideia e praticantes de TDD
Juntou o que tinha ouvido de BDD com Aslak Hellsoy e
Dave Stels
22. @dudumendes
describe
É o método utilizado
para agrupar os describe “titulo” do
testes a serem
executados end
os “exemplos”
testam os
comportamentos
dos objetos
23. @dudumendes
it
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
27. @dudumendes
ligador_spec.rb
describe 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!"
end
end
32. @dudumendes
Ligador
deve dizer 'Hello turma!'
quando receber a mensagem saudar
Finished in 0.00062 seconds
1 example, 0 failures
33. @dudumendes
Dicionário RSpec
Subject Code / Sujeito
Código que possui o comportamento a ser especificado
Expectation / Expectativas
Expressão que representa o comportamento esperado do Subject Code
Code Example / Exemplo de código
Exemplo executável de como o Subject Code pod ser utilizado e seu comportamento
esperado em determinado contexto
Example Group / Grupo de exemplos
Um grupo de exemplos de código
Spec
Um arquivo que contém um ou mais grupos de exemplos
35. @dudumendes
RSpec
Descreve 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. @dudumendes
Describe
Descreve um objeto
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
37. @dudumendes
describe "Uma nova Conta" do
it "deve iniciar com 0 de saldo" do
conta = Conta.new
expect(conta.saldo).to be 0
end
end
38. @dudumendes
O método describe
Argumentos
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. @dudumendes
O método describe
show me the code
describe “Um Usuario” { ... }
=> Um Usuario
describe Usuario { ... }
=>Usuario
describe Usuario, “sem papeis atribuidos” { ... }
=>Usuario sem papeis atribuidos
41. @dudumendes
O método context
alias 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. @dudumendes
describe Usuario do
context “sem papel atribuido” do
it "nao deve acessar conteudo protegido" do
...
end
end
end
43. @dudumendes
It
o 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. @dudumendes
O método it
Argumentos
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. @dudumendes
describe 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
48. @dudumendes
describe 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. @dudumendes
describe 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
end
end
52. @dudumendes
TDD por Kent Beck
Projeto
crie uma lista de teste
anote e identifique os testes
seja conciso: uma classe ou método
posteriormente, é possível adicionar mais testes
53. @dudumendes
Postergando 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. @dudumendes
Exemplo sem bloco
Contexto
Você quer criar sua lista de comportamentos a
serem exercitados
Solução
Coloque somente a descrição do exemplo para
montar sua lista
O RSpec avisará que o exemplo está pendente
55. @dudumendes
describe 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. @dudumendes
TvAberta
deve ser gratuita
deve possuir os canais abertos
nao deve incluir os canais fechados (PENDING: Not yet implemented)
57. @dudumendes
O 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. @dudumendes
describe 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
end
end
59. @dudumendes
TvAberta
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. @dudumendes
O método pending
com 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. @dudumendes
describe "um array vazio" do
it "deve ser vazio" do
pending("bug informado 18987") do
expect([]).to be_empty
end
end
end
62. @dudumendes
um 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)>'
67. @dudumendes
métodos before / after
métodos before e after
equivalem às fases de preparar e resetar,
respectivamente
métodos que executam antes e depois de cada
exemplo
ou antes e depois de grupo de exemplos
68. @dudumendes
mé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. @dudumendes
describe 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
end
end
70. @dudumendes
describe 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
end
end
71. @dudumendes
describe 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
end
end
73. @dudumendes
método before(:all)
Comportamento
o código englobado por before(:all) executa apenas 01
vez antes de todos os exemplos do grupo
Cuidado
componentes devem ser testados de maneira isolada
estados compartilhados por exemplos podem gerar
comportamentos inesperados
não recomendado para variáveis de instância
75. @dudumendes
before(:each) do
@calc = Calculadora.new
end
after(:each) do
@calc = nil
end
76. @dudumendes
before(:each) do
puts “executando before”
@calc = Calculadora.new
end
after(:each) do
puts “executando after”
@calc = nil
end
77. @dudumendes
métodos around(:each)
Contexto
um código deve ser executado antes e depois de
cada exemplo
Solução
utilização de around
Pode falhar, e pode não executar o código
correspondente ao after
83. @dudumendes
be
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. @dudumendes
be_true be_false
OK se o subject for avaliado como true
expect(true).to be_true
expect(1).to be_true
expect(false).not_to be_true
expect(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. @dudumendes
be_nil
OK se o subject for avaliado como nil
expect(nil).to be_nil
expect(false).not_to be nil
86. @dudumendes
be_a be_an
be_kind_of be_a_kind_of
OK 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. @dudumendes
eq, 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. @dudumendes
include
OK 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. @dudumendes
match
OK se o subject casar com a expressão regular da expectativa
expect("alo turma").match(/alo/)
expect("alo turma").match(/ali/)
90. @dudumendes
raise_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/)
92. @dudumendes
Conversão de romanos para
arábicos
Desenvolver em TDD uma funcionalidade que converta
um número romano qualquer em número arábico
O que é importante saber?
100. @dudumendes
Dicas
Exemplos
devem ser curtos e diretos
devem testar uma funcionalidade específica
Como testar
testar um pouco e codificar um pouco
101. @dudumendes
Dicas
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. @dudumendes
Dicas
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. @dudumendes
Bibliografia
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.
Hinweis der Redaktion
\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&#xE1; quantos exemplos pendentes ainda existem\nQu&#xE3;o perto voc&#xEA; est&#xE1; de finalizar seu exemplo\n
\n
A execu&#xE7;&#xE3;o para na linha &#x201C;pending&#x201D; e voc&#xEA; evita de COMENTAR o c&#xF3;digo para n&#xE3;o executar qq\n
A execu&#xE7;&#xE3;o para na linha &#x201C;pending&#x201D; e voc&#xEA; evita de COMENTAR o c&#xF3;digo para n&#xE3;o executar qq\n