SlideShare uma empresa Scribd logo
1 de 161
Baixar para ler offline
Desenvolvimento
Baseado em Testes
RSpec - Prática
Eduardo Mendes
edumendes@gmail.com
@dudumendes

Dicas com RSpec
@dudumendes

Executando spec
rspec arquivo.rb
executa um único spec
rspec path/para/meus/specs
executar todos os specs contidos no diretório
@dudumendes

rspec formatos
Formatando para documentação
rspec path/para/meus/spec --format documentation
rspec path/para/meus/spec --format d
rspec path/para/meus/spec -f d
Gerando um arquivo html
rspec path/para/meus/spec -f html > relatorio.html
rspec path/para/meus/spec -f h > relatorio.html
@dudumendes
@dudumendes

Colorindo o resultado
rspec spec --color
@dudumendes

TDD
@dudumendes

O que veremos?
@dudumendes

O que veremos?
Iniciar os testes baseados em cenários previamente definidos
@dudumendes

O que veremos?
Iniciar os testes baseados em cenários previamente definidos
Nunca codifique uma funcionalidade nova sem um teste falhando
@dudumendes

O que veremos?
Iniciar os testes baseados em cenários previamente definidos
Nunca codifique uma funcionalidade nova sem um teste falhando
Utilizar 01 expectativa por exemplo
@dudumendes

O que veremos?
Iniciar os testes baseados em cenários previamente definidos
Nunca codifique uma funcionalidade nova sem um teste falhando
Utilizar 01 expectativa por exemplo
Sempre refatorar na fase verde
@dudumendes

O que veremos?
Iniciar os testes baseados em cenários previamente definidos
Nunca codifique uma funcionalidade nova sem um teste falhando
Utilizar 01 expectativa por exemplo
Sempre refatorar na fase verde
Buscar sempre o cenário mais simples
@dudumendes

O que veremos?
Iniciar os testes baseados em cenários previamente definidos
Nunca codifique uma funcionalidade nova sem um teste falhando
Utilizar 01 expectativa por exemplo
Sempre refatorar na fase verde
Buscar sempre o cenário mais simples
Pequenos passos
@dudumendes

O que veremos?
Iniciar os testes baseados em cenários previamente definidos
Nunca codifique uma funcionalidade nova sem um teste falhando
Utilizar 01 expectativa por exemplo
Sempre refatorar na fase verde
Buscar sempre o cenário mais simples
Pequenos passos
Utilizar contextos para melhor compreensão dos testes
@dudumendes

O que veremos?
Iniciar os testes baseados em cenários previamente definidos
Nunca codifique uma funcionalidade nova sem um teste falhando
Utilizar 01 expectativa por exemplo
Sempre refatorar na fase verde
Buscar sempre o cenário mais simples
Pequenos passos
Utilizar contextos para melhor compreensão dos testes
Extrair métodos para tornar código mais claro
@dudumendes

O que veremos?
Iniciar os testes baseados em cenários previamente definidos
Nunca codifique uma funcionalidade nova sem um teste falhando
Utilizar 01 expectativa por exemplo
Sempre refatorar na fase verde
Buscar sempre o cenário mais simples
Pequenos passos
Utilizar contextos para melhor compreensão dos testes
Extrair métodos para tornar código mais claro
Adicionar complexidade gradativamente
@dudumendes

TDD com RSpec
@dudumendes

Introdução
Construção de um Jogo chamado Senha
Estrutura inicial disponibilizada no Github
https://github.com/dudumendes/tdd_aulas/tree/master/jogo_senha

Specs separados dos fontes
Classes com nomes qualificados
Jogo Senha
Um Jogo que gera uma senha de 04
posições com os algarismos 1, 2, 3, 4
!

O jogador tenta adivinhar a senha
através de uma contra-senha
!

O Jogo é capaz de avaliar a contrasenha
@dudumendes

Jogo Senha
Uma contra-senha é avaliada através dos
seguintes sinais e regras:
+ : um sinal de “positivo” é apresentado para
cada valor correto na posição correta
- : um único sinal de “negativo” é apresentado
para cada valor correto na posição errada
!

Precedência dos sinais: + > -
@dudumendes

Jogo Senha
Exemplos de avaliação para a Senha: 1232
Contra-senha

Avaliação

1232

Parabens, fulano voce quebrou a senha!

4444
2321
1432
4232
1322
@dudumendes

Senha - estrutura
@dudumendes

github.com/dudumendes/tdd_aulas/
jogo_senha
@dudumendes

Funcionalidade: iniciar jogo
Cenário 1 - Iniciar o jogo
Cenário: iniciar o jogo
Dado que eu ainda não estou jogando
Quando eu vir “Bem-vindo ao Senha”
Então eu espero ver “Informe jogador:”
@dudumendes
@dudumendes

“Nunca codifique uma
funcionalidade nova
sem um teste falhando”
@dudumendes

O ciclo básico do TDD
Escrever um
teste unitário
que falha

Fazer um código
passar no teste

Refatorar
@dudumendes

spec/senha/jogo_spec.rb
require 'spec_helper'
!

module Senha
describe Jogo do
describe "#iniciar" do
it "envia uma mensagem de boas-vindas"
it "solicita pelo 1.o jogador"
end
end
end
@dudumendes

lib/senha/jogo.rb
module Senha
class Jogo
end
end
@dudumendes

executando o RSpec
@dudumendes

Adicionando algo
@dudumendes

Adicionando algo
O jogo será jogado no terminal
@dudumendes

Adicionando algo
O jogo será jogado no terminal
O jogo enviará mensagens para uma saída [output]
@dudumendes

Adicionando algo
O jogo será jogado no terminal
O jogo enviará mensagens para uma saída [output]
boas-vindas
@dudumendes

