desymfonyday 2014 - to mock or not to mock - spanish

52

Upload: akamon-engineering

Post on 14-Dec-2014

704 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: DeSymfonyDay 2014 - To mock or not to mock - Spanish
Page 2: DeSymfonyDay 2014 - To mock or not to mock - Spanish
Page 3: DeSymfonyDay 2014 - To mock or not to mock - Spanish

¿Quiénes somos?

Eloi Poch Jordi Llonch

Page 4: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Agenda• ¿Qué hacemos en Akamon?

• To test or not to test?

• ¿Cómo hacemos test?

• Librerías de mock.

• Conclusiones y consejos.

Page 5: DeSymfonyDay 2014 - To mock or not to mock - Spanish

• Osiris:

• Nueva plataforma de servicios de Akamon.

• Principios:

• Simplicidad sobre facilidad.

¿Qué hacemos?

Calidad

Funcionalidad Velocidad

Page 6: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Domain

Con

tract

Infrastructure

Domain (Business Logic)

Con

tract

Infrastructure

Domain (Business Logic)

Applications

Background

Website

APIsAPIsAPIs

Arquitecturaby Akamon

APIs

DBs

Con

tract

External Services

Infrastructure

Domain (Business Logic)

Page 7: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Calidad

• Pull Request • Pair Programming • Test

by Akamon

Page 8: DeSymfonyDay 2014 - To mock or not to mock - Spanish

To test or not to test?

Todo e

l mund

o

hace t

ests

Page 9: DeSymfonyDay 2014 - To mock or not to mock - Spanish

To test or not to test

Los buenos test ahorran DINERO en cualquier aplicación

Page 10: DeSymfonyDay 2014 - To mock or not to mock - Spanish

To test or not to test

Page 11: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Testear es controvertido

• David Heinemeier (creador de Ruby on Rails y Fundador y CTO de Basecamp)

• TDD is dead. Long live testing & RailsConf 2014 Keynote - Writing Software by DHH

• Hangouts entre Kent Beck, DHH y M. Fowler

El caso DHH

Page 12: DeSymfonyDay 2014 - To mock or not to mock - Spanish

¿Cómo hacemos test?

Akamon

Way

Page 13: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Un feedback rápido…

…para el código que estamos escribiendo…

…de una funcionalidad.

¿Qué queremos de los tests?

Page 14: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Testean de manera rápida una funcionalidad.

¿Qué hacen nuestros tests?

Page 15: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Infrastructure

External Services

Test Double

Test DoubleAPIs

DBs

Con

tract

Domain (Business Logic)

Page 16: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Test doubles• Implementación alternativa de un colaborador

(clase o servicio)

• Objetivo:

• Hacer nuestros tests rápidos.

• Aislar sistemas externos.

• Testear casos extremos.

Page 17: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Test doubles• Tipos:

• Dummy: Implementación no funcional.

• Fake: Implementación completamente funcional pero no usable en un entorno real.

• Stub: Implementación parcialmente funcional preparada únicamente para poder ser usada en el test.

• Spy: Stub con memoria.

• Mock: Spy con expectaciones sobre las llamadas a recibir que las auto-comprueba él mismo.

Page 18: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Tests UnitariosPros Contras

Rápidos No pueden probar la ausencia de errores

Permiten testear todos los casos Los doubles no son confiables

Ayudan a encontrar problemas pronto

Los doubles están acoplados a sus implementaciones

Facilitan el cambio

Buena documentación

Page 19: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Escuelas de Tests Unitarios

Chicago / Classical London / Mockist

Énfasis Algoritmo Envío de mensajes

Enfoque Resultado, estado y efectos colaterales

Roles, responsabilidades e

interacciones

LibroTest-Driven

Development by Example

Growing Object Oriented Software Guided by Tests

Page 20: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Unit Testing :: Chicago School• Pros:

• Menor riesgo de expectaciones incorrectas.

• Tests estables.

• Menos mantenimiento.

