SlideShare una empresa de Scribd logo
1 de 77
TDD: Cómo escribir código testeable.
¿Hacer tests es bueno?
¿Por qué no los hacemos?
Razones Válidas ¡No se! Código antiguo UI No hacer pruebas Inválidas El diseño es malo De eso se encarga QA No coge los bugs Demasiadas interfaces Es lento Aburido…. Es dificil de cambiar
Hacer tests es una habilidad
Entonces… ¿Cómo se escribe código difícil de probar?
¿Por qué? Construcción de objetos 	Trabajo en el constructor 	Estados globales 	Violaciones de la Ley de Deméter
Localización del “new” Estímulo API de Pruebas Clase bajo prueba Verificaciones
Localización del “new” Otra clase Estímulo Otra clase API de Pruebas Clase bajo prueba Verificaciones Otra clase Instanciado dentro de la clase Pasado por referencias Estados globales
Localización del “new” Otra clase Otra clase Otra clase Otra clase Estímulo Otra clase API de Pruebas Clase bajo prueba Otra clase Verificaciones Otra clase
Localización del “new” Otra clase Otra clase Otra clase Otra clase Estímulo Otra clase API de Pruebas Clase bajo prueba Costura Otra clase Verificaciones Otra clase
Localización del “new” Clase Falsa Estímulo Clase Falsa API de Pruebas Clase bajo prueba Costura Verificaciones Clase Falsa
Localización del “new” Lógica de Negocio Construcción del  Grafo de Objetos y  Búsqueda
Localización del “new” Lógica de Negocio Construcción del  Grafo de Objetos y  Búsqueda
Localización del “new” Clase Falsa Estímulo Clase Falsa API de Pruebas Clase bajo prueba Verificaciones Clase Falsa Instanciado dentro de la clase Pasado por referencias Estados globales
Ejemplo (House)
House classHouse { Kitchenkitchen = new Kitchen(); Bedroombedroom; publicHouse()  	{ this.bedroom = new Bedroom(); 	} }
House Test classHouseTests { 	@Test publicvoidimpossibleTestOnIsolation() { 		// Can’treplaceanything!!! } }
Análisis 	Fácil de instanciar pero… 		No se puede remplazar nada. 	Puede ser costoso computacionalmente 	El diseño está acoplado.  	Cerrado para extensión.
House (Refactoizado) classHouse { Kitchenkitchen; Bedroombedroom; @Inject publicHouse(Kitchenkitchen, Bedroombr) { this.bedroom = br; this.kitchen = kitchen; } }
House Test (Refactorizado) classHouseTests { 	@Test publicvoideasierToTestOnIsolation() { DummyKitchendk = new DummyKitchen(); DummyBedroomdb = new DummyBedroom(); House h = new House(dk,db); 	// … } }
Ejemplo (Gardener)
Gardener class Garden { Gardenerjoe; public Garden(Gardenerjoe) { joe.setWorkHours(new TwelveHours()); joe.setBoots(new ExpensiveBoots()); 		this.joe = joe; 	} }
Análisis 	Mejor pero…  		No se pueden remplazar las botas o el 	horario. 	La prueba puede tardar (horario de 12h). 	Necesita el jardinero pero se encarga de 	configurarlo.
Gardener (Refactored) class Garden { Gardenerjoe; 	@Inject public Garden(Gardenerjoe) { 	this.joe = joe; 	} } classGardenerProvider { 	@Provides GardenergetGardener(ExpensiveBootsboots, TwelveHoursschedule) { Gardenerjoe = new Gardener(); joe.setWorkHours(schedule); joe.setBoots(boots); returnjoe; 	} }
¿Por qué? Construcción de objetos Trabajo en el constructor 	Estados globales 	Violaciones de la Ley de Deméter
Costo de la construcción 	Para testear, primero hay que instanciar pero… El trabajo dentro del constructor no tiene “costuras” 	No se puede sobre escribir. 	La prueba tiene que saber navegar lo 	que haya dentro
Ejemplo (Super Car)
Super Car class Car { Engineengine; public Car(Filefile) { String m = readModelFromCfg(file); engine = new EngineFactory().create(m); } }
Super Car Test classCarTest { @Test publicvoidhardToSetupTest() { Filefile = new File(“custom.conf”); 	Car car = new Car(file); 	//Asserts... } }
Análisis 	Pasamos un File cuando lo que se necesita es un Engine. 	Toda prueba que necesite Car requiere eta parafernaria. Accede al sistema de ficheros 	Lento. 	No es una prueba unitaria realmente.
Super Car (Refactorizado) class Car { Engineengine; @Inject public Car(Engineengine) { this.engine = engine; } }
Super Car (Provider) classCarEngineProvider { @Provides EnginegetEngine(EngineFactoryfactory, @EngineModelStringmodel) { returnfactory.create(model); } }
Super Car Test (Refactorizado) classCarTest { @Test publicvoideasyToSetupTest() { Engineengine = new FakeEngine(); 	Car car = new Car(engine); 	//Asserts... } }
¿Por qué? Construcción de objetos 	Trabajo en el constructor 	Estados globales 	Violaciones de la Ley de Deméter
Locura
Locura Definición: Repetir una misma acción una y otra vez y esperar obtener un resultado diferente. Albert Einstein
O mejor dicho… Estados Globales class X { public X() { } publicintdoSomething() { 	//… Something… } }
Estados Globales int a = new X().doSomething(); int b = new X().doSomething();
Estados Globales ¿ a == b ó a != b ?
Estados Globales X x1 = new X(); Y Q X Z
Estados Globales X x1 = new X(); X x2 = new X(); Y Q X Z Y Q X Z
Estados Globales X x1 = new X(); x1.doSomething(); A == B ó A != B X x2 = new X(); x2.doSomething(); Y Q X Z GS Y Q X Z
Consecuencias 	Múltiples ejecuciones 	Resultados inesperados 	Orden importa 	No se pueden ejecutar en paralelo 	Localización del estado desacotado.
Estados Globales Ocultos System.currentTime() new Date() Math.random()
Consecuencias 	La API miente: 	A cerca de lo que necesita 	Hace cosas que dan miedo detrás de la 	fachada
Ejemplo (CreditCard)
CreditCard @Test publicvoidcreditCardChargeTest() { CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); }
CreditCard @Test publicvoidcreditCardChargeTest() { CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); } java.lang.NullPointerException at talk2.CreditCard.charge(CreditCard.java:48)
CreditCard @Test publicvoidcreditCardChargeTest() { CreditCardProcessor.init(…); CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); }
CreditCard @Test publicvoidcreditCardChargeTest() { CreditCardProcessor.init(…); CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); } java.lang.NullPointerException at talk2.CreditCardProcessor.init(CreditCardProcessor.java:134)
CreditCard @Test publicvoidcreditCardChargeTest() { OfflineQueue.start(); CreditCardProcessor.init(…); CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); }
CreditCard @Test publicvoidcreditCardChargeTest() { OfflineQueue.start(); CreditCardProcessor.init(…); CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); } java.lang.NullPointerException at talk2.OffileQueue.start (OfflineQueue.java:203)
CreditCard @Test publicvoidcreditCardChargeTest() { Database.connect(…); OfflineQueue.start(); CreditCardProcessor.init(…); CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); }
CreditCard ¿Se ve un patrón?
CreditCard Miente sobre sus dependencias. El orden de las inicializaciones no es explicito.
CreditCard ¿Qué podemos hacer?
CreditCard (Refactorizado) @Test publicvoidcreditCardChargeTest() { Databasedb = Database(“connectionStr”); OfflineQueuequeue = new OfflineQueue(db); CreditCardProcessorccProcessor = new CreditCardProcessor(queue); CreditCardcc = new CreditCard(“1234567890”, ccProcesor); cc.charge(200); }
CreditCard ¡Tenemos opciones!
CreditCard Pero… 	¿Y si termino con 20 parámetros? 	Es porque los tenias… solo que…
Accounting 101 classAccountView { Useruser; publicAccountView() { user = RPCClient.getInstance().getUser(); } }
Análisis 	Uso de Estados Globales Incorpora las dependencias del “singleton” Miente a cerca de las dependencias.
Accounting 101 classAccountView { Useruser; publicAccountView(Useruser) { user = user; } }
¿Por qué? Construcción de objetos 	Trabajo en el constructor Estados globales Violaciones de la Ley de Deméter
La ley de Deméter 	Cada unidad debería tener conocimiento limitado sobre otras unidades: solo unidades “relacionadas de cerca” a la unidad actual.  	Cada unidad debe de hablar solamente con sus amigos; No hablar con extraños. 	Habla solamente con tus amigos inmediatos.
ServiceLocator Aka. Context, aka. Registry… etc. Mejor que un singleton Al menos el problema está en un solo lugar. Es testeable… pero no muy bonito. Esconde las dependencias reales. Las dependencias hacen el código poco reusable.
ServiceLocator ClassHouse { 	//…  publicHouse(Locatorlocator) { 	//… Qué tengo que mockear??? 	} }
House ClassHouse { //… Windowwindow; Doordoor; Roofroof; publicHouse(Locatorlocator) { this.window = locator.getWindow(); this.door = locator.getDoor(); this.roof = locator.getRoof(); 	} }
House (Refactorizado) classHouse { //… Windowwindow; Doordoor; Roofroof; publicHouse(Window w, Door d, Roof, r) { this.window = w; this.door = d; this.roof = r; 	} }
ServiceLocator ¿Qué otro problema tiene? 	Mezcla responsabilidades. 	Buscar y encontrar. 	Creación Se necesita tener una interface para testear Si dependes de ServiceLocator, dependes de todo lo demás.
Making a Mockery… classLoginPage { RPCClientclient; HttpRequestrequest; publicLoginPage(RPCClientclient, HttpRequestrequest) { this.client = client; this.request = request; 	} publicbooleanlogin() { String cookie = request.getCookie(); returnclient.getAuthenticator().authenticate(cookie); 	} }
Análisis Para testear se hace complicado Las dependencias no son las declaradas. Crear rpcclient, entrenarlo para devolver un authenticator, crear un authenticator… Etc.
Making a Mockery… classLoginPage { Authenticatorauthenticator; String cookie; publicLoginPage(Authenticatorauth, @Cookie String cookie) { this.cookie= cookie; this.authenticator =  auth; 	} publicbooleanlogin() { returnauthenticator.authenticate(cookie); 	} }
Making a Mockery Cosas a tener en cuenta. Tiempo de vida de los objetos que se pasan. 	Ej. Cookie puede ser distinto para 	cada vez
TDD: ¿Cómo escribir código testeable?

Más contenido relacionado

La actualidad más candente

An introduction to Struts 2 and RESTful applications
An introduction to Struts 2 and RESTful applicationsAn introduction to Struts 2 and RESTful applications
An introduction to Struts 2 and RESTful applicationsmrdon
 
Java MySQL Connector & Connection Pool Features & Optimization
Java MySQL Connector & Connection Pool Features & OptimizationJava MySQL Connector & Connection Pool Features & Optimization
Java MySQL Connector & Connection Pool Features & OptimizationKenny Gryp
 
Linux tuning to improve PostgreSQL performance
Linux tuning to improve PostgreSQL performanceLinux tuning to improve PostgreSQL performance
Linux tuning to improve PostgreSQL performancePostgreSQL-Consulting
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVMRafael Winterhalter
 
RocksDB compaction
RocksDB compactionRocksDB compaction
RocksDB compactionMIJIN AN
 
Large Table Partitioning with PostgreSQL and Django
 Large Table Partitioning with PostgreSQL and Django Large Table Partitioning with PostgreSQL and Django
Large Table Partitioning with PostgreSQL and DjangoEDB
 
Postgresql Database Administration- Day3
Postgresql Database Administration- Day3Postgresql Database Administration- Day3
Postgresql Database Administration- Day3PoguttuezhiniVP
 
Percona XtraDB Cluster ( Ensure high Availability )
Percona XtraDB Cluster ( Ensure high Availability )Percona XtraDB Cluster ( Ensure high Availability )
Percona XtraDB Cluster ( Ensure high Availability )Mydbops
 
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015PostgreSQL-Consulting
 
jemalloc 세미나
jemalloc 세미나jemalloc 세미나
jemalloc 세미나Jang Hoon
 
[Outdated] Secrets of Performance Tuning Java on Kubernetes
[Outdated] Secrets of Performance Tuning Java on Kubernetes[Outdated] Secrets of Performance Tuning Java on Kubernetes
[Outdated] Secrets of Performance Tuning Java on KubernetesBruno Borges
 
PostgreSQL HA
PostgreSQL   HAPostgreSQL   HA
PostgreSQL HAharoonm
 
Streaming Operational Data with MariaDB MaxScale
Streaming Operational Data with MariaDB MaxScaleStreaming Operational Data with MariaDB MaxScale
Streaming Operational Data with MariaDB MaxScaleMariaDB plc
 
High Availability PostgreSQL with Zalando Patroni
High Availability PostgreSQL with Zalando PatroniHigh Availability PostgreSQL with Zalando Patroni
High Availability PostgreSQL with Zalando PatroniZalando Technology
 
ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)YoungHeon (Roy) Kim
 
ProxySQL - High Performance and HA Proxy for MySQL
ProxySQL - High Performance and HA Proxy for MySQLProxySQL - High Performance and HA Proxy for MySQL
ProxySQL - High Performance and HA Proxy for MySQLRené Cannaò
 
MongoDB WiredTiger Internals: Journey To Transactions
MongoDB WiredTiger Internals: Journey To TransactionsMongoDB WiredTiger Internals: Journey To Transactions
MongoDB WiredTiger Internals: Journey To TransactionsMydbops
 

La actualidad más candente (20)

An introduction to Struts 2 and RESTful applications
An introduction to Struts 2 and RESTful applicationsAn introduction to Struts 2 and RESTful applications
An introduction to Struts 2 and RESTful applications
 
Java MySQL Connector & Connection Pool Features & Optimization
Java MySQL Connector & Connection Pool Features & OptimizationJava MySQL Connector & Connection Pool Features & Optimization
Java MySQL Connector & Connection Pool Features & Optimization
 
Linux tuning to improve PostgreSQL performance
Linux tuning to improve PostgreSQL performanceLinux tuning to improve PostgreSQL performance
Linux tuning to improve PostgreSQL performance
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVM
 
RocksDB compaction
RocksDB compactionRocksDB compaction
RocksDB compaction
 
Large Table Partitioning with PostgreSQL and Django
 Large Table Partitioning with PostgreSQL and Django Large Table Partitioning with PostgreSQL and Django
Large Table Partitioning with PostgreSQL and Django
 
Postgresql Database Administration- Day3
Postgresql Database Administration- Day3Postgresql Database Administration- Day3
Postgresql Database Administration- Day3
 
Query logging with proxysql
Query logging with proxysqlQuery logging with proxysql
Query logging with proxysql
 
Typeorm decorators
Typeorm decoratorsTypeorm decorators
Typeorm decorators
 
Percona XtraDB Cluster ( Ensure high Availability )
Percona XtraDB Cluster ( Ensure high Availability )Percona XtraDB Cluster ( Ensure high Availability )
Percona XtraDB Cluster ( Ensure high Availability )
 
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
 
jemalloc 세미나
jemalloc 세미나jemalloc 세미나
jemalloc 세미나
 
[Outdated] Secrets of Performance Tuning Java on Kubernetes
[Outdated] Secrets of Performance Tuning Java on Kubernetes[Outdated] Secrets of Performance Tuning Java on Kubernetes
[Outdated] Secrets of Performance Tuning Java on Kubernetes
 
PostgreSQL HA
PostgreSQL   HAPostgreSQL   HA
PostgreSQL HA
 
Streaming Operational Data with MariaDB MaxScale
Streaming Operational Data with MariaDB MaxScaleStreaming Operational Data with MariaDB MaxScale
Streaming Operational Data with MariaDB MaxScale
 
High Availability PostgreSQL with Zalando Patroni
High Availability PostgreSQL with Zalando PatroniHigh Availability PostgreSQL with Zalando Patroni
High Availability PostgreSQL with Zalando Patroni
 
ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)ProxySQL & PXC(Query routing and Failover Test)
ProxySQL & PXC(Query routing and Failover Test)
 
ProxySQL - High Performance and HA Proxy for MySQL
ProxySQL - High Performance and HA Proxy for MySQLProxySQL - High Performance and HA Proxy for MySQL
ProxySQL - High Performance and HA Proxy for MySQL
 
MongoDB WiredTiger Internals: Journey To Transactions
MongoDB WiredTiger Internals: Journey To TransactionsMongoDB WiredTiger Internals: Journey To Transactions
MongoDB WiredTiger Internals: Journey To Transactions
 
Get to know PostgreSQL!
Get to know PostgreSQL!Get to know PostgreSQL!
Get to know PostgreSQL!
 

Destacado (10)

Tdd like beethoven
Tdd like beethovenTdd like beethoven
Tdd like beethoven
 
CAS2013 - ¿Cómo evitar que se vaya al carajo tu implantación de agile?
CAS2013 - ¿Cómo evitar que se vaya al carajo tu implantación de agile?CAS2013 - ¿Cómo evitar que se vaya al carajo tu implantación de agile?
CAS2013 - ¿Cómo evitar que se vaya al carajo tu implantación de agile?
 
Principios SOLID de Diseño Orientado a Objetos
Principios SOLID de Diseño Orientado a ObjetosPrincipios SOLID de Diseño Orientado a Objetos
Principios SOLID de Diseño Orientado a Objetos
 
La muerte del silo - CAS2016
La muerte del silo - CAS2016La muerte del silo - CAS2016
La muerte del silo - CAS2016
 
Developing leadership in the agile organization
Developing leadership in the agile organizationDeveloping leadership in the agile organization
Developing leadership in the agile organization
 
An introduction to agile leadership
An introduction to agile leadershipAn introduction to agile leadership
An introduction to agile leadership
 
Win win negotiation techniques
Win win negotiation techniquesWin win negotiation techniques
Win win negotiation techniques
 
LeanUX - Presentation slides
LeanUX - Presentation slidesLeanUX - Presentation slides
LeanUX - Presentation slides
 
How to write good user stories
How to write good user storiesHow to write good user stories
How to write good user stories
 
Building teams that excel - Creating trust in teams
Building teams that excel - Creating trust in teamsBuilding teams that excel - Creating trust in teams
Building teams that excel - Creating trust in teams
 

Similar a TDD: ¿Cómo escribir código testeable?

Unit Testing - Trovit
Unit Testing - TrovitUnit Testing - Trovit
Unit Testing - TrovitJordi Gerona
 
Unit Testing - GTUG
Unit Testing - GTUGUnit Testing - GTUG
Unit Testing - GTUGJordi Gerona
 
Desarrollo con Java y metodologías agiles
Desarrollo con Java y metodologías agilesDesarrollo con Java y metodologías agiles
Desarrollo con Java y metodologías agilesJobsket
 
Notas clase java ii
Notas clase java iiNotas clase java ii
Notas clase java ii1 2d
 
Cómo lograr mejores pruebas
Cómo lograr mejores pruebasCómo lograr mejores pruebas
Cómo lograr mejores pruebasAndreína Romero
 
Notas clase
Notas claseNotas clase
Notas clase1 2d
 
Notas clase java ii
Notas clase java iiNotas clase java ii
Notas clase java ii1 2d
 
Notas clase
Notas claseNotas clase
Notas clase1 2d
 
Probando aplicaciones AngularJS
Probando aplicaciones AngularJSProbando aplicaciones AngularJS
Probando aplicaciones AngularJSRodrigo Pimentel
 
Rendimiento en aplicaciones web con Symfony2
Rendimiento en aplicaciones web con Symfony2Rendimiento en aplicaciones web con Symfony2
Rendimiento en aplicaciones web con Symfony2Asier Marqués
 
Bases de Datos en Java - Intro a JDBC
Bases de Datos en Java - Intro a JDBCBases de Datos en Java - Intro a JDBC
Bases de Datos en Java - Intro a JDBCCarlos Hernando
 
Conexión a postgres desde
Conexión a postgres desdeConexión a postgres desde
Conexión a postgres desdejbersosa
 
3. Curso Java JDBC (Bases de datos) - Curso 2005-2006
3. Curso Java JDBC (Bases de datos) - Curso 2005-20063. Curso Java JDBC (Bases de datos) - Curso 2005-2006
3. Curso Java JDBC (Bases de datos) - Curso 2005-2006Samuel Marrero
 
Grails 2013 - PUCMM - Santiago - Sistemas
Grails 2013 - PUCMM - Santiago - SistemasGrails 2013 - PUCMM - Santiago - Sistemas
Grails 2013 - PUCMM - Santiago - SistemasCarlos Camacho
 
[ES] Conectividad de java a base de datos(jdbc)
[ES] Conectividad de java a base  de datos(jdbc)[ES] Conectividad de java a base  de datos(jdbc)
[ES] Conectividad de java a base de datos(jdbc)Eudris Cabrera
 
Conexion bd en java y api necesaria
Conexion bd en java y api necesariaConexion bd en java y api necesaria
Conexion bd en java y api necesariaBoris Salleg
 

Similar a TDD: ¿Cómo escribir código testeable? (20)

Unit Testing - Trovit
Unit Testing - TrovitUnit Testing - Trovit
Unit Testing - Trovit
 
Unit Testing - GTUG
Unit Testing - GTUGUnit Testing - GTUG
Unit Testing - GTUG
 
Desarrollo con Java y metodologías agiles
Desarrollo con Java y metodologías agilesDesarrollo con Java y metodologías agiles
Desarrollo con Java y metodologías agiles
 
Metadata api en apex
Metadata api en apexMetadata api en apex
Metadata api en apex
 
Notas clase java ii
Notas clase java iiNotas clase java ii
Notas clase java ii
 
Cómo lograr mejores pruebas
Cómo lograr mejores pruebasCómo lograr mejores pruebas
Cómo lograr mejores pruebas
 
Notas clase
Notas claseNotas clase
Notas clase
 
Notas clase java ii
Notas clase java iiNotas clase java ii
Notas clase java ii
 
Notas clase
Notas claseNotas clase
Notas clase
 
Probando aplicaciones AngularJS
Probando aplicaciones AngularJSProbando aplicaciones AngularJS
Probando aplicaciones AngularJS
 
Rendimiento en aplicaciones web con Symfony2
Rendimiento en aplicaciones web con Symfony2Rendimiento en aplicaciones web con Symfony2
Rendimiento en aplicaciones web con Symfony2
 
Bases de Datos en Java - Intro a JDBC
Bases de Datos en Java - Intro a JDBCBases de Datos en Java - Intro a JDBC
Bases de Datos en Java - Intro a JDBC
 
Conexión a postgres desde
Conexión a postgres desdeConexión a postgres desde
Conexión a postgres desde
 
3. Curso Java JDBC (Bases de datos) - Curso 2005-2006
3. Curso Java JDBC (Bases de datos) - Curso 2005-20063. Curso Java JDBC (Bases de datos) - Curso 2005-2006
3. Curso Java JDBC (Bases de datos) - Curso 2005-2006
 
Grails 2013 - PUCMM - Santiago - Sistemas
Grails 2013 - PUCMM - Santiago - SistemasGrails 2013 - PUCMM - Santiago - Sistemas
Grails 2013 - PUCMM - Santiago - Sistemas
 
Jdbc
JdbcJdbc
Jdbc
 
[ES] Conectividad de java a base de datos(jdbc)
[ES] Conectividad de java a base  de datos(jdbc)[ES] Conectividad de java a base  de datos(jdbc)
[ES] Conectividad de java a base de datos(jdbc)
 
Grails barcamp 2013
Grails barcamp 2013Grails barcamp 2013
Grails barcamp 2013
 
JQuery Mvc
JQuery   MvcJQuery   Mvc
JQuery Mvc
 
Conexion bd en java y api necesaria
Conexion bd en java y api necesariaConexion bd en java y api necesaria
Conexion bd en java y api necesaria
 

Último

EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveFagnerLisboa3
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITMaricarmen Sánchez Ruiz
 
Desarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdfDesarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdfJulian Lamprea
 
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxEL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxMiguelAtencio10
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan JosephBRAYANJOSEPHPEREZGOM
 
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricKeyla Dolores Méndez
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxAlan779941
 
presentacion de PowerPoint de la fuente de poder.pptx
presentacion de PowerPoint de la fuente de poder.pptxpresentacion de PowerPoint de la fuente de poder.pptx
presentacion de PowerPoint de la fuente de poder.pptxlosdiosesmanzaneros
 
Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfAnnimoUno1
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estossgonzalezp1
 
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdfRefrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdfvladimiroflores1
 
Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíassuserf18419
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanamcerpam
 
Presentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxPresentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxLolaBunny11
 
Presentación de elementos de afilado con esmeril
Presentación de elementos de afilado con esmerilPresentación de elementos de afilado con esmeril
Presentación de elementos de afilado con esmerilJuanGallardo438714
 

Último (15)

EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial Uninove
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNIT
 
Desarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdfDesarrollo Web Moderno con Svelte 2024.pdf
Desarrollo Web Moderno con Svelte 2024.pdf
 
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxEL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Joseph
 
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
 
presentacion de PowerPoint de la fuente de poder.pptx
presentacion de PowerPoint de la fuente de poder.pptxpresentacion de PowerPoint de la fuente de poder.pptx
presentacion de PowerPoint de la fuente de poder.pptx
 
Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdf
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdfRefrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
 
Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnología
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
Presentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxPresentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptx
 
Presentación de elementos de afilado con esmeril
Presentación de elementos de afilado con esmerilPresentación de elementos de afilado con esmeril
Presentación de elementos de afilado con esmeril
 

TDD: ¿Cómo escribir código testeable?

  • 1. TDD: Cómo escribir código testeable.
  • 3. ¿Por qué no los hacemos?
  • 4. Razones Válidas ¡No se! Código antiguo UI No hacer pruebas Inválidas El diseño es malo De eso se encarga QA No coge los bugs Demasiadas interfaces Es lento Aburido…. Es dificil de cambiar
  • 5. Hacer tests es una habilidad
  • 6. Entonces… ¿Cómo se escribe código difícil de probar?
  • 7. ¿Por qué? Construcción de objetos Trabajo en el constructor Estados globales Violaciones de la Ley de Deméter
  • 8. Localización del “new” Estímulo API de Pruebas Clase bajo prueba Verificaciones
  • 9. Localización del “new” Otra clase Estímulo Otra clase API de Pruebas Clase bajo prueba Verificaciones Otra clase Instanciado dentro de la clase Pasado por referencias Estados globales
  • 10. Localización del “new” Otra clase Otra clase Otra clase Otra clase Estímulo Otra clase API de Pruebas Clase bajo prueba Otra clase Verificaciones Otra clase
  • 11. Localización del “new” Otra clase Otra clase Otra clase Otra clase Estímulo Otra clase API de Pruebas Clase bajo prueba Costura Otra clase Verificaciones Otra clase
  • 12. Localización del “new” Clase Falsa Estímulo Clase Falsa API de Pruebas Clase bajo prueba Costura Verificaciones Clase Falsa
  • 13. Localización del “new” Lógica de Negocio Construcción del Grafo de Objetos y Búsqueda
  • 14. Localización del “new” Lógica de Negocio Construcción del Grafo de Objetos y Búsqueda
  • 15. Localización del “new” Clase Falsa Estímulo Clase Falsa API de Pruebas Clase bajo prueba Verificaciones Clase Falsa Instanciado dentro de la clase Pasado por referencias Estados globales
  • 17. House classHouse { Kitchenkitchen = new Kitchen(); Bedroombedroom; publicHouse() { this.bedroom = new Bedroom(); } }
  • 18. House Test classHouseTests { @Test publicvoidimpossibleTestOnIsolation() { // Can’treplaceanything!!! } }
  • 19. Análisis Fácil de instanciar pero… No se puede remplazar nada. Puede ser costoso computacionalmente El diseño está acoplado. Cerrado para extensión.
  • 20. House (Refactoizado) classHouse { Kitchenkitchen; Bedroombedroom; @Inject publicHouse(Kitchenkitchen, Bedroombr) { this.bedroom = br; this.kitchen = kitchen; } }
  • 21. House Test (Refactorizado) classHouseTests { @Test publicvoideasierToTestOnIsolation() { DummyKitchendk = new DummyKitchen(); DummyBedroomdb = new DummyBedroom(); House h = new House(dk,db); // … } }
  • 23. Gardener class Garden { Gardenerjoe; public Garden(Gardenerjoe) { joe.setWorkHours(new TwelveHours()); joe.setBoots(new ExpensiveBoots()); this.joe = joe; } }
  • 24. Análisis Mejor pero… No se pueden remplazar las botas o el horario. La prueba puede tardar (horario de 12h). Necesita el jardinero pero se encarga de configurarlo.
  • 25. Gardener (Refactored) class Garden { Gardenerjoe; @Inject public Garden(Gardenerjoe) { this.joe = joe; } } classGardenerProvider { @Provides GardenergetGardener(ExpensiveBootsboots, TwelveHoursschedule) { Gardenerjoe = new Gardener(); joe.setWorkHours(schedule); joe.setBoots(boots); returnjoe; } }
  • 26. ¿Por qué? Construcción de objetos Trabajo en el constructor Estados globales Violaciones de la Ley de Deméter
  • 27. Costo de la construcción Para testear, primero hay que instanciar pero… El trabajo dentro del constructor no tiene “costuras” No se puede sobre escribir. La prueba tiene que saber navegar lo que haya dentro
  • 29. Super Car class Car { Engineengine; public Car(Filefile) { String m = readModelFromCfg(file); engine = new EngineFactory().create(m); } }
  • 30. Super Car Test classCarTest { @Test publicvoidhardToSetupTest() { Filefile = new File(“custom.conf”); Car car = new Car(file); //Asserts... } }
  • 31. Análisis Pasamos un File cuando lo que se necesita es un Engine. Toda prueba que necesite Car requiere eta parafernaria. Accede al sistema de ficheros Lento. No es una prueba unitaria realmente.
  • 32. Super Car (Refactorizado) class Car { Engineengine; @Inject public Car(Engineengine) { this.engine = engine; } }
  • 33. Super Car (Provider) classCarEngineProvider { @Provides EnginegetEngine(EngineFactoryfactory, @EngineModelStringmodel) { returnfactory.create(model); } }
  • 34. Super Car Test (Refactorizado) classCarTest { @Test publicvoideasyToSetupTest() { Engineengine = new FakeEngine(); Car car = new Car(engine); //Asserts... } }
  • 35. ¿Por qué? Construcción de objetos Trabajo en el constructor Estados globales Violaciones de la Ley de Deméter
  • 37. Locura Definición: Repetir una misma acción una y otra vez y esperar obtener un resultado diferente. Albert Einstein
  • 38. O mejor dicho… Estados Globales class X { public X() { } publicintdoSomething() { //… Something… } }
  • 39. Estados Globales int a = new X().doSomething(); int b = new X().doSomething();
  • 40. Estados Globales ¿ a == b ó a != b ?
  • 41. Estados Globales X x1 = new X(); Y Q X Z
  • 42. Estados Globales X x1 = new X(); X x2 = new X(); Y Q X Z Y Q X Z
  • 43. Estados Globales X x1 = new X(); x1.doSomething(); A == B ó A != B X x2 = new X(); x2.doSomething(); Y Q X Z GS Y Q X Z
  • 44. Consecuencias Múltiples ejecuciones Resultados inesperados Orden importa No se pueden ejecutar en paralelo Localización del estado desacotado.
  • 45. Estados Globales Ocultos System.currentTime() new Date() Math.random()
  • 46. Consecuencias La API miente: A cerca de lo que necesita Hace cosas que dan miedo detrás de la fachada
  • 48. CreditCard @Test publicvoidcreditCardChargeTest() { CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); }
  • 49. CreditCard @Test publicvoidcreditCardChargeTest() { CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); } java.lang.NullPointerException at talk2.CreditCard.charge(CreditCard.java:48)
  • 50. CreditCard @Test publicvoidcreditCardChargeTest() { CreditCardProcessor.init(…); CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); }
  • 51. CreditCard @Test publicvoidcreditCardChargeTest() { CreditCardProcessor.init(…); CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); } java.lang.NullPointerException at talk2.CreditCardProcessor.init(CreditCardProcessor.java:134)
  • 52. CreditCard @Test publicvoidcreditCardChargeTest() { OfflineQueue.start(); CreditCardProcessor.init(…); CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); }
  • 53. CreditCard @Test publicvoidcreditCardChargeTest() { OfflineQueue.start(); CreditCardProcessor.init(…); CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); } java.lang.NullPointerException at talk2.OffileQueue.start (OfflineQueue.java:203)
  • 54. CreditCard @Test publicvoidcreditCardChargeTest() { Database.connect(…); OfflineQueue.start(); CreditCardProcessor.init(…); CreditCardcc = new CreditCard(“1234567890”); cc.charge(200); }
  • 55. CreditCard ¿Se ve un patrón?
  • 56. CreditCard Miente sobre sus dependencias. El orden de las inicializaciones no es explicito.
  • 58. CreditCard (Refactorizado) @Test publicvoidcreditCardChargeTest() { Databasedb = Database(“connectionStr”); OfflineQueuequeue = new OfflineQueue(db); CreditCardProcessorccProcessor = new CreditCardProcessor(queue); CreditCardcc = new CreditCard(“1234567890”, ccProcesor); cc.charge(200); }
  • 60. CreditCard Pero… ¿Y si termino con 20 parámetros? Es porque los tenias… solo que…
  • 61.
  • 62. Accounting 101 classAccountView { Useruser; publicAccountView() { user = RPCClient.getInstance().getUser(); } }
  • 63. Análisis Uso de Estados Globales Incorpora las dependencias del “singleton” Miente a cerca de las dependencias.
  • 64. Accounting 101 classAccountView { Useruser; publicAccountView(Useruser) { user = user; } }
  • 65. ¿Por qué? Construcción de objetos Trabajo en el constructor Estados globales Violaciones de la Ley de Deméter
  • 66.
  • 67. La ley de Deméter Cada unidad debería tener conocimiento limitado sobre otras unidades: solo unidades “relacionadas de cerca” a la unidad actual. Cada unidad debe de hablar solamente con sus amigos; No hablar con extraños. Habla solamente con tus amigos inmediatos.
  • 68. ServiceLocator Aka. Context, aka. Registry… etc. Mejor que un singleton Al menos el problema está en un solo lugar. Es testeable… pero no muy bonito. Esconde las dependencias reales. Las dependencias hacen el código poco reusable.
  • 69. ServiceLocator ClassHouse { //… publicHouse(Locatorlocator) { //… Qué tengo que mockear??? } }
  • 70. House ClassHouse { //… Windowwindow; Doordoor; Roofroof; publicHouse(Locatorlocator) { this.window = locator.getWindow(); this.door = locator.getDoor(); this.roof = locator.getRoof(); } }
  • 71. House (Refactorizado) classHouse { //… Windowwindow; Doordoor; Roofroof; publicHouse(Window w, Door d, Roof, r) { this.window = w; this.door = d; this.roof = r; } }
  • 72. ServiceLocator ¿Qué otro problema tiene? Mezcla responsabilidades. Buscar y encontrar. Creación Se necesita tener una interface para testear Si dependes de ServiceLocator, dependes de todo lo demás.
  • 73. Making a Mockery… classLoginPage { RPCClientclient; HttpRequestrequest; publicLoginPage(RPCClientclient, HttpRequestrequest) { this.client = client; this.request = request; } publicbooleanlogin() { String cookie = request.getCookie(); returnclient.getAuthenticator().authenticate(cookie); } }
  • 74. Análisis Para testear se hace complicado Las dependencias no son las declaradas. Crear rpcclient, entrenarlo para devolver un authenticator, crear un authenticator… Etc.
  • 75. Making a Mockery… classLoginPage { Authenticatorauthenticator; String cookie; publicLoginPage(Authenticatorauth, @Cookie String cookie) { this.cookie= cookie; this.authenticator = auth; } publicbooleanlogin() { returnauthenticator.authenticate(cookie); } }
  • 76. Making a Mockery Cosas a tener en cuenta. Tiempo de vida de los objetos que se pasan. Ej. Cookie puede ser distinto para cada vez