Adicionando algo
O jogo será jogado no terminal
O jogo enviará mensagens para uma saída [output]
boas-vindas
retornos sobre as tentativas de adivinhar a senha
@dudumendes

Adicionando algo
O jogo será jogado no terminal
O jogo enviará mensagens para uma saída [output]
boas-vindas
retornos sobre as tentativas de adivinhar a senha
nosso output será um dublê
@dudumendes

Adicionando algo
O jogo será jogado no terminal
O jogo enviará mensagens para uma saída [output]
boas-vindas
retornos sobre as tentativas de adivinhar a senha
nosso output será um dublê
faremos expectativas sobre este comportamento
@dudumendes

require 'spec_helper'
!
module Senha
describe Jogo do
describe "#iniciar" do
it "envia uma mensagem de boas-vindas" do
output = double('output')
!
jogo = Jogo.new(output)
output.should_receive(:puts).with("Bem-vindo ao Senha")

!

jogo.iniciar
end

it "solicita pelo 1.o jogador"
end
end
end
rspec spec -c -f -d

@dudumendes
@dudumendes

module Senha
class Jogo
def initialize(output)
@output = output
end
def iniciar
end
end
end
@dudumendes
@dudumendes

module Senha
class Jogo
def initialize(output)
@output = output
end
def iniciar
@output.puts 'Bem-vindo ao Senha'
end
end
end
@dudumendes
@dudumendes

Resolva a pendência
Resposta no próximo slide
@dudumendes

it "solicita pelo 1.o jogador" do
output = double('output')
jogo = Jogo.new(output)
output.should_receive(:puts).with("Informe jogador:")
jogo.iniciar
end
@dudumendes
@dudumendes

module Senha
class Jogo
def initialize(output)
@output = output
end
def iniciar
@output.puts 'Bem-vindo ao Senha'
@output.puts 'Informe jogador:'
end
end
end
@dudumendes
@dudumendes

02 exemplos falhando
Os doubles reagem exatamente da maneira como foram
programados
1.º exemplo
“Bem-vindo ao Senha” e somente isso
2.º exemplo
“Informe jogador:” e somente isso
Possível solução
combinar as 02 coisas em um único exemplo
@dudumendes
@dudumendes

“01 expectativa por exemplo”
@dudumendes

“01 expectativa por exemplo”
Se 02 expectativas falharem, só veremos a 1.ª
@dudumendes

01 expectativa por exemplo
02 expectativas em um 1 exemplo
Se ambas expectativas falharem, só veremos a 1.ª
01 expectativa por exemplo
Veremos ambas falharem
@dudumendes

método as_null_object
Informa ao double para responder somente às
mensagens configuradas nas expectativas
as outras são ignoradas
baseado no padrão Null Object
@dudumendes
!
module Senha
describe Jogo do
describe "#iniciar" do
it "envia uma mensagem de boas-vindas" do
output = double('output').as_null_object
jogo = Jogo.new(output)
!
output.should_receive(:puts).with("Bem-vindo ao Senha")
jogo.iniciar
end
!
it "solicita pelo 1.o jogador" do
output = double('output').as_null_object
jogo = Jogo.new(output)

output.should_receive(:puts).with("Informe jogador:")
jogo.iniciar
end
end
end
end
@dudumendes
@dudumendes

O ciclo básico do TDD
Escrever um
teste unitário
que falha

Fazer um código
passar no teste

Refatorar
@dudumendes

Refatorando
“Refatoração é o processo de mudança de um sistema
de software de tal forma que não se altere o
comportamento externo do código e ainda melhore a
sua estrutura interna”
Martin Fowler
Se alguma mudança fizé-lo falhar, é porque foi ela
quem causou o problema
É possível retornar para o verde novamente
@dudumendes
@dudumendes

Refatorar na fase verde
@dudumendes

Refatorar na fase verde
Refatorar com confiança
@dudumendes

Refatorando

Buscar duplicações
na implementação
e nos exemplos
@dudumendes
!
module Senha
describe Jogo do
describe "#iniciar" do
it "envia uma mensagem de boas-vindas" do
output = double('output').as_null_object
jogo = Jogo.new(output)
!
output.should_receive(:puts).with("Bem-vindo ao Senha")
jogo.iniciar
end
!
it "solicita pelo 1.o jogador" do
output = double('output').as_null_object
jogo = Jogo.new(output)

output.should_receive(:puts).with("Informe jogador:")
jogo.iniciar
end
end
end
end
@dudumendes

Crie o before
@dudumendes

before(:each) do
@output = double('output').as_null_object
@jogo = Jogo.new(@output)
end

!

it "envia uma mensagem de boas-vindas" do
@output.should_receive(:puts).with("Bem-vindo ao Senha")
@jogo.iniciar
end

!

it "solicita pelo 1.o jogador" do
@output.should_receive(:puts).with("Informe jogador:")
@jogo.iniciar
end
@dudumendes

método let
evitando os @

Se o bloco before é só para criar variáveis de
instâncias com valores
utilize o let
!

let(:output) {double(‘output’).as_null_object }
@dudumendes

describe Jogo do
describe "#iniciar" do
let(:output) { double('output').as_null_object }
let(:jogo) { Jogo.new(output) }
it "envia uma mensagem de boas-vindas" do
output.should_receive(:puts).with("Bem-vindo ao Senha")
jogo.iniciar
end

!

it "solicita pelo 1.o jogador" do
output.should_receive(:puts).with("Informe jogador:")
jogo.iniciar
end
end
end
@dudumendes

