SlideShare uma empresa Scribd logo
Ensaio sobre testes automatizados

TDC2014 – 09/08/2014
Gustavo Fonseca
@gustavonseca

gustavofonseca
1
Níveis de teste
● Testes de aceitação
● Testes de integração
● Testes de sistema
● ...
● Testes de unidade
2
3
Testes de Unidade

4
O que é Teste de Unidade?
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 saudação	
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
5
Características
● Garantir o isolamento dos testes
● Facilitar a configuração do ambiente
● Fomentar a organização dos testes
● Executar os testes
● Produzir relatórios úteis
6
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 execução
dos testes
Casos de teste são
agrupados em
subclasses de
unittest.TestCase
O ambiente pode ser
preparado por meio
dos métodos setUp e
tearDown
unittest (stdlib)
http://docs.python.org/2.7/library/unittest.html
7
Associação
8
Exemplo de Composição
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.')	
Composição
9
1 import unittest	
2 	
3 from cod3 import Carro, Motor	
4 	
5 	
6 class MotorTests(unittest.TestCase):	
7 """	
8 Os testes foram suprimidos para	
9 economizar espaco	
10 """	
11 	
12 class CarroTests(unittest.TestCase):	
13 def setUp(self):	
14 self.carro = Carro()	
15 	
16 def test_dar_partida(self):	
17 self.carro.dar_partida()	
18 self.assertTrue(self.carro.esta_ligado())	
19 	
20 def test_andar(self):	
21 self.carro.dar_partida()	
22 self.assertIsNone(self.carro.andar())	
23 	
24 def test_andar_com_carro_desligado_levanta_excecao(self):	
25 self.assertRaises(RuntimeError, self.carro.andar)	
26 	
Uma instância de
Motor foi criada
Motor().ligar()
10
Isolamento de dependências
dublê
11
__init__
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.')	
Composição via
argumento na
inicialização do
objeto
12
Atributo de 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 classe_motor = Motor	
14 	
15 def __init__(self):	
16 self.motor = self.classe_motor()	
17 	
18 def dar_partida(self):	
19 self.motor.ligar()	
20 	
21 def esta_ligado(self):	
22 return self.motor.ligado	
23 	
24 def andar(self):	
25 if self.esta_ligado():	
26 print 'Andando... uhul!'	
27 else:	
28 raise RuntimeError('O carro precisa estar ligado.')	 13
Composição via atributo
de classe
Atributo de classe (cont.)
14
from unittest import mock # python3	
!
with mock.patch.object(Carro, 'classe_motor', autospec=True) as motor_teste:	
motor_teste.return_value = MotorDuble	
!
carro = Carro()	
# testes aqui...
Dublês de teste
dummy - fake - stub - mock
http://martinfowler.com/articles/mocksArentStubs.html 15
Stub
class CarroTests(unittest.TestCase):	
def setUp(self):	
!
class MotorStub(object):	
def __init__(self):	
self.ligado = False	
def ligar(self): return None	
def desligar(self): return None	
!
self.carro = Carro(motor=MotorStub)	
!
def test_dar_partida(self):	
self.carro.motor.ligado = True	
!
self.carro.dar_partida()	
self.assertTrue(self.carro.esta_ligado())	
!
def test_andar(self):	
self.carro.motor.ligado = True	
!
self.carro.dar_partida()	
self.assertIsNone(self.carro.andar())	
!
def test_andar_com_carro_desligado_levanta_excecao(self):	
self.assertRaises(RuntimeError, self.carro.andar)	
!
Implementa a
interface do objeto,
com retornos
previsíveis.
O dublê entra em ação! rá!
16
Configuração de estado
pré-teste.
Mock
import mocker # python 2 apenas =/	
!
from cod3 import Carro	
!
!
class CarroTests(mocker.MockerTestCase):	
!
def test_dar_partida(self):	
# Inicio do treinamento	
MotorMock = self.mocker.mock()	
!
MotorMock()	
self.mocker.result(MotorMock)	
!
MotorMock.ligar()	
self.mocker.result(None)	
!
MotorMock.ligado	
self.mocker.result(True)	
!
self.mocker.replay()	
# Fim do treinamento	
!
carro = Carro(motor=MotorMock)	
carro.dar_partida()	
self.assertTrue(carro.esta_ligado())	
Ver também: http://docs.python.org/3.3/library/unittest.mock.html
labix.org/mocker
17
import mocker	
!
from cod3 import Carro	
!
!
class CarroTests(mocker.MockerTestCase):	
!
def test_dar_partida(self):	
# Inicio do treinamento	
MotorMock = self.mocker.mock()	
!
MotorMock()	
self.mocker.result(MotorMock)	
!
MotorMock.ligar()	
self.mocker.result(None)	
!
#MotorMock.ligado	
#self.mocker.result(True)	
!
self.mocker.replay()	
# Fim do treinamento	
!
carro = Carro(motor=MotorMock)	
carro.dar_partida()	
self.assertTrue(carro.esta_ligado())	
Removido o treino do
atributo .ligado
18
19
"Mocke" com moderação
• Testes menos manuteníveis
• Mudanças de interface (API)
• Inconsistências entre "treinamentos"
• Prefira "mockar" os pontos de integração
• Teste os mocks! o.O
Pontos de integração
20
21
Cliente REST
http://git.io/S9YCrg
Grato!

