Share
Embed
Pirâmide de Teste
Randson
January 26, 2017
Transcript
92 slides
-
O que veremos? Por que fazer testes? Qualidade de testes
Mocks e Stubs Alguns exemplos a mais… -
Por que fazer testes? Manter o projeto em níveis saudáveis
Ajudar na qualidade externa Ajudar na qualidade interna -
Qualidade de testes Como posso avaliar se meu teste ou
suíte está com qualidade? -
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 -
Adequação do tipo de teste O teste foi feito com
o tipo mais adequado? Aceitação, integração ou unitário? -
São sobre o domínio do problema(regras de negócio), não sobre
o domínio de UI -
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 -
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 -
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 -
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 -
Integração Está entre o teste de aceitação e o unitário,
testa o comportamento de 2 ou mais objetos juntos -
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 -
Pirâmide de Testes Guia de estratégia de testes baseados na
natureza do tipo de teste -
Aceitação Integração Unitário + Frágil + Lento + Garantia de
qualidade externa + Rápido - Frágil - Garantia de qualidade externa -
xUnit Tente estruturar seu teste nas 4 fases do padrão
http://xunitpatterns.com -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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? -
DRY não deve ser aplicado em testes do mesmo modo
que é aplicado em produção -
SUT e Collaborator SUT: System Under Test DOC: Dependent On
Component (Collaborator) -
Tipos de test doubles Existem vários tipos de testes doubles,
entre eles estão: - Mocs - Stubs - Spy - Fake - Dummy Object -
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 -
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 -
describe SecretOfLife do it 'prints the number of the life'
do end end SecretOfLife Printer print(42) -
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 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 -
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 -
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 -
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 -
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 -
Mockar um objeto é programá- lo para verificar se ele
recebeu as mensagens corretas do SUT -
Criado originalmente para ser usado na com a tecnica de
interface discovery -
Stubar um objeto é programá- lo para retornar uma resposta
de um certo método -
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 -
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 -
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 -
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 -
Mocks foram feitos com o propósito de fazer design com
a técnica de interface discovery -
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