• Contras:

• Ciclo largo de Red-Green-Refactor.

• Explosión combinatoria de los casos a testear.

• Un simple bug rompe muchos tests.

• Más debugging para encontrar la raíz del error.

Page 21: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Unit Testing :: London School• Pros:

• Facilita el enfoque.

• Baby steps.

• Contras:

• Alto riesgo de expectaciones incorrectas (el refactoring no detecta cambios en los colaboradores)

• Acople del test a la implementación.

• Test frágiles.

Page 22: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Glosario• Test Unitarios:!

• Test del código y la lógica de negocio de una funcionalidad (operaciones con el contrato del módulo).

• Test double: La infraestructura y los servicios externos.

• Riesgo:

• Test demasiado profundo que no permita testear de manera simple todas las casuísticas

by Akamon

Page 23: DeSymfonyDay 2014 - To mock or not to mock - Spanish

…pero los test unitarios no son suficientes…

Page 24: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Queremos saber si las integraciones con los sistemas

externos funcionan correctamente.

Page 25: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Infrastructure

External ServicesAPIs

DBs

Con

tract

Domain (Business Logic)

Page 26: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Tests de Integración

Pros Contras

Confiables Lentos

Encontrar problemas/cambios con servicios de terceros

Imposible de testear algunos casos extremos

Buena documentación

Page 27: DeSymfonyDay 2014 - To mock or not to mock - Spanish

• Test de integración:!

• Test de las implementaciones de los contratos/interfaces de la infraestructura y los servicios externos.

• Test double: Nada.

by AkamonGlosario

Page 28: DeSymfonyDay 2014 - To mock or not to mock - Spanish

…pero con test unitario e integración todavía no es

suficiente…

Page 29: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Applications

APIs

Background

Website

APIsAPIs ?Domain

Module User

Module Analytics

Module Marketing

Module Device

Module Economy

Module Game

Module Game Event

Page 30: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Tests de AceptaciónPros Contras

Amigables y entendibles para usuarios no técnicos Lentos

Gran confianza Complicado de testear algunos casos

Buena documentación Imposible testear algunos casos extremos

Complicado localizar errores

Complicados de escribir (estado inicial)

Page 31: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Glosario

• Test de aceptación:!

• Test de una funcionalidad (end-to-end black-box mode).

• Test double: Nada.

by Akamon

Page 32: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Nuestra pirámide de tests

Acceptance

Integration

Unit

Page 33: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Librerías mock

https://github.com/Akamon/to-mock-or-not-to-mock

Page 34: DeSymfonyDay 2014 - To mock or not to mock - Spanish

PHPUnit_MockObject/** @test */!public function it_should_publish_a_message()!{! $body = 'my message';! $message = new Message($body);! $serializedMessage = ['body' => $body];!! $serializer = $this->getMock(SerializerInterface::class, ['serialize']);! $serializer! ->expects($this->once())! ->method('serialize')! ->with($this->identicalTo($message))! ->will($this->returnValue($serializedMessage));!! $sender = $this->getMock(SenderInterface::class, ['send']);! $sender! ->expects($this->once())! ->method('send')! ->with($this->equalTo($serializedMessage))! ->will($this->returnValue(true));!! $publisher = new Publisher($serializer, $sender);! $this->assertTrue($publisher->send($message));!}

Page 35: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Mockery/** @test */!public function it_should_publish_a_message()!{! $body = 'my message';! $message = new Message($body);! $serializedMessage = ['body' => $body];!! $serializer = Mockery::mock(SerializerInterface::class);! $serializer! ->shouldReceive('serialize')! ->with(Mockery::mustBe($message))! ->once()! ->andReturn($serializedMessage);!! $sender = Mockery::mock(SenderInterface::class);! $sender! ->shouldReceive('send')! ->with($serializedMessage)! ->once()! ->andReturn(true);!! $publisher = new Publisher($serializer, $sender);! $this->assertTrue($publisher->send($message));!}

