<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es"><title>Chemaclass - refactoring</title><subtitle>Tech Lead compartiendo ideas prácticas sobre artesanía del software, TDD, liderazgo, Bitcoin e IA. Artículos, resúmenes de libros y charlas.</subtitle><link rel="self" type="application/atom+xml" href="https://chemaclass.com/es/tags/refactoring/atom.xml"/><link rel="alternate" type="text/html" href="https://chemaclass.com"/><generator uri="https://www.getzola.org/">Zola</generator><updated>2022-07-11T00:00:00+00:00</updated><id>https://chemaclass.com/es/tags/refactoring/atom.xml</id><entry xml:lang="es"><title>Artesanía Limpia</title><subtitle>Disciplinas, Estándares y Ética</subtitle><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="xp" scheme="https://chemaclass.com/tags/xp/" label="Xp"/><published>2022-07-11T00:00:00+00:00</published><updated>2022-07-11T00:00:00+00:00</updated><author><name>
Robert C. Martin</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/readings/clean-craftsmanship/"/><id>https://chemaclass.com/es/readings/clean-craftsmanship/</id><summary type="html">Disciplinas, estándares y ética del desarrollo de software profesional.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>
&lt;p>El libro tiene tres partes: disciplinas, estándares y ética.&lt;/p>
&lt;p>La primera es la más técnica. Te guía con ejemplos de TDD y muestra cómo el testing te ayuda a diseñar tu código.&lt;/p>
&lt;p>La segunda trata sobre productividad, calidad y coraje.&lt;/p>
&lt;p>La tercera explica cómo hemos llegado hasta aquí como profesionales del software y nuestra responsabilidad ética: no hacer daño, integridad y trabajo en equipo.&lt;/p>
&lt;hr />
&lt;p>Una de mis partes favoritas del libro:&lt;/p>
&lt;blockquote>
&lt;p>Nuestra industria es dinámica y cambia constantemente. Hay que aprender de forma continua y agresiva.&lt;/p>
&lt;p>¿Cómo y cuándo aprendes? Si tu empresa te da tiempo para ello, aprovéchalo al máximo. Si no, tendrás que hacerlo por tu cuenta.&lt;/p>
&lt;p>Prepárate para dedicar varias horas al mes. Reserva ese tiempo.&lt;/p>
&lt;p>Sí, ya sé: familia, facturas, viajes, la vida. Pero también tienes una profesión. Y las profesiones requieren cuidado y mantenimiento. Aprendamos de forma continua y agresiva.&lt;/p>
&lt;p>&lt;code>Capítulo 11. Coraje - Aprendizaje Agresivo Continuo&lt;/code>&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;h2 id="indice">Índice
&lt;a class="heading-anchor" href="#indice" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="parte-i-las-disciplinas">Parte I: Las Disciplinas
&lt;a class="heading-anchor" href="#parte-i-las-disciplinas" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="capitulo-1-artesania">Capítulo 1. Artesanía
&lt;a class="heading-anchor" href="#capitulo-1-artesania" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Extreme Programming&lt;/li>
&lt;li>Test-Driven Development&lt;/li>
&lt;li>Refactoring&lt;/li>
&lt;li>Diseño Simple&lt;/li>
&lt;li>Programación Colaborativa&lt;/li>
&lt;li>Tests de Aceptación&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-2-test-driven-development">Capítulo 2. Test-Driven Development
&lt;a class="heading-anchor" href="#capitulo-2-test-driven-development" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Visión General&lt;/li>
&lt;li>Lo Básico&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-3-tdd-avanzado">Capítulo 3. TDD Avanzado
&lt;a class="heading-anchor" href="#capitulo-3-tdd-avanzado" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Quedarse Atascado&lt;/li>
&lt;li>Arrange, Act, Assert&lt;/li>
&lt;li>Test Doubles&lt;/li>
&lt;li>Arquitectura&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-4-diseno-de-tests">Capítulo 4. Diseño de Tests
&lt;a class="heading-anchor" href="#capitulo-4-diseno-de-tests" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Testeando Bases de Datos&lt;/li>
&lt;li>Testeando GUIs&lt;/li>
&lt;li>Patrones de Test&lt;/li>
&lt;li>Subclase Específica de Test&lt;/li>
&lt;li>Humble Object&lt;/li>
&lt;li>Diseño de Tests&lt;/li>
&lt;li>Rompiendo la Correspondencia&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-5-refactoring">Capítulo 5. Refactoring
&lt;a class="heading-anchor" href="#capitulo-5-refactoring" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>¿Qué es Refactoring?&lt;/li>
&lt;li>El Kit Básico de Herramientas&lt;/li>
&lt;li>Extract Method&lt;/li>
&lt;li>Las Disciplinas&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-6-diseno-simple">Capítulo 6. Diseño Simple
&lt;a class="heading-anchor" href="#capitulo-6-diseno-simple" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>YAGNI&lt;/li>
&lt;li>Cubierto por Tests&lt;/li>
&lt;li>Cobertura&lt;/li>
&lt;li>¿Diseño?&lt;/li>
&lt;li>Maximizar Expresión&lt;/li>
&lt;li>La Abstracción Subyacente&lt;/li>
&lt;li>Minimizar Duplicación&lt;/li>
&lt;li>Minimizar Tamaño&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-7-programacion-colaborativa">Capítulo 7. Programación Colaborativa
&lt;a class="heading-anchor" href="#capitulo-7-programacion-colaborativa" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;h4 id="capitulo-8-tests-de-aceptacion">Capítulo 8. Tests de Aceptación
&lt;a class="heading-anchor" href="#capitulo-8-tests-de-aceptacion" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>La Disciplina&lt;/li>
&lt;li>El Build Continuo&lt;/li>
&lt;/ul>
&lt;h3 id="parte-ii-los-estandares">Parte II: Los Estándares
&lt;a class="heading-anchor" href="#parte-ii-los-estandares" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="capitulo-9-productividad">Capítulo 9. Productividad
&lt;a class="heading-anchor" href="#capitulo-9-productividad" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Nunca Enviaremos M***da&lt;/li>
&lt;li>Adaptabilidad Económica&lt;/li>
&lt;li>Siempre Estaremos Listos&lt;/li>
&lt;li>Productividad Estable&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-10-calidad">Capítulo 10. Calidad
&lt;a class="heading-anchor" href="#capitulo-10-calidad" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Mejora Continua&lt;/li>
&lt;li>Competencia Sin Miedo&lt;/li>
&lt;li>Calidad Extrema&lt;/li>
&lt;li>No Volcaremos en QA&lt;/li>
&lt;li>QA No Encontrará Nada&lt;/li>
&lt;li>Automatización de Tests&lt;/li>
&lt;li>Testing Automatizado e Interfaces de Usuario&lt;/li>
&lt;li>Testeando la Interfaz de Usuario&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-11-coraje">Capítulo 11. Coraje
&lt;a class="heading-anchor" href="#capitulo-11-coraje" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Nos Cubrimos Mutuamente&lt;/li>
&lt;li>Estimaciones Honestas&lt;/li>
&lt;li>Debes Decir NO&lt;/li>
&lt;li>Aprendizaje Agresivo Continuo&lt;/li>
&lt;li>Mentoría&lt;/li>
&lt;/ul>
&lt;h3 id="parte-iii-la-etica">Parte III: La Ética
&lt;a class="heading-anchor" href="#parte-iii-la-etica" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>El Primer Programador&lt;/li>
&lt;li>Setenta y Cinco Años&lt;/li>
&lt;li>Nerds y Salvadores&lt;/li>
&lt;li>Modelos a Seguir y Villanos&lt;/li>
&lt;li>Gobernamos el Mundo&lt;/li>
&lt;li>Catástrofes&lt;/li>
&lt;li>El Juramento&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-12-dano">Capítulo 12. Daño
&lt;a class="heading-anchor" href="#capitulo-12-dano" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Primero, No Hacer Daño&lt;/li>
&lt;li>Mejor Trabajo&lt;/li>
&lt;li>Prueba Repetible&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-13-integridad">Capítulo 13. Integridad
&lt;a class="heading-anchor" href="#capitulo-13-integridad" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Ciclos Pequeños&lt;/li>
&lt;li>Mejora Implacable&lt;/li>
&lt;li>Mantener Alta Productividad&lt;/li>
&lt;/ul>
&lt;h4 id="capitulo-14-trabajo-en-equipo">Capítulo 14. Trabajo en Equipo
&lt;a class="heading-anchor" href="#capitulo-14-trabajo-en-equipo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Trabajar como Equipo&lt;/li>
&lt;li>Estimar Honesta y Justamente&lt;/li>
&lt;li>Respeto&lt;/li>
&lt;li>Nunca Dejes de Aprender&lt;/li>
&lt;/ul>
&lt;hr />
&lt;p>Charla de Uncle Bob donde cubre la mayoría de los temas del libro.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/sPXk11hrWTM"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="plain">&lt;span class="giallo-l">&lt;span>Escucha sobre:&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Cita e Intro - [00:00:00]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Trayectoria Profesional - [00:07:29]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Clean Craftsmanship - [00:10:53]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Programador como Profesión - [00:15:31]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Artesanía - [00:18:45]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Disciplinas - [00:22:45]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Disciplinas: Test-Driven Development - [00:28:49]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Disciplinas: Refactoring - [00:34:31]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Cobertura de Código - [00:39:02]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Estándar: Nunca Enviar M***da - [00:42:35]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Estándar: Siempre Estar Listo - [00:47:15]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Ética: No Hacer Daño - [00:50:00]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* Ética: Estimar Honestamente - [00:53:56]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>* 2 Sabiduría de Tech Lead - [00:57:50]&lt;/span>&lt;/span>&lt;/code>&lt;/pre></content></entry><entry xml:lang="es"><title>London vs Chicago</title><subtitle>Es una integración, no una elección</subtitle><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2021-11-20T00:00:00+00:00</published><updated>2021-11-20T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/london-vs-chicago/"/><id>https://chemaclass.com/es/blog/london-vs-chicago/</id><summary type="html">Hay dos escuelas conocidas en TDD: la escuela mockista (también conocida como Outside-in) y la escuela clasicista (también conocida como Inside-out).</summary><content type="html">&lt;p>Hay dos escuelas conocidas en TDD: la escuela mockista (también conocida como Outside-in) y la escuela clasicista (también conocida como Inside-out).&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h3 id="por-que-london-y-chicago">¿Por qué London y Chicago?
&lt;a class="heading-anchor" href="#por-que-london-y-chicago" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Dos empresas, una de Londres y otra de Chicago, afirmaban hacer TDD pero con enfoques diferentes. La de Londres construía software de afuera hacia adentro; la de Chicago, de adentro hacia afuera. Veamos cada una.&lt;/p>
&lt;h2 id="outside-in-escuela-de-londres">Outside-in: Escuela de Londres
&lt;a class="heading-anchor" href="#outside-in-escuela-de-londres" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Un enfoque guiado por comportamiento para TDD. Empiezas desde el exterior de la aplicación y vas hacia adentro, bajando a capas inferiores. Por ejemplo, desde la API/Controladores hacia las capas de aplicación o dominio.&lt;/p>
&lt;h3 id="pros">PROS
&lt;a class="heading-anchor" href="#pros" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Enfocado en Comportamiento&lt;/strong>: requiere muchos dobles de test porque testeas abstracciones que aún no existen (creas lógica de alto nivel primero). No escribirás código muerto, pero es fácil crear tests muy acoplados a la lógica, lo que dificulta el refactoring.&lt;/li>
&lt;li>&lt;strong>Separación Comando-Consulta&lt;/strong>: es una disciplina para gestionar efectos secundarios. O realizas una acción (comando) o pides un valor (consulta).&lt;/li>
&lt;/ul>
&lt;h3 id="contras">CONTRAS
&lt;a class="heading-anchor" href="#contras" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Tests Frágiles&lt;/strong>: tiende a crear tests que se rompen fácilmente porque suelen estar muy acoplados al código de producción.&lt;/li>
&lt;li>&lt;strong>Refactoring Difícil&lt;/strong>: por la misma razón, tener tests acoplados hace que el refactoring continuo sea lento y complicado.&lt;/li>
&lt;/ul>
&lt;h2 id="inside-out-escuela-de-chicago">Inside-out: Escuela de Chicago
&lt;a class="heading-anchor" href="#inside-out-escuela-de-chicago" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Un enfoque informal, exploratorio, basado en estado. Empiezas desde el interior de la aplicación (normalmente el dominio) y vas hacia afuera, hacia las APIs.&lt;/p>
&lt;h3 id="pros-1">PROS
&lt;a class="heading-anchor" href="#pros-1" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Red de Seguridad Fuerte&lt;/strong>: produce tests desacoplados de la implementación. Puedes cambiar el software sin miedo a romperlo, ideal para el refactoring continuo.&lt;/li>
&lt;li>&lt;strong>Alta Cohesión&lt;/strong>: a medida que los tests se vuelven más generales, el código de producción se vuelve más específico. Alta cohesión lleva a bajo acoplamiento, lo que mejora extensibilidad, mantenibilidad y testeabilidad.&lt;/li>
&lt;li>&lt;strong>Minimiza Dobles de Test&lt;/strong>: construir de adentro hacia afuera requiere menos dobles porque construyes sobre tests previamente escritos. Esto ayuda a tener tests menos frágiles.&lt;/li>
&lt;/ul>
&lt;h3 id="contras-1">CONTRAS
&lt;a class="heading-anchor" href="#contras-1" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>YAGNI&lt;/strong>: a menudo sobre-diseña soluciones, con código que realmente no se necesita (¡o ni siquiera se usa!) al final.&lt;/li>
&lt;/ul>
&lt;h2 id="londres-y-chicago-funcionan-mejor-juntas">Londres y Chicago funcionan mejor juntas
&lt;a class="heading-anchor" href="#londres-y-chicago-funcionan-mejor-juntas" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>No se trata de elegir uno u otro. Se trata de entender tu contexto y optimizar las cualidades que lo necesitan. London y Chicago tienen sus pros y contras. El mejor enfoque para TDD es integrar ambas escuelas.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/rbSDGr-_UwY"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;hr />
&lt;h3 id="referencias">Referencias
&lt;a class="heading-anchor" href="#referencias" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="/es/blog/test-driven-development/">Test-Driven (Development)&lt;/a>&lt;/li>
&lt;li>&lt;a href="/es/blog/tdd-vs-bdd/">TDD vs BDD&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://gist.github.com/xpepper/2e3519d2cb8568a0b13739d9ae497f21">Notes about “London vs Chicago TDD styles”&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="es"><title>Test-Driven (Development)</title><subtitle>¿Qué tiene de desafiante?</subtitle><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2021-08-01T00:00:00+00:00</published><updated>2021-08-01T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/test-driven-development/"/><id>https://chemaclass.com/es/blog/test-driven-development/</id><summary type="html">TDD es una práctica de diseño, no solo una técnica de testing. Escribir tests primero cambia cómo piensas sobre el código y su estructura.</summary><content type="html">&lt;p>La complejidad aquí no está en escribir tests en sí, sino en los hábitos que tenemos que cambiar para crear software que sea fácil de testear.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="la-raiz-del-problema">La raíz del problema
&lt;a class="heading-anchor" href="#la-raiz-del-problema" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Sin experiencia sólida en testing, los desarrolladores lo pasan mal al intentar aplicar tests en su trabajo diario. No es solo por la complejidad del tema, sino &lt;strong>porque están acostumbrados a escribir código difícil de testear.&lt;/strong>&lt;/p>
&lt;p>Escribir tests para software que ya funciona (sobre todo cuando se hizo sin pensar en testing) se siente aburrido y casi inútil. Viene acompañado de falta de motivación, culpando al sujeto equivocado: “los tests me hacen ir más lento”.&lt;/p>
&lt;blockquote>
&lt;p>En un contexto de dominio, si una pieza de lógica de software es difícil de testear, el problema no es el test, sino el código que no estaba bien escrito.&lt;/p>
&lt;/blockquote>
&lt;p>Ya hay cientos de tutoriales, libros y documentación sobre testing. Aquí comparto mi experiencia y cómo aplico esta filosofía en mi trabajo diario.&lt;/p>
&lt;h3 id="test-driven-se-basa-en-esta-simple-regla">Test-Driven se basa en esta simple regla
&lt;a class="heading-anchor" href="#test-driven-se-basa-en-esta-simple-regla" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>En lugar de: diseñar código -&amp;gt; desarrollar código -&amp;gt; escribir tests.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2021-08-01/non-tdd-style.png" alt="non-tdd-style" />&lt;/p>
&lt;ul>
&lt;li>Se trata de: escribir test automatizado que falla -&amp;gt; ejecutar test que falla -&amp;gt; desarrollar código para hacer pasar el test -&amp;gt; ejecutar test -&amp;gt; repetir.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2021-08-01/tdd-style.png" alt="tdd-style" />&lt;/p>
&lt;p>La idea de guiar tu código con tests depende del nivel de abstracción de lo que estés escribiendo. No quieres acoplar mal los tests con el código testeado. Quieres testear el comportamiento de tu lógica.&lt;/p>
&lt;p>TDD se basa en un bucle de pequeños pasos que te ayuda a encontrar &lt;strong>patrones&lt;/strong> y guiar tu diseño de software con &lt;strong>refactorizaciones constantes&lt;/strong>. Es la mejor opción si quieres asegurar el comportamiento esperado de todos los caminos posibles de tu lógica.&lt;/p>
&lt;p>Lo bonito es que no necesitas conocer el algoritmo completo desde el principio. Vas &lt;strong>descubriendo&lt;/strong> cómo debería ser tu lógica expresando la implementación deseada, paso a paso, en tests automatizados.&lt;/p>
&lt;p>Escribir tests al mismo tiempo que escribes el código te &lt;strong>obliga a escribir mejor software&lt;/strong>. Porque quieres que sea fácil de testear, y eso lleva a mayor calidad.&lt;/p>
&lt;blockquote>
&lt;p>Ya escribí otro post sobre la relación entre &lt;strong>calidad y testing&lt;/strong> del software: &lt;a href="/es/blog/the-art-of-testing/">El Arte del Testing: donde el diseño se encuentra con la calidad&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;h2 id="mejora-tus-habilidades-de-test-driven">Mejora tus habilidades de Test-Driven
&lt;a class="heading-anchor" href="#mejora-tus-habilidades-de-test-driven" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>&lt;img src="/images/blog/2021-08-01/tdd-style-with-git.png" alt="tdd-style" />&lt;/p>
&lt;p>La mejor manera de aprender Test-Driven es haciendo katas de software. Pruébalas solo y con otros. Ambas son igualmente importantes.&lt;/p>
&lt;ul>
&lt;li>Solo: para desafiar tu yo interior sin ninguna distracción excepto tú mismo.&lt;/li>
&lt;li>Con otros: el pair-programming es esencial en nuestro trabajo. Las katas son las mejores herramientas para entrenar nuestras habilidades de comunicación y aprender juntos unos de otros.&lt;/li>
&lt;/ul>
&lt;h3 id="que-es-una-code-kata">¿Qué es una Code Kata?
&lt;a class="heading-anchor" href="#que-es-una-code-kata" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Los desarrolladores no practicamos lo suficiente. La mayor parte de nuestro aprendizaje ocurre en el trabajo, y ahí es donde cometemos la mayoría de nuestros errores.&lt;/p>
&lt;p>Otras profesiones creativas sí practican: los músicos tocan piezas técnicas, los poetas reescriben obras constantemente. En karate, un estudiante dedica la mayor parte del tiempo a aprender y perfeccionar movimientos básicos. Esas son las katas.&lt;/p>
&lt;h3 id="cual-es-el-objetivo-de-una-kata-que-deberiamos-tener-al-final">¿Cuál es el objetivo de una kata? ¿Qué deberíamos tener al final?
&lt;a class="heading-anchor" href="#cual-es-el-objetivo-de-una-kata-que-deberiamos-tener-al-final" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Las katas existen para que los desarrolladores obtengamos los mismos beneficios que practicar en otras profesiones. Son ejercicios simples y artificiales que permiten experimentar y aprender sin la presión de producción.&lt;/p>
&lt;blockquote>
&lt;p>No hay respuestas correctas o incorrectas en ninguna kata de software: el beneficio viene del proceso, no del resultado.&lt;/p>
&lt;/blockquote>
&lt;h3 id="consejos">Consejos
&lt;a class="heading-anchor" href="#consejos" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Cuando resuelvas una kata, vuelve a intentarla en unas semanas o meses.&lt;/li>
&lt;li>Explora nuevas soluciones. Sé creativo y no te apresures.&lt;/li>
&lt;li>En grupo, no es una competición para ver quién logra más.&lt;/li>
&lt;li>El foco debe estar en el proceso, nunca en el resultado.&lt;/li>
&lt;li>El verdadero valor de cualquier kata son los aprendizajes que obtendréis después de hablar y compartir experiencias.&lt;/li>
&lt;/ul>
&lt;p>Puedes encontrar muchas katas en Internet. Por ejemplo:&lt;/p>
&lt;ul>
&lt;li>&lt;a rel="external" href="http://codekata.com">http://codekata.com&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://codingdojo.org/kata">https://codingdojo.org/kata&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/gamontal/awesome-katas">https://github.com/gamontal/awesome-katas&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr />
&lt;h3 id="tdd-es-mas-un-flujo-de-trabajo-que-un-diseno">TDD es más un flujo de trabajo que un diseño
&lt;a class="heading-anchor" href="#tdd-es-mas-un-flujo-de-trabajo-que-un-diseno" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;blockquote>
&lt;p>“TDD es una herramienta de diseño.” Eso es lo que Sandro dijo durante años. Pero ya no. Tras trabajar con diferentes equipos y organizaciones, y observar cómo trabaja él mismo, Sandro cambió de opinión sobre el rol de TDD en el diseño de software.&lt;/p>
&lt;/blockquote>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/KyFVA4Spcgg"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;p>TDD en pocas palabras; se trata del ritmo.&lt;/p>
&lt;ol>
&lt;li>Especifica lo que quieres.&lt;/li>
&lt;li>Hazlo funcionar.&lt;/li>
&lt;li>Hazlo mejor.&lt;/li>
&lt;/ol>
&lt;hr />
&lt;h2 id="kent-beck">Kent Beck
&lt;a class="heading-anchor" href="#kent-beck" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;blockquote class="twitter-tweet">&lt;p lang="en" dir="ltr">1. Change the code as usual&lt;br>2. Write a test that only passes after the change&lt;br>3. Revert to before 1&lt;br>4. Type the test again (copy/paste is cheating &amp;amp; invalidates the warranty of the exercise)&lt;br>5. Make it compile by changing the code&lt;br>6. See it fail&lt;br>7. Change the code to make it pass&lt;/p>&amp;mdash; Kent Beck 🌻 (@KentBeck) &lt;a href="https://twitter.com/KentBeck/status/1421257650113634304?ref_src=twsrc%5Etfw">July 30, 2021&lt;/a>&lt;/blockquote> &lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8">&lt;/script>
&lt;hr />
&lt;p>Imágenes originales de &lt;a rel="external" href="https://x.com/evrtrabajo">Emmanuel Valverde Ramos&lt;/a>.&lt;/p></content></entry><entry xml:lang="es"><title>Nunca Uses array_merge en un Bucle</title><subtitle>El operador spread al rescate</subtitle><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2020-11-10T00:00:00+00:00</published><updated>2020-11-10T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/array-merge-in-loop/"/><id>https://chemaclass.com/es/blog/array-merge-in-loop/</id><summary type="html">Usar array_merge dentro de un bucle mata el rendimiento. El operador spread te ayudará a mejorar esto aplanando el array.</summary><content type="html">&lt;p>Usar array_merge dentro de un bucle mata el rendimiento.
El operador spread te ayudará a mejorar esto aplanando el array.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="aplanando-un-array-de-un-nivel">Aplanando un array de un nivel
&lt;a class="heading-anchor" href="#aplanando-un-array-de-un-nivel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>He visto a gente usar array_merge dentro de un bucle así:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">foreach&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> as&lt;/span>&lt;span> $&lt;/span>&lt;span>list&lt;/span>&lt;span>)&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> $&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span>,&lt;/span>&lt;span> $&lt;/span>&lt;span>list&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> $merged === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Esto es mala práctica porque destroza el rendimiento de memoria.
Mejor usa el operador spread (disponible desde PHP 5.6):&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h2 id="desempaquetando-un-array-asociativo">Desempaquetando un array asociativo
&lt;a class="heading-anchor" href="#desempaquetando-un-array-asociativo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>¿Y si tuvieras un array asociativo como este?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-1&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-3&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">5&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>En ese caso, necesitarás desempaquetar sus valores:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">array_values&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> === [1, 2, 3, 4, 5, 6];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>En programación funcional, esto se conoce como aplanar una lista.
Sin bucles ni problemas de rendimiento.&lt;/p>
&lt;h2 id="aplanando-un-array-multinivel">Aplanando un array multinivel
&lt;a class="heading-anchor" href="#aplanando-un-array-multinivel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>¿Y si quisieras aplanar un array multinivel como este?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">1&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 2&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">3&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 4&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 5&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span>[&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>[&lt;/span>&lt;span>[&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">6&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 7&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 8&lt;/span>&lt;span>,&lt;/span>&lt;span> [&lt;/span>&lt;span>]&lt;/span>&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>¿O como este, incluso con clave-valores?&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-1&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 1&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">2&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 3&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-3&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">4&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 5&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 6&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key-4&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">7&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> 8&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>]&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Para estos casos, puedes usar la librería estándar de PHP:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>merged&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> iterator_to_array&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> RecursiveIteratorIterator&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> RecursiveArrayIterator&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> $&lt;/span>&lt;span>use_keys&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> false&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">//&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> $merged === [1, 2, 3, 4, 5, 6, 7, 8];&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h2 id="que-enfoque-de-aplanado-usar">Qué enfoque de aplanado usar
&lt;a class="heading-anchor" href="#que-enfoque-de-aplanado-usar" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Normalmente, saber aplanar un array de dos niveles suele ser suficiente:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;lt;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">?&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">php&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>$&lt;/span>&lt;span>flattenList&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> array_merge&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">...&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">array_values&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>lists&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Para casos más complejos, la librería estándar de PHP te saca del apuro.&lt;/p>
&lt;hr />
&lt;h3 id="referencias">Referencias
&lt;a class="heading-anchor" href="#referencias" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://wiki.php.net/rfc/spread_operator_for_array">Spread_operator_for_array - Wikipedia&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://rosettacode.org/wiki/Flatten_a_list">Flatten_a_list - Rosettacode&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="es"><title>Testeando Código Legacy de Forma Efectiva</title><subtitle>Cómo escribir tests adecuados para código ya escrito</subtitle><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><published>2020-08-17T00:00:00+00:00</published><updated>2020-08-17T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/testing-effectively-legacy-code/"/><id>https://chemaclass.com/es/blog/testing-effectively-legacy-code/</id><summary type="html">Cómo escribir tests de caracterización para código legacy y refactorizar de forma segura sin romper el comportamiento existente.</summary><content type="html">&lt;p>Estos tests también se conocen como tests de caracterización.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;blockquote>
&lt;p>Un test de caracterización describe el comportamiento real de una pieza de software existente, y por lo tanto protege el
comportamiento existente del código legacy contra cambios no intencionados mediante testing automatizado. Este término fue acuñado por &lt;a href="/es/readings/working-effectively-with-legacy-code/">Michael Feathers&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;p>Permiten y proporcionan una red de seguridad para extender y refactorizar código que no tiene tests adecuados. Se puede
escribir un test que afirme que la salida del código legacy coincide con el resultado observado para las entradas dadas.&lt;/p>
&lt;h2 id="como-empezar">¿Cómo empezar?
&lt;a class="heading-anchor" href="#como-empezar" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Estos son mis aprendizajes un año después de
leer &lt;a href="/es/readings/working-effectively-with-legacy-code/">Working Effectively with Legacy Code&lt;/a> y aplicarlo a los
diferentes proyectos en los que he trabajado desde entonces.&lt;/p>
&lt;h3 id="1-que-quieres-testear">1. ¿Qué quieres testear?
&lt;a class="heading-anchor" href="#1-que-quieres-testear" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Averigua las aserciones. Crea un archivo de test para tu clase, y un método de test para la función que quieres testear.
Pista:&lt;/p>
&lt;ul>
&lt;li>Si tienes el siguiente método &lt;code>applySomeLogic(): ReturnType&lt;/code>,&lt;/li>
&lt;li>el test que podrías escribir es &lt;code>test_apply_some_logic(): void&lt;/code>.&lt;/li>
&lt;/ul>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogic&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> private&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> DependencyInterface&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> dependencyInterface&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> private&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> concrete&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> __construct&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> DependencyInterface dependencyInterface&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ConcreteDependency concrete&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">dependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> dependencyInterface&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">concrete&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> concrete&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span>Input input&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ReturnType&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> caja negra responsable de crear un ReturnType&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> basado en el Input dado&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> return&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> Quiero afirmar que &amp;quot;aplicando alguna lógica&amp;quot;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> de MyBusinessLogic con el Input dado&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> recibiré un ReturnType concreto con un&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> cierto valor como su propiedad. Algo como:&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="2-instancia-la-clase-concreta-final-que-quieres-testear">2. Instancia la clase concreta/final que quieres testear.
&lt;a class="heading-anchor" href="#2-instancia-la-clase-concreta-final-que-quieres-testear" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>No mockees tus clases concretas. Especialmente tu dominio de negocio. Mockea solo interfaces. De lo contrario, puedes estar ocultando
bugs sin querer (¡con tests verdes/pasando!). Trata tus &lt;a href="/es/blog/final-classes">clases de dominio de negocio como finales&lt;/a>.&lt;/p>
&lt;p>O mockea la interfaz o instancia una clase anónima si quieres crear un Stub:&lt;/p>
&lt;blockquote>
&lt;p>Los Stubs proporcionan respuestas a llamadas hechas durante el test, normalmente sin responder a nada fuera de lo programado para el test.&lt;/p>
&lt;/blockquote>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createMock&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">DependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">class&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> O&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> FakeDependency&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> //&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ...&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;blockquote>
&lt;p>Donde &lt;code>FakeDependency&lt;/code> es una implementación concreta de &lt;code>DependencyInterface&lt;/code> con “datos/implementación falsos” ya preparados que solo es útil para propósitos de testing.&lt;/p>
&lt;/blockquote>
&lt;h3 id="3-llama-al-metodo-de-esa-clase-proporcionando-la-entrada-deseada">3. Llama al método de esa clase proporcionando la entrada deseada.
&lt;a class="heading-anchor" href="#3-llama-al-metodo-de-esa-clase-proporcionando-la-entrada-deseada" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>La salida será determinada por el estado inicial de la clase de lógica de negocio que queremos testear MÁS los argumentos
de entrada que estamos usando.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Input&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="4-afirma-la-salida-con-el-valor-esperado">4. Afirma la salida con el valor esperado.
&lt;a class="heading-anchor" href="#4-afirma-la-salida-con-el-valor-esperado" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Del paso 1 necesitas saber qué quieres. Aplica la(s) aserción(es) ahora.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createMock&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">DependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">::&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">class&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Input&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">/*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> returnType&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="5-puede-que-quieras-afirmar-diferentes-valores-esperados">5. Puede que quieras afirmar diferentes valores esperados.
&lt;a class="heading-anchor" href="#5-puede-que-quieras-afirmar-diferentes-valores-esperados" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Puedes proporcionar fácilmente diferentes argumentos a tu lógica de negocio ya sea a través de la construcción de la lógica o diferentes
argumentos dados. Para hacerlo, usa la anotación @dataProvider. El método “dataProvider” debe ser público y devolver cualquier iterable.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);">final&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> class&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> MyBusinessLogicTest&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> extends&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> TestCase&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>{&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> /**&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> @dataProvider providerApplySomeLogic &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> test_apply_some_logic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> array concreteMapping&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> string argInput&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> string expectedValue&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> void&lt;/span>&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> MyBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createMock&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">DependencyInterface&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">class&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> ConcreteDependency&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">concreteMapping&lt;/span>&lt;span>)&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);"> /*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> )&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> new&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Input&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">argInput&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> /*&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> ... &lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);">*/&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);"> actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);"> assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span>$&lt;/span>&lt;span>expectedValue&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> public&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> function&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);"> providerApplySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">:&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> Generator&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> {&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> yield&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">concreteMapping&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">value&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">argInput&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">something&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expectedValue&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected-value-A&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#D73A49, #F97583);"> yield&lt;/span>&lt;span> [&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">concreteMapping&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span> [&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">key2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">value2&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>]&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">argInput&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">something-else&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expectedValue&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&amp;gt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">expected-value-B&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;span>,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> ]&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> }&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="por-ultimo-limpia-lo-que-hiciste">Por último: limpia lo que hiciste.
&lt;a class="heading-anchor" href="#por-ultimo-limpia-lo-que-hiciste" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Sí, limpia los tests. Merecen estar tan limpios como tu código de producción. De lo contrario, se pudrirán con el tiempo y
¡permanecerán sucios para tus compañeros y tu yo futuro!&lt;/p>
&lt;p>Por ejemplo, puedes aplicar el refactoring extract method para mover los detalles de implementación (de la creación de los
diferentes objetos) y mantener el mismo nivel de abstracción mientras lees el código del test.&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="php">&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createBusinessLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">concreteMapping&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> this&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">createInput&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">argInput&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);">actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> =&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> myBusinessLogic&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">applySomeLogic&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">input&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">assertEquals&lt;/span>&lt;span>(&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">expectedValue&lt;/span>&lt;span>,&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> actual&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">.&lt;/span>&lt;span style="color: light-dark(#6F42C1, #B392F0);">getProperty&lt;/span>&lt;span>(&lt;/span>&lt;span>)&lt;/span>&lt;span>)&lt;/span>&lt;span>;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Por supuesto, todo depende del contexto. ¿Realmente tiene sentido extraer a un método privado
createBusinessLogic() o incluso createInput()? Bueno, eso depende de ti. Depende del número de líneas y, lo más
importante, del nivel de abstracción que pertenece a ese contexto.&lt;/p>
&lt;blockquote>
&lt;p>Solo recuerda: mantén tus métodos pequeños.&lt;/p>
&lt;/blockquote>
&lt;p>Ahora puedes refactorizar el código de producción que cubriste con tests sin ese miedo a romperlo.&lt;/p>
&lt;hr />
&lt;h3 id="todo-junto">Todo junto
&lt;a class="heading-anchor" href="#todo-junto" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;script src="https://gist.github.com/Chemaclass&amp;#x2F;07704606fcb337dbb0881c94197c329e.js">&lt;/script>
&lt;script src="https://gist.github.com/Chemaclass&amp;#x2F;9f7f96242153b696b3f8da5c7fa80461.js">&lt;/script>
&lt;hr />
&lt;h2 id="el-codigo-legacy-es-codigo-sin-tests">El código legacy es código sin tests
&lt;a class="heading-anchor" href="#el-codigo-legacy-es-codigo-sin-tests" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>&lt;img src="/images/blog/2020-08-17/footer.jpg" alt="el código legacy es código sin tests" />&lt;/p>
&lt;p>Por supuesto, hay mucho más que aprender
sobre &lt;a href="/es/readings/working-effectively-with-legacy-code/">testing y trabajo con código legacy&lt;/a>. De hecho, especialmente cuando
tratamos con código legacy, encontrarás situaciones donde el código está acoplado de alguna manera que podrías querer mockear
tus clases concretas porque no hay interfaz (todavía) para ello.&lt;/p>
&lt;p>Este libro te presenta muchas técnicas sobre cuándo, por qué, dónde y cómo puedes aplicar estos cambios.&lt;/p>
&lt;blockquote>
&lt;p>Cuando trabajas con código necesitas &lt;strong>retroalimentación&lt;/strong>. La retroalimentación automatizada es la mejor. Por lo tanto, esto es lo primero que necesitas hacer: escribir los tests.&lt;/p>
&lt;/blockquote>
&lt;h3 id="primero-anade-tests-luego-haz-tus-cambios">Primero, añade tests, luego haz tus cambios.
&lt;a class="heading-anchor" href="#primero-anade-tests-luego-haz-tus-cambios" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="cambia-la-menor-cantidad-de-codigo-posible-para-poner-los-tests-en-su-lugar-con-la-receta">Cambia la menor cantidad de código posible para poner los tests en su lugar con la receta:
&lt;a class="heading-anchor" href="#cambia-la-menor-cantidad-de-codigo-posible-para-poner-los-tests-en-su-lugar-con-la-receta" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ol>
&lt;li>Identifica “puntos de cambio” para romper las dependencias de tu código.&lt;/li>
&lt;li>Rompe las dependencias.&lt;/li>
&lt;li>Escribe los tests.&lt;/li>
&lt;li>Haz tus cambios.&lt;/li>
&lt;li>Refactoriza.&lt;/li>
&lt;/ol>
&lt;hr />
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/wRtJRkRIa2s"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry><entry xml:lang="es"><title>Advanced Web Application Architecture</title><subtitle>La guía que lleva tus habilidades de código al siguiente nivel</subtitle><category term="architecture" scheme="https://chemaclass.com/tags/architecture/" label="Architecture"/><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2020-08-16T00:00:00+00:00</published><updated>2020-08-16T00:00:00+00:00</updated><author><name>
Matthias Noback</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/readings/advance-web-application-architecture/"/><id>https://chemaclass.com/es/readings/advance-web-application-architecture/</id><summary type="html">Cómo desacoplar tu aplicación del framework y la base de datos con PHP moderno y diseño modular</summary><content type="html">&lt;p>Este libro te ayuda a poner en forma tus aplicaciones web. Trae muchas técnicas para desacoplar tu código de la infraestructura (el framework, la base de datos, etc.).&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>La Parte 1 presenta patrones de diseño para separar código de negocio e infraestructura. La Parte 2 muestra cómo estos patrones encajan con conceptos arquitectónicos como capas, puertos y adaptadores (arquitectura Hexagonal). El libro cierra con estrategias de testing y decisiones de diseño.&lt;/p>
&lt;h3 id="lo-que-aprenderas">Lo que aprenderás
&lt;a class="heading-anchor" href="#lo-que-aprenderas" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Separar código mezclado en código de negocio e infraestructura usando patrones.&lt;/li>
&lt;li>Dividir tu código en capas con una distinción clara entre puertos y adaptadores.&lt;/li>
&lt;li>Testear aplicaciones desacopladas.&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>Compra el libro: &lt;a rel="external" href="https://leanpub.com/web-application-architecture">https://leanpub.com/web-application-architecture&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;h3 id="patrones-de-diseno-para-modernizar-codigo-legacy">Patrones de diseño para modernizar código legacy
&lt;a class="heading-anchor" href="#patrones-de-diseno-para-modernizar-codigo-legacy" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/WI1QY6OMglE"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry><entry xml:lang="es"><title>El Arte del Refactoring</title><subtitle>Cuándo, cómo y por qué</subtitle><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><published>2020-06-28T00:00:00+00:00</published><updated>2020-06-28T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/the-art-of-refactoring/"/><id>https://chemaclass.com/es/blog/the-art-of-refactoring/</id><summary type="html">Si ves algo, en el ámbito de tu tarea actual, que puede mejorarse fácilmente, mejóralo. Y si tienes alguna pregunta al respecto, pregunta.</summary><content type="html">&lt;p>Si ves algo, en el ámbito de tu tarea actual, que puede mejorarse fácilmente, mejóralo. Y si tienes alguna pregunta al respecto, pregunta.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="que-es-el-refactoring">¿Qué es el refactoring?
&lt;a class="heading-anchor" href="#que-es-el-refactoring" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Refactoring significa mejorar tu código. Puede ser renombrar una variable, extraer líneas en un método privado, o separar responsabilidades de una clase en varias.&lt;/p>
&lt;p>El refactoring demuestra que te importa lo que haces como profesional. Es un tema controvertido desde hace tiempo. Pero eso no debería frenarnos de mejorar la calidad del sistema.&lt;/p>
&lt;h2 id="cuando-y-como-refactorizar">¿Cuándo y cómo refactorizar?
&lt;a class="heading-anchor" href="#cuando-y-como-refactorizar" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Siempre. Dentro del ámbito de tu tarea actual, a menos que sea una tarea planificada específicamente para refactoring de arquitectura.&lt;/p>
&lt;blockquote>
&lt;p>El refactoring debería ser parte del trabajo diario, no una tarea separada.&lt;/p>
&lt;/blockquote>
&lt;p>No necesitamos pedir permiso para refactorizar. ¿Acaso pedimos permiso para hacer nuestro mejor trabajo?&lt;/p>
&lt;p>Para refactorizar bien, la intención debe estar clara. ¿Qué queremos lograr y cómo? El pair programming (o incluso el “pair thinking”) ayuda porque sincroniza dos cerebros y fomenta mejor comprensión mutua.&lt;/p>
&lt;p>Refactorizar de forma colaborativa es fundamental en equipo. No debería ser tabú. Al contrario: ayuda a unificar objetivos y dirección de calidad del código.&lt;/p>
&lt;h3 id="algunos-consejos-sobre-el-como">Algunos consejos sobre el “cómo”
&lt;a class="heading-anchor" href="#algunos-consejos-sobre-el-como" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Buscamos mejora continua, pero…&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Si tus cambios generan más ruido que ayuda, para. Piensa si valen la pena en el estado actual del sistema. Quizás no es el momento. Quizás estás contaminando el diff con cambios fuera del ámbito. O quizás es demasiado grande para tu tarea actual. En ese caso, mejor crear una tarea de seguimiento.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Si el refactoring es necesario antes de empezar tu tarea, hazlo primero.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Refactorizamos para aumentar productividad: código más legible es código más fácil de entender.&lt;/p>
&lt;h3 id="testing">Testing
&lt;a class="heading-anchor" href="#testing" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Necesitas un buen conjunto de tests cubriendo la lógica que vas a cambiar. Sin tests, refactorizar es arriesgado. Por lo general, cuanto más fácil es testear algo, más fácil es reemplazarlo o eliminarlo.&lt;/p>
&lt;p>Puedes leer más sobre cómo el testing está relacionado con la calidad aquí.&lt;/p>
&lt;h2 id="por-que-hacerlo">¿Por qué hacerlo?
&lt;a class="heading-anchor" href="#por-que-hacerlo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>¿No querrías un sistema mejor con el tiempo?&lt;/p>
&lt;p>El software no es como el vino: no mejora solo. Si quieres un sistema mejor, tienes que trabajar para conseguirlo.&lt;/p>
&lt;p>&lt;img src="/images/blog/2020-06-28/footer.webp" alt="el refactoring como mejora continua" />&lt;/p></content></entry><entry xml:lang="es"><title>Trabajando con código legado</title><subtitle>Estrategias para trabajar con código heredado</subtitle><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><published>2019-07-01T00:00:00+00:00</published><updated>2019-07-01T00:00:00+00:00</updated><author><name>
Michael Feathers</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/readings/working-effectively-with-legacy-code/"/><id>https://chemaclass.com/es/readings/working-effectively-with-legacy-code/</id><summary type="html">Estrategias prácticas para lidiar con grandes bases de código sin tests. Cómo añadir tests, romper dependencias y refactorizar con seguridad.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>&lt;h2 id="que-es-codigo-legacy">¿Qué es código legacy?
&lt;a class="heading-anchor" href="#que-es-codigo-legacy" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;blockquote>
&lt;p>El código legacy es simplemente código sin tests.&lt;/p>
&lt;/blockquote>
&lt;h3 id="beneficios-de-los-tests">Beneficios de los tests
&lt;a class="heading-anchor" href="#beneficios-de-los-tests" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>El comportamiento es clave para entender los beneficios del testing:&lt;/p>
&lt;blockquote>
&lt;p>El comportamiento es lo más importante del software. Los usuarios dependen de él. Les gusta que añadamos funcionalidad (si es lo que querían), pero si cambiamos o rompemos comportamiento del que dependen, pierden la confianza.&lt;/p>
&lt;/blockquote>
&lt;h3 id="como-implementar-tests-en-bases-de-codigo-legacy">Cómo implementar tests en bases de código legacy
&lt;a class="heading-anchor" href="#como-implementar-tests-en-bases-de-codigo-legacy" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Para cambiar código necesitas tests. Pero para añadir tests muchas veces tienes que cambiar código.&lt;/p>
&lt;p>El enfoque sugerido:&lt;/p>
&lt;ol>
&lt;li>Identificar puntos de cambio.&lt;/li>
&lt;li>Encontrar puntos de test.&lt;/li>
&lt;li>Romper dependencias.&lt;/li>
&lt;li>Escribir tests.&lt;/li>
&lt;li>Hacer cambios y refactorizar.&lt;/li>
&lt;/ol>
&lt;p>Un término útil es “&lt;strong>costura&lt;/strong>” (seam): &lt;strong>un lugar donde puedes cambiar el comportamiento sin editar ese código directamente&lt;/strong>. Como la costura en la ropa, donde dos partes se unen.
En software, &lt;strong>estos lugares suelen tener interfaces bien definidas&lt;/strong>. Puedes aprovecharlos para cambiar implementaciones con inyección de dependencias o mocking en tests.&lt;/p>
&lt;hr />
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/wRtJRkRIa2s"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry><entry xml:lang="es"><title>El Programador Pragmático</title><subtitle>El camino hacia la maestría</subtitle><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><category term="career" scheme="https://chemaclass.com/tags/career/" label="Career"/><published>2016-10-01T00:00:00+00:00</published><updated>2016-10-01T00:00:00+00:00</updated><author><name>
Andrew Hunt</name></author><author><name>
David Thomas</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/readings/the-pragmatic-programmer/"/><id>https://chemaclass.com/es/readings/the-pragmatic-programmer/</id><summary type="html">Un clásico sobre cómo convertirse en mejor desarrollador. Mentalidad, herramientas y buenas prácticas para dominar el oficio.</summary><content type="html">&lt;span id="continue-reading">&lt;/span>&lt;h3 id="aprendizajes">Aprendizajes
&lt;a class="heading-anchor" href="#aprendizajes" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>No te repitas.&lt;/li>
&lt;li>La mentalidad importa tanto como el conocimiento.&lt;/li>
&lt;li>El buen código es más fácil de cambiar que el mal diseño.&lt;/li>
&lt;li>Elige buenas herramientas y domínalas.&lt;/li>
&lt;/ul>
&lt;hr />
&lt;h4 id="no-te-repitas-dry">No Te Repitas (DRY)
&lt;a class="heading-anchor" href="#no-te-repitas-dry" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;ul>
&lt;li>Cada pieza de conocimiento debe tener una única representación clara dentro del sistema.&lt;/li>
&lt;li>DRY trata sobre la duplicación de conocimiento, de intención. Es expresar lo mismo en dos lugares, quizás de formas diferentes.&lt;/li>
&lt;/ul>
&lt;h4 id="la-mentalidad-importa-tanto-como-el-conocimiento">La mentalidad importa tanto como el conocimiento
&lt;a class="heading-anchor" href="#la-mentalidad-importa-tanto-como-el-conocimiento" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>Aspectos clave:&lt;/p>
&lt;ul>
&lt;li>Asume la responsabilidad de tu trabajo. Sin excusas ni culpas cuando algo sale mal.&lt;/li>
&lt;li>Escribe software “suficientemente bueno”. No pierdas tiempo perfeccionando lo que ya funciona para el producto.&lt;/li>
&lt;li>No ignores la deuda técnica. Los autores usan la analogía de las ventanas rotas:&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>No dejes “ventanas rotas” (malos diseños, decisiones incorrectas o código pobre) sin reparar.
Arregla cada una cuando la descubras. Si no hay tiempo, al menos tápalas.
Comenta el código problemático, muestra un mensaje de “No Implementado” o usa datos ficticios temporalmente.&lt;/p>
&lt;/blockquote></content></entry><entry xml:lang="es"><title>Código Limpio</title><subtitle>Manual de artesanía ágil de software</subtitle><category term="clean-code" scheme="https://chemaclass.com/tags/clean-code/" label="Clean Code"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><category term="refactoring" scheme="https://chemaclass.com/tags/refactoring/" label="Refactoring"/><published>2016-05-01T00:00:00+00:00</published><updated>2016-05-01T00:00:00+00:00</updated><author><name>
Robert C. Martin</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/readings/clean-code/"/><id>https://chemaclass.com/es/readings/clean-code/</id><summary type="html">El código malo funciona, pero puede hundir a una empresa. Cada año se pierden horas y recursos por código mal escrito. Este libro te enseña a evitarlo.</summary><content type="html">&lt;p>El código malo puede funcionar, pero si no está limpio, puede hundir a una empresa. Cada año se pierden horas y recursos por culpa de código mal escrito. No tiene por qué ser así.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;hr />
&lt;h2 id="resumen">Resumen
&lt;a class="heading-anchor" href="#resumen" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="capitulo-1-que-es-el-codigo-limpio">Capítulo 1: ¿Qué es el código limpio?
&lt;a class="heading-anchor" href="#capitulo-1-que-es-el-codigo-limpio" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>El código se puede medir como “bueno” o “malo” en una revisión, o por cuánto tiempo tardas en explicarlo.&lt;/li>
&lt;li>El código limpio es elegante, eficiente, legible, simple, sin duplicaciones y bien escrito.&lt;/li>
&lt;li>Tu código debe añadir valor al negocio.&lt;/li>
&lt;li>Al abrir un archivo fuente, el código limpio transmite calidad y se entiende fácilmente.&lt;/li>
&lt;li>Haz tu código limpio y legible para que cualquiera pueda entenderlo rápido. No hagas perder tiempo a otros.&lt;/li>
&lt;/ul>
&lt;h3 id="capitulo-2-nombres-significativos">Capítulo 2: Nombres significativos
&lt;a class="heading-anchor" href="#capitulo-2-nombres-significativos" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Los nombres de las clases, variables y métodos deben ser significativos e indicar claramente lo que hace un método o lo que es un atributo.&lt;/li>
&lt;li>Crea nombres pronunciables para facilitar la comunicación.&lt;/li>
&lt;li>Evita acrónimos y nombres confusos, que pueden llevar a conclusiones erróneas a cualquiera que lea el código.&lt;/li>
&lt;li>Usa nombres que reflejen el dominio del sistema, el contexto y los problemas que deben resolverse.&lt;/li>
&lt;/ul>
&lt;h3 id="capitulo-3-funciones">Capítulo 3: Funciones
&lt;a class="heading-anchor" href="#capitulo-3-funciones" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Los métodos deben ser fáciles de leer y entender.&lt;/li>
&lt;li>Deben transmitir su intención.&lt;/li>
&lt;li>Deben ser pequeños: hasta 20 líneas.&lt;/li>
&lt;li>Deben hacer solo una cosa.&lt;/li>
&lt;li>Usa nombres que digan claramente qué hace el método.&lt;/li>
&lt;li>El número ideal de parámetros es cero, luego uno, luego dos.&lt;/li>
&lt;li>Evita tres parámetros; si los usas, justifícalo.&lt;/li>
&lt;li>Un &lt;code>Boolean&lt;/code> como parámetro indica que el método hace más de una cosa.&lt;/li>
&lt;li>Evita la duplicación.&lt;/li>
&lt;/ul>
&lt;h3 id="capitulo-4-comentarios">Capítulo 4: Comentarios
&lt;a class="heading-anchor" href="#capitulo-4-comentarios" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Cuando necesitas comentarios suele ser porque el código es malo.&lt;/li>
&lt;li>Si piensas escribir un comentario, mejor refactoriza el código.&lt;/li>
&lt;li>Los comentarios no salvan el código malo.&lt;/li>
&lt;li>El código debe explicarse por sí mismo.&lt;/li>
&lt;li>A veces los comentarios son útiles en ciertos lugares específicos.&lt;/li>
&lt;li>No expliques el código con comentarios. Usa nombres descriptivos de variables y métodos.&lt;/li>
&lt;li>Los comentarios pueden destacar la importancia de ciertos puntos.&lt;/li>
&lt;li>No escribas comentarios redundantes, inútiles o falsos.&lt;/li>
&lt;li>Para saber quién cambió qué y por qué, usa control de versiones.&lt;/li>
&lt;li>No comentes código sin usar. Elimínalo.&lt;/li>
&lt;/ul>
&lt;h3 id="capitulo-5-formato">Capítulo 5: Formato
&lt;a class="heading-anchor" href="#capitulo-5-formato" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>El formato es una forma de comunicación entre desarrolladores.&lt;/li>
&lt;li>El código desordenado es difícil de leer.&lt;/li>
&lt;li>La legibilidad afecta a todos los cambios futuros.&lt;/li>
&lt;li>Las clases pequeñas son más fáciles de entender.&lt;/li>
&lt;li>Pon un límite de caracteres por línea (por ejemplo, 120).&lt;/li>
&lt;li>Mantén los conceptos relacionados cerca verticalmente para crear un flujo natural.&lt;/li>
&lt;li>Usa espacios entre operadores, parámetros y comas.&lt;/li>
&lt;/ul>
&lt;h3 id="capitulo-6-objetos-y-estructuras-de-datos">Capítulo 6: Objetos y estructuras de datos
&lt;a class="heading-anchor" href="#capitulo-6-objetos-y-estructuras-de-datos" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Sigue la &lt;a rel="external" href="https://en.wikipedia.org/wiki/Law_of_Demeter">Ley de Demeter&lt;/a>:
&lt;ul>
&lt;li>Cada unidad debe tener solo conocimiento limitado sobre otras unidades: solo unidades “estrechamente” relacionadas con la unidad actual.&lt;/li>
&lt;li>Cada unidad solo debe hablar con sus amigos; no hables con extraños.&lt;/li>
&lt;li>Solo habla con tus amigos inmediatos.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>No hagas objetos tontos.&lt;/li>
&lt;li>Los objetos ocultan la abstracción de datos y exponen métodos que operan los datos.&lt;/li>
&lt;li>Las estructuras de datos exponen sus datos y no tienen métodos significativos.&lt;/li>
&lt;/ul>
&lt;h3 id="capitulo-7-manejo-de-errores">Capítulo 7: Manejo de errores
&lt;a class="heading-anchor" href="#capitulo-7-manejo-de-errores" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Planifica el manejo de errores con cuidado.&lt;/li>
&lt;li>Cuando algo falla, hay que hacer que el sistema responda correctamente.&lt;/li>
&lt;li>Lanza excepciones en lugar de ocultarlas.&lt;/li>
&lt;li>Crea mensajes de error informativos: qué falló, dónde y, si es posible, por qué.&lt;/li>
&lt;li>Separa las reglas de negocio del manejo de errores.&lt;/li>
&lt;li>Evita devolver &lt;code>NULL&lt;/code>; devuelve un objeto vacío.&lt;/li>
&lt;li>Evita pasar &lt;code>NULL&lt;/code> a los métodos; puede causar &lt;code>NullPointerExceptions&lt;/code>.&lt;/li>
&lt;/ul>
&lt;h3 id="capitulo-8-limites">Capítulo 8: Límites
&lt;a class="heading-anchor" href="#capitulo-8-limites" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Al usar código de terceros, encapsula las APIs para no exponer objetos externos.&lt;/li>
&lt;li>Haz tests de las APIs de terceros.&lt;/li>
&lt;li>Estudia la documentación y prueba la API antes de usarla.&lt;/li>
&lt;li>Conoce bien las características que vas a usar.&lt;/li>
&lt;/ul>
&lt;h3 id="capitulo-9-tests-unitarios">Capítulo 9: Tests unitarios
&lt;a class="heading-anchor" href="#capitulo-9-tests-unitarios" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Asegúrate de que cada pieza de código hace lo que esperas.&lt;/li>
&lt;li>Sigue las &lt;a rel="external" href="https://en.wikipedia.org/wiki/Test-driven_development">leyes de TDD&lt;/a>:
&lt;ul>
&lt;li>No escribas código sin tener primero un test que falle.&lt;/li>
&lt;li>No escribas más tests de los necesarios para fallar.&lt;/li>
&lt;li>No escribas más código del necesario para pasar el test.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Mantén tus tests limpios.&lt;/li>
&lt;li>Los tests evolucionan junto con el código.&lt;/li>
&lt;li>Código sucio = tests difíciles de mantener.&lt;/li>
&lt;li>Usa la regla F.I.R.S.T:
&lt;ul>
&lt;li>&lt;strong>F&lt;/strong>ast: ejecución rápida.&lt;/li>
&lt;li>&lt;strong>I&lt;/strong>ndependent: independientes entre sí.&lt;/li>
&lt;li>&lt;strong>R&lt;/strong>epeatable: repetibles en cualquier entorno.&lt;/li>
&lt;li>&lt;strong>S&lt;/strong>elf-validating: auto-validantes.&lt;/li>
&lt;li>&lt;strong>T&lt;/strong>imely: escritos a tiempo.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Los tests son tan importantes como el código de producción.&lt;/li>
&lt;/ul>
&lt;h3 id="capitulo-10-clases">Capítulo 10: Clases
&lt;a class="heading-anchor" href="#capitulo-10-clases" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>Organiza las clases así:
&lt;ul>
&lt;li>Constantes públicas estáticas.&lt;/li>
&lt;li>Variables privadas estáticas.&lt;/li>
&lt;li>Variables de instancia privadas.&lt;/li>
&lt;li>Luego los métodos.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>El nombre de la clase debe reflejar su responsabilidad.&lt;/li>
&lt;li>Cada clase debe tener &lt;a rel="external" href="https://en.wikipedia.org/wiki/Single-responsibility_principle">una sola responsabilidad&lt;/a>: una razón para cambiar.&lt;/li>
&lt;li>Intenta describir la clase en una frase breve.&lt;/li>
&lt;li>Los métodos deben ser pequeños y con una sola responsabilidad.&lt;/li>
&lt;/ul>
&lt;hr />
&lt;p>Esta entrevista se basa en el libro de Uncle Bob “Código Limpio”. Repasan algunas guías que te ayudarán a ser mejor programador y exploran cómo los libros y tendencias actuales están moldeando el mundo del software.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/QnmRpHFoYLk"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div></content></entry></feed>