Dúvidas?
Gustavo Fonseca
@gustavonseca

gustavofonseca
22

Mais conteúdo relacionado

Destaque (7)

Adeus Wordpress. Ola Pelican!
Adeus Wordpress. Ola Pelican!Adeus Wordpress. Ola Pelican!
Adeus Wordpress. Ola Pelican!
 
Testando Aplicações Django: Quando, Como e Onde?
Testando Aplicações Django: Quando, Como e Onde?Testando Aplicações Django: Quando, Como e Onde?
Testando Aplicações Django: Quando, Como e Onde?
 
TDD com Python
TDD com PythonTDD com Python
TDD com Python
 
Apresentação de imuno iii
Apresentação de imuno iiiApresentação de imuno iii
Apresentação de imuno iii
 
import pybr12: experiencias de inclusión en la última PyCon Brazil
import pybr12: experiencias de inclusión en la última PyCon Brazilimport pybr12: experiencias de inclusión en la última PyCon Brazil
import pybr12: experiencias de inclusión en la última PyCon Brazil
 
Métodos
MétodosMétodos
Métodos
 
Curso de Python e Django
Curso de Python e DjangoCurso de Python e Django
Curso de Python e Django
 

Semelhante a Ensaio sobre testes automatizados

Coding Dojo e Test Driven Development
Coding Dojo e Test Driven DevelopmentCoding Dojo e Test Driven Development
Coding Dojo e Test Driven Development
Rodrigo Alves Vieira
 
JUnit: framework de testes unitários
JUnit: framework de testes unitáriosJUnit: framework de testes unitários
JUnit: framework de testes unitários
elliando dias
 
Testes automatizados
Testes automatizadosTestes automatizados
Testes automatizados
Rodrigo Maia
 
Testes e depuração de código com Python
Testes e depuração de código com PythonTestes e depuração de código com Python
Testes e depuração de código com Python
Dorneles Treméa
 
Java introdução ao java
Java   introdução ao javaJava   introdução ao java
Java introdução ao java
Armando Daniel
 

Semelhante a Ensaio sobre testes automatizados (18)

Android: testes automatizados e TDD
Android: testes automatizados e TDDAndroid: testes automatizados e TDD
Android: testes automatizados e TDD
 
Coding Dojo e Test Driven Development
Coding Dojo e Test Driven DevelopmentCoding Dojo e Test Driven Development
Coding Dojo e Test Driven Development
 
Coding Dojo e Test Driven Development
Coding Dojo e Test Driven DevelopmentCoding Dojo e Test Driven Development
Coding Dojo e Test Driven Development
 
Groovy na plataforma Java
Groovy na plataforma JavaGroovy na plataforma Java
Groovy na plataforma Java
 
Qualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitQualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnit
 
Aula5
Aula5Aula5
Aula5
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
 
Demoiselle Behave - Parte 3
Demoiselle Behave - Parte 3Demoiselle Behave - Parte 3
Demoiselle Behave - Parte 3
 
JUnit: framework de testes unitários
JUnit: framework de testes unitáriosJUnit: framework de testes unitários
JUnit: framework de testes unitários
 
Testes automatizados
Testes automatizadosTestes automatizados
Testes automatizados
 
Testes e depuração de código com Python
Testes e depuração de código com PythonTestes e depuração de código com Python
Testes e depuração de código com Python
 
Testes com JUnit
Testes com JUnitTestes com JUnit
Testes com JUnit
 
TDD em django sem desculpas versao fisl
TDD em django sem desculpas versao fislTDD em django sem desculpas versao fisl
TDD em django sem desculpas versao fisl
 
Floggy-JustJava-2008-09-10
Floggy-JustJava-2008-09-10Floggy-JustJava-2008-09-10
Floggy-JustJava-2008-09-10
 
Relato Sobre a Migração de uma Aplicação Legada para Rails
Relato Sobre a Migração de uma Aplicação Legada para RailsRelato Sobre a Migração de uma Aplicação Legada para Rails
Relato Sobre a Migração de uma Aplicação Legada para Rails
 
Java introdução ao java
Java   introdução ao javaJava   introdução ao java
Java introdução ao java
 
jQuery básico (parte 3)
jQuery básico (parte 3)jQuery básico (parte 3)
jQuery básico (parte 3)
 

