o que você deve saber sobre unit tests

Download O que você deve saber sobre Unit Tests

If you can't read please download the document

Upload: gustavo-fonseca

Post on 15-May-2015

244 views

Category:

Technology


5 download

DESCRIPTION

Apresentado no evento FISL14, em Porto Alegre - Brasil, no dia 03/07/2013.

TRANSCRIPT

  • 1. O que voc deve saber sobre Unit Tests. fisl14 03/07/2013 Gustavo Fonseca [email protected] @gustavonseca gustavofonseca

2. Agradecimento +420.000 artigos cientficos +1.000 peridicos +9.000.000 citaes www.scielo.org 3. O que Unit Test? 1 #coding: utf-8 2 3 def saudar(nome): 4 return u'Ol, %s.' % nome 5 6 7 # garantir que o nome do fulano passado como 8 # argumento seja utilizado na saudao 9 assert saudar('Gustavo') == u'Ol, Gustavo.' 10 11 # garantir que seja retornado um objeto unicode 12 assert isinstance(saudar('foo'), unicode) Unidade objeto dos testes Casos de teste 4. O framework de unit tests deve... Garantir o isolamento dos testes Facilitar a configurao do ambiente Fomentar a organizao dos testes Executar os testes Produzir relatrios teis 5. 1 #coding: utf-8 2 import unittest 3 4 5 def saudar(nome): 6 return u'Ol, %s.' % nome 7 8 9 class SaudarTests(unittest.TestCase): 10 11 def test_nome_do_fulano_seja_utilizado_na_saudacao(self): 12 self.assertEqual(saudar('Gustavo'), u'Ol, Gustavo.') 13 14 def test_objeto_retornado_tipo_unicode(self): 15 self.assertIsInstance(saudar('foo'), unicode) Resumo da execuo dos testes Casos de teste so agrupados em subclasses de unittest.TestCase O ambiente pode ser preparado por meio dos mtodos setUp e tearDown unittest (stdlib) http://docs.python.org/2.7/library/unittest.html 6. E quando h colaborao? 1 class Motor(object): 2 def __init__(self): 3 self.ligado = False 4 5 def ligar(self): 6 self.ligado = True 7 8 def desligar(self): 9 self.ligado = False 10 11 12 class Carro(object): 13 def __init__(self): 14 self.motor = Motor() 15 16 def dar_partida(self): 17 self.motor.ligar() 18 19 def esta_ligado(self): 20 return self.motor.ligado 21 22 def andar(self): 23 if self.esta_ligado(): 24 print 'Andando... uhul!' 25 else: 26 raise RuntimeError('o carro precisa estar ligado para andar.') Composio 7. 1 import unittest 2 3 from cod3 import Carro, Motor 4 5 6 class MotorTests(unittest.TestCase): 7 def setUp(self): 8 self.motor = Motor() 9 10 def test_estado_padrao_eh_desligado(self): 11 self.assertFalse(self.motor.ligado) 12 13 def test_ligar(self): 14 self.motor.ligar() 15 self.assertTrue(self.motor.ligado) 16 17 def test_desligar(self): 18 self.motor.ligar() 19 20 self.assertTrue(self.motor.ligado) 21 self.motor.desligar() 22 self.assertFalse(self.motor.ligado) 23 24 25 class CarroTests(unittest.TestCase): 26 def setUp(self): 27 self.carro = Carro() 28 29 def test_dar_partida(self): 30 self.carro.dar_partida() 31 self.assertTrue(self.carro.esta_ligado()) 32 33 def test_andar(self): 34 self.carro.dar_partida() 35 self.assertIsNone(self.carro.andar()) 36 37 def test_andar_com_carro_desligado_levanta_excecao(self): 38 self.assertRaises(RuntimeError, self.carro.andar) 39 Uma instncia de Motor foi criada Motor().ligar() 8. Isolamento de dependncias dubl 9. Dubls de teste stub dummy fake http://martinfowler.com/articles/mocksArentStubs.html mock 10. Cidados de primeira classe 1 class Motor(object): 2 def __init__(self): 3 self.ligado = False 4 5 def ligar(self): 6 self.ligado = True 7 8 def desligar(self): 9 self.ligado = False 10 11 12 class Carro(object): 13 def __init__(self, motor=Motor): 14 self.motor = motor() 15 16 def dar_partida(self): 17 self.motor.ligar() 18 19 def esta_ligado(self): 20 return self.motor.ligado 21 22 def andar(self): 23 if self.esta_ligado(): 24 print 'Andando... uhul!' 25 else: 26 raise RuntimeError('o carro precisa estar ligado para andar.') Composio via argumento na construo do objeto 11. Stub 1 import unittest 2 3 from cod3 import Carro, Motor 4 5 6 class MotorTests(unittest.TestCase): 7 """Suprimidos os testes para economizar tela""" 8 9 class CarroTests(unittest.TestCase): 10 def setUp(self): 11 12 class MotorStub(object): 13 def __init__(self): 14 self.ligado = False 15 def ligar(self): return None 16 def desligar(self): return None 17 18 self.carro = Carro(motor=MotorStub) 19 20 def test_dar_partida(self): 21 self.carro.motor.ligado = True 22 23 self.carro.dar_partida() 24 self.assertTrue(self.carro.esta_ligado()) 25 26 def test_andar(self): 27 self.carro.motor.ligado = True 28 29 self.carro.dar_partida() 30 self.assertIsNone(self.carro.andar()) 31 32 def test_andar_com_carro_desligado_levanta_excecao(self): 33 self.assertRaises(RuntimeError, self.carro.andar) 34 Implementa a interface do objeto, com retornos previsveis. O dubl entra em ao! 12. Mock 1 import mocker 2 3 from cod3 import Carro, Motor 4 5 6 class MotorTests(mocker.MockerTestCase): 7 """Suprimidos os testes para economizar tela""" 8 9 class CarroTests(mocker.MockerTestCase): 10 11 def test_dar_partida(self): 12 # Inicio do treinamento 13 MotorMock = self.mocker.mock() 14 15 MotorMock() 16 self.mocker.result(MotorMock) 17 18 MotorMock.ligar() 19 self.mocker.result(None) 20 21 MotorMock.ligado 22 self.mocker.result(True) 23 24 self.mocker.replay() 25 # Fim do treinamento 26 27 carro = Carro(motor=MotorMock) 28 carro.dar_partida() 29 self.assertTrue(carro.esta_ligado()) 30 31 def test_andar(self): 32 """Suprimido para economizar tela""" 33 34 def test_andar_com_carro_desligado_levanta_excecao(self): 35 """Suprimido para economizar tela""" http://docs.python.org/3.3/library/unittest.mock.html labix.org/mocker Treinando o mock Fim do treinamento 13. 1 import mocker 2 3 from cod3 import Carro, Motor 4 5 6 class MotorTests(mocker.MockerTestCase): 7 """Suprimidos os testes para economizar tela""" 8 9 class CarroTests(mocker.MockerTestCase): 10 11 def test_dar_partida(self): 12 # Inicio do treinamento 13 MotorMock = self.mocker.mock() 14 15 MotorMock() 16 self.mocker.result(MotorMock) 17 18 MotorMock.ligar() 19 self.mocker.result(None) 20 21 self.mocker.replay() 22 # Fim do treinamento 23 24 carro = Carro(motor=MotorMock) 25 carro.dar_partida() 26 self.assertTrue(carro.esta_ligado()) 27 28 def test_andar(self): 29 """Suprimido para economizar tela""" 30 31 def test_andar_com_carro_desligado_levanta_excecao(self): 32 """Suprimido para economizar tela""" Removido o treino do atributo .ligado Unexpected expression 14. Estratgias Cobertura de linhas de cdigo Cobertura de caminhos Classes de equivalncia Fronteiras Erros 15. Outras siglas e nomes conhecidos IoC (Inversion of control) DI (Dependency injection) Fixtures Doctests (Python) 16. Obrigado! Dvidas? Gustavo Fonseca [email protected] @gustavonseca gustavofonseca