tdd com mock e orientação a objetos (pyne 2015)

47
PyNE 2015 TDD com Mock e Orientação a Objetos Bernardo Fontes Natal/RN 16 de Maio de 2015

Upload: bernardo-fontes

Post on 23-Jul-2015

90 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

PyNE 2015TDD com Mock e Orientação a Objetos

Bernardo FontesNatal/RN

16 de Maio de 2015

Page 3: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

github.com/berinhard/talks

Page 4: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Obrigado, Turicas!

Page 5: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Obrigado, Turicas!

Page 6: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

RoteiroBásicos de Orientação aObjetosTest-driven Development(TDD)TDD Com MocksDúvidas

Page 7: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Básicos de Orientação aObjetos

Não é fazer getter e setter

Page 8: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Orientação aObjetos?

Estratégia de DesignDefinição de EstadoEncapsulamentoColaboração com troca deMensagens

Page 9: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

S.O.L.I.D.

Page 10: Tdd Com Mock e Orientação a Objetos (PyNE 2015)
Page 11: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Exemplo Pythonfrom datetime import date

class Ticket(object):

def __init__(self, buyer, price, schedule_date): self.buyer = buyer self.price = price self.schedule_date = schedule_date

def has_expired(self): return date.today() > self.schedule_date

#############################

ticket = Ticket("Bernardo", 10, date(2015, 10, 10))if not ticket.has_expired(): #processa ticket válido

Page 12: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Referências

Page 14: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Test-driven Development (TDD)

Page 15: Tdd Com Mock e Orientação a Objetos (PyNE 2015)
Page 16: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Primeiro o testeclass Ticket(TestCase):

def test_3_returns_fizz(self): self.assertEqual("fizz", fizz(3))

Page 17: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Primeira implementaçãodef foo(number): return "fizz"

class Ticket(TestCase):

def test_3_returns_fizz(self): self.assertEqual("fizz", fizz(3))

Page 18: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Coding Dojo!!!

Page 20: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Processo de Design

Page 21: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Design EmergenteRefatoraçãoRemoção de AcoplamentosDuplicidade

Page 22: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Exploração e Descobertacansativo...

Page 23: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Sem Evidência do Designclass TestTicketManager(TestCase):

def test_expire_ticket(self): ticket = Ticket.objects.create(id=30) self.assertFalse(ticket.expired)

manager = TicketManager() manager.expire_ticket(ticket_id=30)

ticket = Ticket.objects.get(id=30) self.assertTrue(ticket.expired)

Page 24: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Difícil de começar a testar noalto nível

Infra vs Domínio

Page 25: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Referências

Page 26: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Curso TDD - J. B. Rainsberger

Page 27: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

TDD com Mock

Page 28: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

MockSimulam funcionamento de objetosRespeitam API dos objetosViabilizam maneira de fazer asserções

Page 29: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Foco do Domíno nasMensagens

Menos Estado e mais Colaboração

Page 30: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Implementação de Testes Top-Down

Page 31: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Need-Driven DevelopmentCódigo criado só se necessário

Page 32: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

TODO ListRecuperar IngressoExpirá-loNotificar Usuário

Page 33: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Entry Pointclass TestTicketManager(TestCase):

def test_expire_ticket(self): manager = TicketManager() manager.expire_ticket(ticket_id=30)

Page 34: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Recuperar Ingressofrom mock import Mock

class TestTicketManager(TestCase):

def test_expire_ticket(self): tickets_repository = Mock(TicketsRepository) tickets_repository.get_by_id.return_value = Ticket()

manager = TicketManager(tickets_repository) manager.expire_ticket(ticket_id=30)

tickets_repository.get_by_id.assert_called_once_with(30)

Page 35: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

class TicketManager(object):

def __init__(self, tickets_repository): self.repository = tickets_repository

def expire_ticket(self, ticket_id): self.repository.get_by_id(ticket_id)

class Ticket(object): pass

class TicketsRepository(object):

def get_by_id(self, id): "Must return a Ticket object" pass

Page 36: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Expirar Ingressofrom mock import Mock

class TestTicketManager(TestCase):

def test_expire_ticket(self): ticket = Mock(Ticket) tickets_repository = Mock(TicketsRepository) tickets_repository.get_by_id.return_value = ticket

manager = TicketManager(tickets_repository) manager.expire_ticket(ticket_id=30)

tickets_repository.get_by_id.assert_called_once_with(30) ticket.expire.assert_called_once_with()

Page 37: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

class TicketManager(object):

def __init__(self, tickets_repository): self.repository = tickets_repository

def expire_ticket(self, ticket_id): ticket = self.repository.get_by_id(ticket_id) ticket.expire()

class Ticket(object):

def expire(self): pass

class TicketsRepository(object):

def get_by_id(self, id): "Must return a Ticket object"

Page 38: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Notificar Usuáriofrom mock import Mock

class TestTicketManager(TestCase):

def test_expire_ticket(self): ticket = Mock(Ticket) tickets_repository = Mock(TicketsRepository) tickets_repository.get_by_id.return_value = ticket notificator = Mock(TicketNotificator)

manager = TicketManager(tickets_repository, notificator) manager.expire_ticket(ticket_id=30)

tickets_repository.get_by_id.assert_called_once_with(30) ticket.expire.assert_called_once_with() notificator.notify_expired.assert_called_once_with(ticket)

Page 39: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

class TicketManager(object):

def __init__(self, tickets_repository, notificator): self.repository = tickets_repository self.notificator = notificator

def expire_ticket(self, ticket_id): ticket = self.repository.get_by_id(ticket_id) ticket.expire() self.notificator.notify_expired(ticket)

class Ticket(object):

def expire(self): pass

class TicketsRepository(object):

Page 40: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Respeito ao contrato é tudoComportamentos de EntradaComportamentos de Saída

Page 41: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Novos testes para garantircontrato e funcionamentounitário dos componentes

Page 42: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Referências

Page 43: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Mock Roles, not Objects

Page 46: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Dúvidas?

Page 47: Tdd Com Mock e Orientação a Objetos (PyNE 2015)

Obrigado!Bernardo Fontes

twitter.com/bbfontesgithub.com/berinhard

garimpo.fmpessoas.cc

[email protected]