Ensaio sobre testes automatizados

  • 1. Ensaio sobre testes automatizados
 TDC2014 – 09/08/2014 Gustavo Fonseca @gustavonseca
 gustavofonseca 1
  • 2. Níveis de teste ● Testes de aceitação ● Testes de integração ● Testes de sistema ● ... ● Testes de unidade 2
  • 3. 3
  • 5. O que é Teste de Unidade? 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 saudação 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 5
  • 6. Características ● Garantir o isolamento dos testes ● Facilitar a configuração do ambiente ● Fomentar a organização dos testes ● Executar os testes ● Produzir relatórios úteis 6
  • 7. 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 execução dos testes Casos de teste são agrupados em subclasses de unittest.TestCase O ambiente pode ser preparado por meio dos métodos setUp e tearDown unittest (stdlib) http://docs.python.org/2.7/library/unittest.html 7
  • 9. Exemplo de Composição 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.') Composição 9
  • 10. 1 import unittest 2 3 from cod3 import Carro, Motor 4 5 6 class MotorTests(unittest.TestCase): 7 """ 8 Os testes foram suprimidos para 9 economizar espaco 10 """ 11 12 class CarroTests(unittest.TestCase): 13 def setUp(self): 14 self.carro = Carro() 15 16 def test_dar_partida(self): 17 self.carro.dar_partida() 18 self.assertTrue(self.carro.esta_ligado()) 19 20 def test_andar(self): 21 self.carro.dar_partida() 22 self.assertIsNone(self.carro.andar()) 23 24 def test_andar_com_carro_desligado_levanta_excecao(self): 25 self.assertRaises(RuntimeError, self.carro.andar) 26 Uma instância de Motor foi criada Motor().ligar() 10
  • 12. __init__ 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.') Composição via argumento na inicialização do objeto 12
  • 13. Atributo de 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 classe_motor = Motor 14 15 def __init__(self): 16 self.motor = self.classe_motor() 17 18 def dar_partida(self): 19 self.motor.ligar() 20 21 def esta_ligado(self): 22 return self.motor.ligado 23 24 def andar(self): 25 if self.esta_ligado(): 26 print 'Andando... uhul!' 27 else: 28 raise RuntimeError('O carro precisa estar ligado.') 13 Composição via atributo de classe
  • 14. Atributo de classe (cont.) 14 from unittest import mock # python3 ! with mock.patch.object(Carro, 'classe_motor', autospec=True) as motor_teste: motor_teste.return_value = MotorDuble ! carro = Carro() # testes aqui...
  • 15. Dublês de teste dummy - fake - stub - mock http://martinfowler.com/articles/mocksArentStubs.html 15
  • 16. Stub class CarroTests(unittest.TestCase): def setUp(self): ! class MotorStub(object): def __init__(self): self.ligado = False def ligar(self): return None def desligar(self): return None ! self.carro = Carro(motor=MotorStub) ! def test_dar_partida(self): self.carro.motor.ligado = True ! self.carro.dar_partida() self.assertTrue(self.carro.esta_ligado()) ! def test_andar(self): self.carro.motor.ligado = True ! self.carro.dar_partida() self.assertIsNone(self.carro.andar()) ! def test_andar_com_carro_desligado_levanta_excecao(self): self.assertRaises(RuntimeError, self.carro.andar) ! Implementa a interface do objeto, com retornos previsíveis. O dublê entra em ação! rá! 16 Configuração de estado pré-teste.
  • 17. Mock import mocker # python 2 apenas =/ ! from cod3 import Carro ! ! class CarroTests(mocker.MockerTestCase): ! def test_dar_partida(self): # Inicio do treinamento MotorMock = self.mocker.mock() ! MotorMock() self.mocker.result(MotorMock) ! MotorMock.ligar() self.mocker.result(None) ! MotorMock.ligado self.mocker.result(True) ! self.mocker.replay() # Fim do treinamento ! carro = Carro(motor=MotorMock) carro.dar_partida() self.assertTrue(carro.esta_ligado()) Ver também: http://docs.python.org/3.3/library/unittest.mock.html labix.org/mocker 17
  • 18. import mocker ! from cod3 import Carro ! ! class CarroTests(mocker.MockerTestCase): ! def test_dar_partida(self): # Inicio do treinamento MotorMock = self.mocker.mock() ! MotorMock() self.mocker.result(MotorMock) ! MotorMock.ligar() self.mocker.result(None) ! #MotorMock.ligado #self.mocker.result(True) ! self.mocker.replay() # Fim do treinamento ! carro = Carro(motor=MotorMock) carro.dar_partida() self.assertTrue(carro.esta_ligado()) Removido o treino do atributo .ligado 18
  • 19. 19 "Mocke" com moderação • Testes menos manuteníveis • Mudanças de interface (API) • Inconsistências entre "treinamentos" • Prefira "mockar" os pontos de integração • Teste os mocks! o.O