Funcionalidade
o jogador submete uma contra-senha
O jogador submete uma contra-senha de 04 dígitos.
O jogo avalia a contra senha com sinais + e Para cada dígito na contra-senha que casa com um
dígito na posição correta
a avaliação inclui um sinal de +
Para cada dígito na contra-senha que casa com um
dígito, mas não na posição
a avaliação inclui um sinal de -
@dudumendes

Esquema do Cenário:
o jogador informa a contra-senha

Dado que a senha é “<senha>”
Quando eu informar uma “<contra-senha>”
Então a avaliação deve ser “<avaliação>”
@dudumendes

Cenários
sem acertos

senha
!
1234
!

contra-senha

com 03 dígitos corretos
avaliacao

5555

com 01 dígito correto
senha
!
1234
!
1234

avaliacao

contra-senha

1555

+

2555

-

senha
!1234

contra-senha

avaliacao

5234

+++

1234
!
1234

5134

++-

5124

+--

!1234

5123

---

com todos corretos
senha

com 2 dígitos corretos
senha
!
1234

contra-senha

avaliacao

5254

++

1234

5154

+-

1234

2545

--

contra-senha

avaliacao

1234

1234

++++

1234

1243

++--

1234

1423

+---

1234

4321

----
@dudumendes

Criação da senha

Vamos informar a senha na hora da chamada ao início
do jogo
@dudumendes

it "envia uma mensagem de boas-vindas" do
output.should_receive(:puts).with("Bem-vindo ao Senha")
jogo.iniciar('1234')
end
!
it "solicita pelo 1.o jogador" do
!
output.should_receive(:puts).with("Informe jogador:")
jogo.iniciar('1234')
!
end
!
@dudumendes
@dudumendes

module Senha
class Jogo
def initialize(output)
@output = output
end
def iniciar(senha)
@output.puts 'Bem-vindo ao Senha'
@output.puts 'Informe jogador:'
end
end
end
@dudumendes

Avaliação
@dudumendes

14 cenários identificados

Qual deles é o mais importante?
Por qual cenário começar?
@dudumendes
@dudumendes

“Utilize o cenário mais simples”
@dudumendes

“Utilize o cenário mais simples”
Que permita progredir facilmente
@dudumendes

“Utilize o cenário mais simples”
Que permita progredir facilmente
Pequenos passos
@dudumendes

Cenários
sem acertos

senha
!
1234
!

contrasenha
5555

com 03 dígitos corretos
avaliacao

com 01 dígito correto
senha
!
1234
!
1234

avaliacao

contra-senha

1555

+

2555

-

senha
!1234

contra-senha

avaliacao

5234

+++

1234
!
1234

5134

++-

5124

+--

!1234

5123

---

com todos corretos
senha

com 2 dígitos corretos
senha
!
1234

contra-senha

avaliacao

5254

++

1234

5154

+-

1234

2545

--

contra-senha

avaliacao

1234

1234

++++

1234

1243

++--

1234

1423

+---

1234

4321

----
@dudumendes

describe "#avaliar" do
it "envia ‘’ quando receber ‘5555’" do
end
end
@dudumendes
@dudumendes

“Utilize contextos”
@dudumendes

“Utilize contextos”
organizam seus testes
@dudumendes

“Utilize contextos”
organizam seus testes
tornam-os mais compreensíveis
@dudumendes

describe "#avaliar" do
!

context "sem acertos" do
!

it "envia uma avaliacao com ''" do
jogo.iniciar('1234')
output.should_receive(:puts).with('')
jogo.avaliar('5555')
end

!

end
!

end
@dudumendes
@dudumendes

module Senha
class Jogo
def initialize(output)
@output = output
end
def iniciar(senha)
@output.puts 'Bem-vindo ao Senha'
@output.puts 'Informe jogador:'
end
def avaliar(contra_senha)
end
end
end
@dudumendes
@dudumendes

Qual a solução mais simples?
@dudumendes

module Senha
class Jogo
def initialize(output)
@output = output
end
def iniciar(senha)
@output.puts 'Bem-vindo ao Senha'
@output.puts 'Informe jogador:'
end
def avaliar(contra_senha)
@output.puts ''
end
end
end
@dudumendes
@dudumendes

Próximo cenário?
sem acertos

senha
!
1234
!

com 03 dígitos corretos

contrasenha
5555

avaliacao

com 01 dígito correto
senha
!
1234
!
1234

avaliacao

contra-senha

1555

+

2555

-

senha
!1234

contra-senha

avaliacao

5234

+++

1234
!
1234

5134

++-

5124

+--

!1234

5123

---

com todos corretos
senha

com 2 dígitos corretos
senha
!
1234

contra-senha

avaliacao

5254

++

1234

5154

+-

1234

2545

--

contra-senha

avaliacao

1234

1234

++++

1234

1243

++--

1234

1423

+---

1234

4321

----
@dudumendes

context "com 01 digito correto" do
it "envia uma avaliacao com '-'" do
jogo.iniciar('1234')
output.should_receive(:puts).with('-')
jogo.avaliar('2555')
end
end
@dudumendes
module Senha
class Jogo
def initialize(output)
@output = output
end
def iniciar(senha)
@senha = senha
@output.puts 'Bem-vindo ao Senha'
@output.puts 'Informe jogador:'
end
def avaliar(contra_senha)
if @senha.include?(contra_senha[0])
@output.puts '-'
else
@output.puts ''
end
end
end
end

@dudumendes
@dudumendes
@dudumendes

O ciclo básico do TDD
Escrever um
teste unitário
que falha

Fazer um código
passar no teste