Page 36: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Phake/** @test */!public function it_should_publish_a_message()!{! $body = 'my message';! $message = new Message($body);! $serializedMessage = ['body' => $body];!! $serializer = Phake::mock(SerializerInterface::class);! Phake::when($serializer)! ->serialize($message)! ->thenReturn($serializedMessage);!! $sender = Phake::mock(SenderInterface::class);! Phake::when($sender)! ->send($serializedMessage)! ->thenReturn(true);!! $publisher = new Publisher($serializer, $sender);! $this->assertTrue($publisher->send($message));!! Phake::verify($serializer, Phake::times(1))->serialize($message);! Phake::verify($sender, Phake::times(1))->send($serializedMessage);!}

Page 37: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Prophecy/** @var Prophet */!private $prophet;!!protected function setup()!{! $this->prophet = new Prophet();!}!!protected function tearDown()!{! $this->prophet->checkPredictions();!}!!/** @test */!public function it_should_publish_a_message()!{! $body = 'my message';! $message = new Message($body);! $serializedMessage = ['body' => $body];!! $serializer = $this->prophet->prophesize(SerializerInterface::class);! $serializer! ->serialize($message)! ->shouldBeCalled()! ->willReturn($serializedMessage);!! $sender = $this->prophet->prophesize(SenderInterface::class);! $sender! ->send($serializedMessage)! ->shouldBeCalled()! ->willReturn(true);!! $publisher = new Publisher($serializer->reveal(), $sender->reveal());! $this->assertTrue($publisher->send($message));!}

Page 38: DeSymfonyDay 2014 - To mock or not to mock - Spanish

ComparativaPHPUnit 4.1 Mockery 0.9 Phake 1.1 Prophecy 1.0 Notas

Invocation Count Constraint Ok Muy bueno Muy bueno Ok

Mockery/Phake son mejores. Métodos atMost() y atLeast()

disponibles.

Ordered Expectations Ok Bueno Ok No Mockery es mejor. Simplemente usando ordered([group]).

Argument Matchers Bueno Ok Ok Ok PHPUnit es mejor. Sobre todo con la funcionalidad delta

Partial Mocking Ok Muy bueno Ok No La construcción es mucho más simple con Mockery.

Mocking Demeter Chains And Fluent

InterfacesOk Muy bueno Ok Ok Muy sencillo con Mockery y un poco

rebuscado con los otros.

Test Doubles Ok Bueno Ok BuenoProphecy es el único con spies y Mockery el único que gestiona

static, final & private

Page 39: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Otro punto de vista

Page 40: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Property-Based Testing• Aproximación totalmente diferente.

• No se escriben los tests, se generan.

• QuickCheck: Canonical framework escrito en Haskell.

• ¿Cómo funciona?:

• Describe las entradas y salidas permitidas y las transiciones de estado.

• Genera aleatóriamente un gran número de casos de test y busca fallos.

• Devuelve el mínimo ejemplo de fallo.

• Casos de uso: Comportamientos no determinísticos y sistemas concurrentes.

Page 41: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Conclusiones

En el mundo del testing lo más importante es determinar la unidad o sistema a testear.

Los tipos de tests, los doubles e incluso los frameworks dependen de la unidad o sistema a

testear.

Page 42: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Consejos

• Evita Minimiza los dobles:

• Están acoplados a la implementación ➙ Limitan la refactorización pura.

• No son confiables ➙ Pueden tener un comportamiento diferente al real.

by Akamon

Page 43: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Consejos

• Los test unitarios testean código no funcionalidad:

• TDD por si solo no es suficiente.

• BDD por si solo puede ser suficiente (si no te importa la lentitud).

• TDD + BDD = WIN

by Akamon

Page 44: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Consejos

• Separa la lógica del test de los datos del test:

• Usa el @dataProvider de PHPUnit (no para los doubles).

• Usa el Scenario Outline de Behat.

by Akamon

Page 45: DeSymfonyDay 2014 - To mock or not to mock - Spanish