Refatorar
para remover
duplicação
module Senha
class Jogo
def initialize(output)
@output = output
end
def iniciar(senha)
@senha = senha
@output.puts 'Bem-vindo ao Senha'
@output.puts 'Informe jogador:'
end
def avaliar(contra_senha)
if @senha.include?(contra_senha[0])
@output.puts '-'
else
@output.puts ''
end
end
end
end

@dudumendes
module Senha
class Jogo
def initialize(output)
@output = output
end
def iniciar(senha)
@senha = senha
@output.puts 'Bem-vindo ao Senha'
@output.puts 'Informe jogador:'
end
def avaliar(contra_senha)
if @senha.include?(contra_senha[0])
avalicao = '-'
else
avaliacao = ''
end
@output.puts avaliacao
end
end
end

@dudumendes
@dudumendes

Próximo cenário?
sem acertos

senha
!
1234
!

com 03 dígitos corretos

contrasenha
5555

avaliacao

com 01 dígito correto
senha
!
1234
!
1234

avaliacao

contra-senha

1555

+

2555

-

senha
!1234

contra-senha

avaliacao

5234

+++

1234
!
1234

5134

++-

5124

+--

!1234

5123

---

com todos corretos
senha

com 2 dígitos corretos
senha
!
1234

contra-senha

avaliacao

5254

++

1234

5154

+-

1234

2545

--

contra-senha

avaliacao

1234

1234

++++

1234

1243

++--

1234

1423

+---

1234

4321

----
@dudumendes

context "com 01 digito exatamente correto" do
it "envia uma avaliacao com '+'" do
jogo.iniciar('1234')
output.should_receive(:puts).with('+')
jogo.avaliar('1555')
end
end
@dudumendes
@dudumendes

def avaliar(contra_senha)
if @senha[0] == contra_senha[0]
avaliacao = '+'
elsif @senha.include?(contra_senha[0])
avaliacao = '-'
else
avaliacao = ''
end
@output.puts avaliacao
end
@dudumendes
@dudumendes

O ciclo básico do TDD
Escrever um
teste unitário
que falha

Fazer um código
passar no teste

Refatorar
para expressar
intenção
@dudumendes

Refatorar para expressar intenção

À medida que o projeto vai evoluindo
aparecem novas duplicações
Remover duplicação
melhorar o projeto
dar mais semântica ao código
@dudumendes

As intenções estão claras?
def avaliar(contra_senha)
if @senha[0] == contra_senha[0]
avaliacao = '+'
elsif @senha.include?(contra_senha[0])
avaliacao = '-'
else
avaliacao = ''
end
@output.puts avaliacao
end
@dudumendes
@dudumendes

“Extraia métodos”
@dudumendes

“Extraia métodos”
elimina duplicação
@dudumendes

“Extraia métodos”
elimina duplicação
introduz abstrações que expressam

com mais clareza

a intenção do código
@dudumendes

Extrair Método
@dudumendes

Extrair Método
• Contexto
• métodos muito longos
• lógicas de complexo entendimento
@dudumendes

Extrair Método
• Contexto
• métodos muito longos
• lógicas de complexo entendimento
• Solução
• fracionar o método em métodos menores mais
coesos
@dudumendes

Extrair Método
• Contexto
• métodos muito longos
• lógicas de complexo entendimento
• Solução
• fracionar o método em métodos menores mais
coesos

• Extração de comportamentos para novos métodos
@dudumendes