• La unidad a testear:

• Mockists are dead. Long live classicists.

• Unit Tests: Isolation

• Mock aren’t stubs: Dummy, Fake, Stub and Mock

• TTDD (Tautological TDD): An anti-pattern

• The depth of tests

• Avoid Testing Implementation Details, Test Behaviours

• The Failures of "Intro to TDD"

• The London School of Test Driven Development

Referencias

Page 47: DeSymfonyDay 2014 - To mock or not to mock - Spanish

• Contract tests (a.k.a integration tests):

• Integrated tests are scam (Collaboration & Contract tests)

• Integration contract tests

Referencias

Page 48: DeSymfonyDay 2014 - To mock or not to mock - Spanish

• La pirámide de los tests:

• Test Pyramid

• Testing Pyramid: A case study

• Inverting the testing pyramid

• Testing ice-crean corn anti-pattern

Referencias

Page 49: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Referencias

• Property-Based testing:

• Better than unit tests

• Powerful testing with test.check

• Testing the Hard Stuff and Staying Sane

Page 50: DeSymfonyDay 2014 - To mock or not to mock - Spanish

• Entrevistas a veteranos del TDD:

• Ron Jeffries (One of the founders of Extreme Programming & Agile Manifesto)

• Steve Freeman (Co-author of Growing Object-Oriented Software Guided by Tests)

• James Shore (Author of The Art of Agile Development)

• J.B. Rainsberger (Author of JUnit Recipes : Practical Methods for Programmer Testing

Referencias

Page 51: DeSymfonyDay 2014 - To mock or not to mock - Spanish

¿Preguntas?

¡Gracias!

Page 52: DeSymfonyDay 2014 - To mock or not to mock - Spanish

Imágeneshttp://transmedialshakespeare.files.wordpress.com/2011/01/3459513455_d1288a14b9_o.jpeg

http://info.fonality.com/Portals/65551/images/Presentation.jpg

http://www.renders-graphiques.fr/image/upload/normal/organisateur_bloc_notes_agenda-.png

http://www.luxfacta.com/wp-content/uploads/2014/01/programar.jpg

http://www.kinderlandshop.es/WebRoot/StoreES2/Shops/eb0950/5020/E112/E380/66B2/C9CA/AC10/1414/0340/C05_1.jpg

http://www.allpurposeabrasives.com.au/uploads/images/Quality%20Assurrance.jpg

http://news.liv.ac.uk/wp-content/uploads/2013/03/knowledgeHOMEb.jpg

http://www.worldnpa.org/site/wp-content/uploads/2013/01/hand-writing.jpg

http://ievasapple.com/photo/images/my%20point%20of%20view.JPG

http://www.snegmortgageteam.ca/wp-content/uploads/2013/12/mortgage-glossary.jpg

http://birddogrealestate.net/wp-content/uploads/2012/09/Home-Toolbox.jpg

http://www.balticblues-events.com/sites/default/files/images/ideas/photos/32-Live-Cooking1.jpg

http://www.youwall.com/papel/on_my_way_wallpaper_fa2bb.jpg

http://inheritancethefilm.com/wp-content/uploads/2013/06/thankyou.jpg

http://www.ngn.com.au/wp-content/uploads/2013/07/Websites-on-white.png

http://hn-marketing.co.uk/wp-content/uploads/2012/09/shutterstock_12553684.jpg

http://picturesofmoney.org/wp-content/uploads/2013/04/Animated-American-Money-Falling-Into-a-Pile.jpg

http://st.gdefon.com/wallpapers_original/wallpapers/18716_palma_more_plyazh_pesok_oblaka_tropiki_2560x1600_(www.GdeFon.ru).jpg

http://i.imgur.com/DbTGPys.gif

http://media.tumblr.com/e96b538708be71104f21689d3a820b9c/tumblr_inline_n54iazp56x1raprkq.gif

http://i.imgur.com/8Lpsys5.gif