def init
content_pane.layout(FlowLayout.new)
movie_list = List.new(my_editor.movies)
scroller = ScrollPane.new(movie_list)
content_pane.add(scroller)
movie_field = TextField.new(16)
content_pane.add(movie_field)
add_button = Button.new(“Add")
....
end
@dudumendes

def init
// set the layout
content_pane.layout(FlowLayout.new)
!

// create the list
movie_list = List.new(my_editor.movies)
scroller = ScrollPane.new(movie_list)
content_pane.add(scroller)
!

// create the field
movie_field = TextField.new(16)
content_pane.add(movie_field)
!

// create theadd button
add_button = Button.new(“Add")
....
end
def init
setLayout
initMovieList
initMovieField
initAddButton
end	

def setLayout
contentPane.layout(FlowLayout.new)
end	

def initMovieList
movie_list = List.new(my_editor.movies)
scroller = ScrollPane.new(movie_list)
content_pane.add(scroller)
end	

def initMovieField
movie_field = TextField.new(16)
content_pane.add(movie_field)
end	

def initAddButton
addButton = Button.new(“Add")
addButton.addActionListener(ActionListener()) {

@dudumendes
@dudumendes

Extrair Método
outro caso
Se um trecho de código duplicado diferentes do
programa
Classe1
@dudumendes

Extrair Método
outro caso

• Se as duplicatas de código devem permanecer

sempre iguais, ou seja, uma vez que se realize uma
alteração em uma delas, as demais devem refletir a
alteração
Classe1
@dudumendes

Extrair Método
outro caso

• Se as duplicatas de código devem permanecer

sempre iguais, ou seja, uma vez que se realize uma
alteração em uma delas, as demais devem refletir a
alteração
Classe1
@dudumendes

def edit	

id = params[:id]	

@personagem = Personagem.find(id)	

//Mais código	

end	

!

def create	

id = params[:id]	

@personagem = Personagem.find(id)	

//Mais código	

end
@dudumendes

Extraindo o método
• Concentre o código que se repete em um único
lugar, por exemplo, em um método e leve as
dependências para lá
@dudumendes

Extraindo o método
• Concentre o código que se repete em um único
lugar, por exemplo, em um método e leve as
dependências para lá

def edit	

id = params[:id]	

@personagem = Personagem.find(id)	

//Mais código	

end
@dudumendes

Extraindo o método
• Concentre o código que se repete em um único
lugar, por exemplo, em um método e leve as
dependências para lá

def edit	

id = params[:id]	

@personagem = Personagem.find(id)	

//Mais código	

end	

def novo_metodo
id = params[:id]	

@personagem = Personagem.find(id)	

//Mais código	

end
@dudumendes

def edit	

self.novo_metodo
end	

!
!

def create	

self.novo_metodo
end
!
!

def novo_metodo
id = params[:id]	

@personagem = Personagem.find(id)	

//Mais código
end
@dudumendes

Extração de método no Senha
@dudumendes

def avaliar(contra_senha)
if digito_exato?(contra_senha, 0)
avaliacao = '+'
!

elsif digito_correto?(contra_senha, 0)
avaliacao = '-'
!

else
avaliacao = ''
end
@output.puts avaliacao
!

end
def digito_exato?(contra_senha, index)
@senha[index] == contra_senha[index]
end
def digito_correto?(contra_senha, index)
@senha.include?(contra_senha[index])
end
@dudumendes
@dudumendes
@dudumendes

“Adicione complexidade
gradativamente”
@dudumendes

“Adicione complexidade
gradativamente”
confiança ao programar
@dudumendes

Próximo cenário?
sem acertos

senha
!
1234
!

com 03 dígitos corretos

contrasenha
5555

avaliacao

com 01 dígito correto
senha
!
1234
!
1234

avaliacao

contra-senha

1555

+

2555

-

senha
!1234

contra-senha

avaliacao

5234

+++

1234
!
1234

5134

++-

5124

+--

!1234

5123

---

com todos corretos
senha

com 2 dígitos corretos
senha
!
1234

contra-senha

avaliacao

5254

++

1234

5154

+-

1234

2545

--

contra-senha

avaliacao

1234

1234

++++

1234

1243

++--

1234

1423

+---

1234

4321

----
@dudumendes

!

context "com 02 digitos corretos" do
it "envia uma avaliacao com '--'" do
jogo.iniciar('1234')
output.should_receive(:puts).with('--')
jogo.avaliar('2355')
end
end
@dudumendes
@dudumendes

Obtendo resultado

Como já foram realizadas algumas refatorações
o código já passa a nos ajudar
@dudumendes

def avaliar(contra_senha)
avaliacao = ''
(0..3).each do |index|

!
!
!
!

if digito_exato?(contra_senha, index)
avaliacao << '+'
elsif digito_correto?(contra_senha, index)
avaliacao << '-'
end
end
@output.puts avaliacao
end
@dudumendes
@dudumendes

Próximo cenário?
sem acertos

senha
!
1234
!

com 03 dígitos corretos

contrasenha
5555

avaliacao

com 01 dígito correto
senha
!
1234
!
1234

avaliacao

contra-senha

1555

+

2555

-

senha
!1234

contra-senha

avaliacao

5234

+++

1234
!
1234

5134

++-

5124

+--

!1234

5123

---

com todos corretos
senha

com 2 dígitos corretos
senha
!
1234

contra-senha

avaliacao

5254

++

1234

5154

+-

1234

2545

--

contra-senha

avaliacao

1234

1234

++++

1234

1243

++--

1234

1423

+---

1234

4321

----
@dudumendes

context "com 01 digito correto e 01 digito exato (nesta ordem)" do
it "envia uma avaliacao com '+-'" do
jogo.iniciar('1234')
output.should_receive(:puts).with('+-')
jogo.avaliar('2535')
end
end
@dudumendes
@dudumendes

def avaliar(contra_senha)
avaliacao = ''
(0..3).each do |index|
if digito_exato?(contra_senha, index)
avaliacao << '+'
end
end
(0..3).each do |index|
if digito_correto?(contra_senha, index)
avaliacao << '-'
end
end
@output.puts avaliacao
end
@dudumendes
@dudumendes

def digito_correto?(contra_senha, index)
@senha.include?(contra_senha[index]) &&
!digito_exato?(contra_senha, index)
end
@dudumendes
@dudumendes

Em seguida?
@dudumendes

Em seguida
Remover bad smells
Variáveis temporárias
Métodos longos estruturados
Classes com responsabilidades demais
Extrair classe
@dudumendes

O que vimos?
@dudumendes

O que vimos?
Iniciar os testes baseados em cenários previamente
@dudumendes

O que vimos?
Iniciar os testes baseados em cenários previamente
Nunca codifique uma funcionalidade nova sem um teste falhando
@dudumendes

O que vimos?
Iniciar os testes baseados em cenários previamente
Nunca codifique uma funcionalidade nova sem um teste falhando
01 expectativa por exemplo
@dudumendes

O que vimos?
Iniciar os testes baseados em cenários previamente
Nunca codifique uma funcionalidade nova sem um teste falhando
01 expectativa por exemplo
Refatorar na fase verde
@dudumendes

O que vimos?
Iniciar os testes baseados em cenários previamente
Nunca codifique uma funcionalidade nova sem um teste falhando
01 expectativa por exemplo
Refatorar na fase verde
Utilizar o cenário mais simples
@dudumendes

O que vimos?
Iniciar os testes baseados em cenários previamente
Nunca codifique uma funcionalidade nova sem um teste falhando
01 expectativa por exemplo
Refatorar na fase verde
Utilizar o cenário mais simples
Pequenos passos
@dudumendes

O que vimos?
Iniciar os testes baseados em cenários previamente
Nunca codifique uma funcionalidade nova sem um teste falhando
01 expectativa por exemplo
Refatorar na fase verde
Utilizar o cenário mais simples
Pequenos passos
Utilizar contextos
@dudumendes

O que vimos?
Iniciar os testes baseados em cenários previamente
Nunca codifique uma funcionalidade nova sem um teste falhando
01 expectativa por exemplo
Refatorar na fase verde
Utilizar o cenário mais simples
Pequenos passos
Utilizar contextos
Extrair métodos para tornar código mais claro
@dudumendes

O que vimos?
Iniciar os testes baseados em cenários previamente
Nunca codifique uma funcionalidade nova sem um teste falhando
01 expectativa por exemplo
Refatorar na fase verde
Utilizar o cenário mais simples
Pequenos passos
Utilizar contextos
Extrair métodos para tornar código mais claro
Adicionar complexidade gradativamente
@dudumendes

Bibliografia
FOWLER, Martin. “Mocks aren’t Stubs”.
FOWLER, Martin; BECK, Kent; BRANT, John; Opdyke,
William; ROBERTS, Don. Refactoring: Improving The
Design of Existing Code.
CHELIMSKY, David. The RSpec Book. PragBook,
2011.

Mais conteúdo relacionado

Destaque

Introdução à Linguagem Ruby - Fundamentos - Parte 2
 Introdução à Linguagem Ruby - Fundamentos - Parte 2 Introdução à Linguagem Ruby - Fundamentos - Parte 2
Introdução à Linguagem Ruby - Fundamentos - Parte 2Eduardo Mendes
 
Academia do Arquiteto Globalcode
Academia do Arquiteto GlobalcodeAcademia do Arquiteto Globalcode
Academia do Arquiteto GlobalcodeGlobalcode
 
Acesso a banco de dados com JDBC
Acesso a banco de dados com JDBCAcesso a banco de dados com JDBC
Acesso a banco de dados com JDBCEduardo Mendes
 
Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7Eduardo Mendes
 
TDD Projeto e Estrategias
TDD Projeto e EstrategiasTDD Projeto e Estrategias
TDD Projeto e EstrategiasEduardo Mendes
 
The Power of Collaboration to Build Your Own Startup
The Power of Collaboration to Build Your Own StartupThe Power of Collaboration to Build Your Own Startup
The Power of Collaboration to Build Your Own StartupTaufan Erfiyanto
 
Testes de Software parte 2
Testes de Software parte 2Testes de Software parte 2
Testes de Software parte 2Eduardo Mendes
 
Teste de Software - parte 1
Teste de Software - parte 1Teste de Software - parte 1
Teste de Software - parte 1Eduardo Mendes
 
Desenvolvimento web com PHP parte 4
Desenvolvimento web com PHP parte 4Desenvolvimento web com PHP parte 4
Desenvolvimento web com PHP parte 4Eduardo Mendes
 
Engenharia de Requisitos
Engenharia de RequisitosEngenharia de Requisitos
Engenharia de RequisitosEduardo Mendes
 
Evolucao de software - parte 1
Evolucao de software - parte 1Evolucao de software - parte 1
Evolucao de software - parte 1Eduardo Mendes
 
Java Web 2 - Ferramentas e configuração
Java Web 2 - Ferramentas e configuraçãoJava Web 2 - Ferramentas e configuração
Java Web 2 - Ferramentas e configuraçãoEduardo Mendes
 
Singleton - Padrão de Projeto
Singleton - Padrão de ProjetoSingleton - Padrão de Projeto
Singleton - Padrão de ProjetoEduardo Mendes
 
Certificação Java: Exceções
Certificação Java: ExceçõesCertificação Java: Exceções
Certificação Java: ExceçõesEduardo Mendes
 

Destaque (20)

Introdução à Linguagem Ruby - Fundamentos - Parte 2
 Introdução à Linguagem Ruby - Fundamentos - Parte 2 Introdução à Linguagem Ruby - Fundamentos - Parte 2
Introdução à Linguagem Ruby - Fundamentos - Parte 2
 
Html Aula 1 - parte 2
Html Aula 1 - parte 2Html Aula 1 - parte 2
Html Aula 1 - parte 2
 
RSpec com doubles
RSpec com doublesRSpec com doubles
RSpec com doubles
 
Academia do Arquiteto Globalcode
Academia do Arquiteto GlobalcodeAcademia do Arquiteto Globalcode
Academia do Arquiteto Globalcode
 
Acesso a banco de dados com JDBC
Acesso a banco de dados com JDBCAcesso a banco de dados com JDBC
Acesso a banco de dados com JDBC
 
Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7Desenvolvimento Web com PHP parte 7
Desenvolvimento Web com PHP parte 7
 
TDD Projeto e Estrategias
TDD Projeto e EstrategiasTDD Projeto e Estrategias
TDD Projeto e Estrategias
 
The Power of Collaboration to Build Your Own Startup
The Power of Collaboration to Build Your Own StartupThe Power of Collaboration to Build Your Own Startup
The Power of Collaboration to Build Your Own Startup
 
Testes de Software parte 2
Testes de Software parte 2Testes de Software parte 2
Testes de Software parte 2
 
Teste de Software - parte 1
Teste de Software - parte 1Teste de Software - parte 1
Teste de Software - parte 1
 
Desenvolvimento web com PHP parte 4
Desenvolvimento web com PHP parte 4Desenvolvimento web com PHP parte 4
Desenvolvimento web com PHP parte 4
 
Engenharia de Requisitos
Engenharia de RequisitosEngenharia de Requisitos
Engenharia de Requisitos
 
Academia java intensivo
Academia java intensivoAcademia java intensivo
Academia java intensivo
 
Jquery
JqueryJquery
Jquery
 
Rails - parte 1
Rails - parte 1Rails - parte 1
Rails - parte 1
 
Evolucao de software - parte 1
Evolucao de software - parte 1Evolucao de software - parte 1
Evolucao de software - parte 1
 
ExtJS-4
ExtJS-4ExtJS-4
ExtJS-4
 
Java Web 2 - Ferramentas e configuração
Java Web 2 - Ferramentas e configuraçãoJava Web 2 - Ferramentas e configuração
Java Web 2 - Ferramentas e configuração
 
Singleton - Padrão de Projeto
Singleton - Padrão de ProjetoSingleton - Padrão de Projeto
Singleton - Padrão de Projeto
 
Certificação Java: Exceções
Certificação Java: ExceçõesCertificação Java: Exceções
Certificação Java: Exceções
 

Semelhante a TDD RSpec Jogo Senha

tdc-2020-poa-pedra-tesoura-papel
tdc-2020-poa-pedra-tesoura-papeltdc-2020-poa-pedra-tesoura-papel
tdc-2020-poa-pedra-tesoura-papelDouglas Siviotti
 
Aprenda bdd-jogando-dados-ebook
Aprenda bdd-jogando-dados-ebookAprenda bdd-jogando-dados-ebook
Aprenda bdd-jogando-dados-ebookValério Farias
 
Dojo UECE - javaCE
Dojo UECE - javaCEDojo UECE - javaCE
Dojo UECE - javaCEYuri Adams
 
RSpec - Desenvolvimento Baseado em Teste
RSpec - Desenvolvimento Baseado em TesteRSpec - Desenvolvimento Baseado em Teste
RSpec - Desenvolvimento Baseado em TesteEduardo Mendes
 
Programação Orientada a Testes
Programação Orientada a TestesProgramação Orientada a Testes
Programação Orientada a TestesGregorio Melo
 
TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...
TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...
TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...tdc-globalcode
 
Removendo o cheiro ruim do seu código - SoLiSC 2011
Removendo o cheiro ruim do seu código - SoLiSC 2011Removendo o cheiro ruim do seu código - SoLiSC 2011
Removendo o cheiro ruim do seu código - SoLiSC 2011Luís Cobucci
 
Introdução aos testes unitários
Introdução aos testes unitáriosIntrodução aos testes unitários
Introdução aos testes unitáriosoverduka
 
Tdd em django sem desculpas versao final
Tdd em django sem desculpas versao finalTdd em django sem desculpas versao final
Tdd em django sem desculpas versao finalAdriano Petrich
 
AULA 06 - REVISÃO DE CONCEITOS INICIAIS DE ALGORITMOS
AULA 06 - REVISÃO DE CONCEITOS INICIAIS DE ALGORITMOSAULA 06 - REVISÃO DE CONCEITOS INICIAIS DE ALGORITMOS
AULA 06 - REVISÃO DE CONCEITOS INICIAIS DE ALGORITMOSprofjotamarcosduarte
 
In tests we trust: começando com TDD, mocks e mais
In tests we trust: começando com TDD, mocks e maisIn tests we trust: começando com TDD, mocks e mais
In tests we trust: começando com TDD, mocks e maisAna Paula Gomes
 
Dito Tech Talk RSpec
Dito Tech Talk RSpecDito Tech Talk RSpec
Dito Tech Talk RSpecguest49d83b2
 
Preparando-se para a prova da Certificação Zend PHP 5.3
Preparando-se para a prova da Certificação Zend PHP 5.3Preparando-se para a prova da Certificação Zend PHP 5.3
Preparando-se para a prova da Certificação Zend PHP 5.3klaussilveira
 
Workshop Ruby on Rails dia 1 ruby-pt
Workshop Ruby on Rails dia 1 ruby-ptWorkshop Ruby on Rails dia 1 ruby-pt
Workshop Ruby on Rails dia 1 ruby-ptPedro Sousa
 
Não existe feedback melhor do que o do seu código
Não existe feedback melhor do que o do seu códigoNão existe feedback melhor do que o do seu código
Não existe feedback melhor do que o do seu códigoRenan Carvalho
 
Vamos falar de Clean Code, Refatoração e TDD
Vamos falar de Clean Code, Refatoração e TDDVamos falar de Clean Code, Refatoração e TDD
Vamos falar de Clean Code, Refatoração e TDDDomingos Teruel
 

Semelhante a TDD RSpec Jogo Senha (20)

tdc-2020-poa-pedra-tesoura-papel
tdc-2020-poa-pedra-tesoura-papeltdc-2020-poa-pedra-tesoura-papel
tdc-2020-poa-pedra-tesoura-papel
 
Aprenda bdd-jogando-dados-ebook
Aprenda bdd-jogando-dados-ebookAprenda bdd-jogando-dados-ebook
Aprenda bdd-jogando-dados-ebook
 
Dojo UECE - javaCE
Dojo UECE - javaCEDojo UECE - javaCE
Dojo UECE - javaCE
 
RSpec - Desenvolvimento Baseado em Teste
RSpec - Desenvolvimento Baseado em TesteRSpec - Desenvolvimento Baseado em Teste
RSpec - Desenvolvimento Baseado em Teste
 
Programação Orientada a Testes
Programação Orientada a TestesProgramação Orientada a Testes
Programação Orientada a Testes
 
TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...
TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...
TDC2017 | POA Trilha Programacao Funicional - (Nunca) Ouvi falar de Rust... m...
 
Python para Programadores
Python para ProgramadoresPython para Programadores
Python para Programadores
 
Removendo o cheiro ruim do seu código - SoLiSC 2011
Removendo o cheiro ruim do seu código - SoLiSC 2011Removendo o cheiro ruim do seu código - SoLiSC 2011
Removendo o cheiro ruim do seu código - SoLiSC 2011
 
Introdução aos testes unitários
Introdução aos testes unitáriosIntrodução aos testes unitários
Introdução aos testes unitários
 
Clean code
Clean codeClean code
Clean code
 
Tdd em django sem desculpas versao final
Tdd em django sem desculpas versao finalTdd em django sem desculpas versao final
Tdd em django sem desculpas versao final
 
AULA 06 - REVISÃO DE CONCEITOS INICIAIS DE ALGORITMOS
AULA 06 - REVISÃO DE CONCEITOS INICIAIS DE ALGORITMOSAULA 06 - REVISÃO DE CONCEITOS INICIAIS DE ALGORITMOS
AULA 06 - REVISÃO DE CONCEITOS INICIAIS DE ALGORITMOS
 
In tests we trust: começando com TDD, mocks e mais
In tests we trust: começando com TDD, mocks e maisIn tests we trust: começando com TDD, mocks e mais
In tests we trust: começando com TDD, mocks e mais
 
Dito Tech Talk RSpec
Dito Tech Talk RSpecDito Tech Talk RSpec
Dito Tech Talk RSpec
 
Preparando-se para a prova da Certificação Zend PHP 5.3
Preparando-se para a prova da Certificação Zend PHP 5.3Preparando-se para a prova da Certificação Zend PHP 5.3
Preparando-se para a prova da Certificação Zend PHP 5.3
 
Qualidade de código Android
Qualidade de código AndroidQualidade de código Android
Qualidade de código Android
 
Minicurso Ruby on Rails
Minicurso Ruby on RailsMinicurso Ruby on Rails
Minicurso Ruby on Rails
 
Workshop Ruby on Rails dia 1 ruby-pt
Workshop Ruby on Rails dia 1 ruby-ptWorkshop Ruby on Rails dia 1 ruby-pt
Workshop Ruby on Rails dia 1 ruby-pt
 
Não existe feedback melhor do que o do seu código
Não existe feedback melhor do que o do seu códigoNão existe feedback melhor do que o do seu código
Não existe feedback melhor do que o do seu código
 
Vamos falar de Clean Code, Refatoração e TDD
Vamos falar de Clean Code, Refatoração e TDDVamos falar de Clean Code, Refatoração e TDD
Vamos falar de Clean Code, Refatoração e TDD
 

Mais de Eduardo Mendes

JavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a ObjetosJavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a ObjetosEduardo Mendes
 
Angular JS - Fundamentos
Angular JS - FundamentosAngular JS - Fundamentos
Angular JS - FundamentosEduardo Mendes
 
Introdução à Internet, Http e HTML
Introdução à Internet, Http e HTMLIntrodução à Internet, Http e HTML
Introdução à Internet, Http e HTMLEduardo Mendes
 
Estimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de SoftwareEstimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de SoftwareEduardo Mendes
 
Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2Eduardo Mendes
 
Validações no Ruby on Rails
Validações no Ruby on Rails Validações no Ruby on Rails
Validações no Ruby on Rails Eduardo Mendes
 
Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)Eduardo Mendes
 
PHP básico para iniciantes
PHP básico para iniciantesPHP básico para iniciantes
PHP básico para iniciantesEduardo Mendes
 
PHP e MySQL para iniciantes
PHP e MySQL para iniciantesPHP e MySQL para iniciantes
PHP e MySQL para iniciantesEduardo Mendes
 
Introdução a Padrões de Projeto
Introdução a Padrões de ProjetoIntrodução a Padrões de Projeto
Introdução a Padrões de ProjetoEduardo Mendes
 

Mais de Eduardo Mendes (20)

JavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a ObjetosJavaScript - Introdução com Orientação a Objetos
JavaScript - Introdução com Orientação a Objetos
 
Angular JS - Fundamentos
Angular JS - FundamentosAngular JS - Fundamentos
Angular JS - Fundamentos
 
Layout Fluido
Layout FluidoLayout Fluido
Layout Fluido
 
Web Design Responsivo
Web Design ResponsivoWeb Design Responsivo
Web Design Responsivo
 
Html - Aula 4
Html - Aula 4Html - Aula 4
Html - Aula 4
 
Html - Aula 3
Html - Aula 3Html - Aula 3
Html - Aula 3
 
Introdução à Internet, Http e HTML
Introdução à Internet, Http e HTMLIntrodução à Internet, Http e HTML
Introdução à Internet, Http e HTML
 
Jquery 2
Jquery 2Jquery 2
Jquery 2
 
Estimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de SoftwareEstimativas de Esforço - Engenharia de Software
Estimativas de Esforço - Engenharia de Software
 
Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2Java web 6 JSP Expression Language Taglib parte 2
Java web 6 JSP Expression Language Taglib parte 2
 
Validações no Ruby on Rails
Validações no Ruby on Rails Validações no Ruby on Rails
Validações no Ruby on Rails
 
Padrão Iterator
Padrão IteratorPadrão Iterator
Padrão Iterator
 
Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)Padroes Template-Method (Método Gabarito)
Padroes Template-Method (Método Gabarito)
 
Padrão Command
Padrão CommandPadrão Command
Padrão Command
 
Padrão Fachada
Padrão FachadaPadrão Fachada
Padrão Fachada
 
Padrão Adapter
Padrão AdapterPadrão Adapter
Padrão Adapter
 
Web Design Responsivo
Web Design ResponsivoWeb Design Responsivo
Web Design Responsivo
 
PHP básico para iniciantes
PHP básico para iniciantesPHP básico para iniciantes
PHP básico para iniciantes
 
PHP e MySQL para iniciantes
PHP e MySQL para iniciantesPHP e MySQL para iniciantes
PHP e MySQL para iniciantes
 
Introdução a Padrões de Projeto
Introdução a Padrões de ProjetoIntrodução a Padrões de Projeto
Introdução a Padrões de Projeto
 

TDD RSpec Jogo Senha