<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es"><title>Chemaclass - bashunit</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/bashunit/atom.xml"/><link rel="alternate" type="text/html" href="https://chemaclass.com"/><generator uri="https://www.getzola.org/">Zola</generator><updated>2024-10-30T00:00:00+00:00</updated><id>https://chemaclass.com/es/tags/bashunit/atom.xml</id><entry xml:lang="es"><title>bashunit</title><subtitle>Convirtiendo frustraciones en herramientas para mejor desarrollo</subtitle><category term="bashunit" scheme="https://chemaclass.com/tags/bashunit/" label="Bashunit"/><category term="bash" scheme="https://chemaclass.com/tags/bash/" label="Bash"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="open-source" scheme="https://chemaclass.com/tags/open-source/" label="Open Source"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><published>2024-10-30T00:00:00+00:00</published><updated>2024-10-30T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/bashunit/"/><id>https://chemaclass.com/es/blog/bashunit/</id><summary type="html">bashunit es un framework de testing ligero y fácil de usar para Bash, repleto de características útiles como testing paralelo y de snapshots, dobles de test, data providers y toneladas de assertions incorporadas. Respaldado por documentación clara y una comunidad activa, se ha convertido en un favorito para testing confiable en Bash. Lo que comenzó como una simple frustración de desarrollo ha crecido hasta convertirse en una herramienta open-source que hace que el testing en Bash sea mucho más fácil y divertido.</summary><content type="html">&lt;p>bashunit es un framework de testing ligero y fácil de usar para Bash. Características como testing paralelo y de snapshots, dobles de test, data providers y toneladas de assertions incorporadas.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>Respaldado por documentación clara y una comunidad activa, se ha convertido en un favorito para testing confiable en Bash. Lo que comenzó como una simple frustración de desarrollo ha crecido hasta convertirse en una herramienta open-source que hace que el testing en Bash sea mucho más fácil y divertido.&lt;/p>
&lt;ol>
&lt;li>La historia detrás de bashunit&lt;/li>
&lt;li>¿Por qué crear otra librería de testing?&lt;/li>
&lt;li>¿Cómo está hoy en día?&lt;/li>
&lt;li>Características principales&lt;/li>
&lt;li>Lightning tech talk&lt;/li>
&lt;/ol>
&lt;h2 id="la-historia-detras-de-bashunit">La historia detrás de bashunit
&lt;a class="heading-anchor" href="#la-historia-detras-de-bashunit" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>El viaje para crear bashunit comenzó con una simple frustración: trabajaba con un equipo donde cada commit tenía que empezar con el nombre del ticket. Como me gusta trabajar en pequeños pasos con commits rápidos e iterativos, añadir la clave y número del ticket a cada commit se convirtió en un gran obstáculo, ralentizando mi flujo de desarrollo con fricción innecesaria.&lt;/p>
&lt;p>Después de unos días así, decidí automatizarlo. Git tiene un hook útil, &lt;code>prepare-commit-msg&lt;/code>, que te permite alterar los mensajes de commit antes de que se finalicen. Creé un (&lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/main/git-hooks/prepare-commit-msg.sh">script&lt;/a>) en Bash que automáticamente obtiene la clave y número del ticket del nombre de la rama y lo inserta en el mensaje del commit, haciendo mi proceso más fluido y eficiente.&lt;/p>
&lt;p>Como alguien que valora la mejora continua, comencé a añadir más características a este script. Sin embargo, se hizo evidente que mantener y probar estos cambios manualmente llevaba demasiado tiempo y era propenso a errores. Para hacer el desarrollo más seguro y eficiente, creé una función &lt;code>assert&lt;/code>(&lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/705489a3487a4607183090d5574827bf6fedabda/git-hooks/prepare-commit-msg_test.sh">enlace&lt;/a>), permitiendo tests automatizados que verificaban el comportamiento esperado basado en la salida del script.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-original-assert.jpg" alt="bashunit-original-assert.jpg" />&lt;/p>
&lt;p>La función &lt;code>assert&lt;/code> me permitió definir múltiples assertions en un archivo separado, facilitando la validación de que cualquier refactorización del hook original mantuviera el comportamiento esperado. Si un cambio rompía inadvertidamente la funcionalidad existente, lo señalaría instantáneamente, haciéndome saber de inmediato que algo necesitaba arreglarse. Esta configuración proporcionaba retroalimentación inmediata y ayudaba a asegurar que cualquier actualización al script no interrumpiera su lógica prevista. Por ejemplo:&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/conventional-commits-original-tests.jpg" alt="conventional-commits-original-tests.jpg" />&lt;/p>
&lt;p>En el ejemplo anterior, notarás que ejecuto el “&lt;code>SCRIPT&lt;/code>” real como el segundo argumento en la función assert, comparando su salida con el valor esperado proporcionado como primer argumento. Aquí, tenemos dos casos de test, cada uno exportando &lt;code>TEST_BRANCH&lt;/code> para simular cómo el mensaje del commit variaría según el nombre de la rama. Esta configuración emula el comportamiento real, permitiéndonos probar cómo diferentes nombres de rama afectan el formato del mensaje del commit. Más ejemplos &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/27aeebe4e76afe0a2e91cba85537399eab112eb4/test/prepare-commit-msg_test.sh">aquí&lt;/a>.&lt;/p>
&lt;p>Decidí separar la función &lt;code>assert&lt;/code> de los casos de test, como se muestra &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/commit/5458e5728296bb94b1e8e6b25eeccde6cc700589">aquí&lt;/a>, para mantener las cosas modulares y reutilizables. Luego, creé un &lt;code>runner&lt;/code> para ejecutar cada caso de test independientemente, reduciendo la interferencia entre tests y mejorando la confiabilidad. Puedes ver esa configuración &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/commit/92a5880d7f26b3422de6b91b51c04f9ff7b961fd">aquí&lt;/a>. Esta estructura hizo el testing automatizado más fácil y la refactorización más segura.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/conventional-commits-call_test_functions.jpg" alt="conventional-commits-call_test_functions.jpg" />&lt;/p>
&lt;p>Esta fue una gran mejora porque facilitó separar los &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/4c7dae8d44d425ff06fbb48654388f90c2beb3c4/tests/prepare-commit-msg_test.sh">casos de test&lt;/a> de la lógica del runner de tests en sí. Esta estructura clara ha simplificado tanto la creación como la gestión de tests.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/conventional-commits-refactor-test-cases.webp" alt="conventional-commits-refactor-test-cases.jpg" />&lt;/p>
&lt;p>Ahora los tests estaban organizados y tuve una &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/commit/f459f43cecc271becb1e5eb6ca95d24c97e87830">idea&lt;/a>:&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-idea.jpg" alt="nota de la idea de bashunit" />&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="markdown">&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);font-weight: bold;">##&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);font-weight: bold;"> Idea de seguimiento&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>Separar la lógica de testing en otro repositorio,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>para que pueda ser reutilizada en cualquier lugar.&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Y así &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/commit/27269c21c8d0b03bcb3f2000767f4a27b8bf08a1">comenzó&lt;/a>. En ese momento, no sabía mucho sobre Bash o las mejores formas de usar un proyecto Bash como dependencia. Pero sabía que podía empezar usando un submódulo de Git, aunque no soy muy fan de ellos.&lt;/p>
&lt;p>El 4 de septiembre de 2023, lancé la versión &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/commit/fc9aac40eb8e5ad4483f08d79eb678a3650dcf78">0.1&lt;/a>, que presentaba un runner funcional y una única función de assertion: &lt;code>assertEquals&lt;/code>. Más tarde, se lanzó la versión &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/commit/b546c693198870dd75d1a102b94f4ddad6f4f3ea#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4edR12">0.2&lt;/a>, permitiendo que &lt;code>./bashunit&lt;/code> fuera un ejecutable independiente, ejecutable desde cualquier carpeta. Así es como se veía entonces:&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-02-demo.jpg" alt="bashunit-02-demo.jpg" />&lt;/p>
&lt;p>Compartí el proyecto con algunos amigos que rápidamente se unieron para ayudar con la documentación, el sitio web, assertions adicionales, testing de snapshots y decisiones clave. Para enfatizar su espíritu open-source y propiedad comunitaria, lo moví a una organización que creamos específicamente para compartir proyectos OSS, convirtiéndolo en un proyecto verdaderamente colaborativo en lugar de uno individual.&lt;/p>
&lt;h2 id="por-que-crear-otra-libreria-de-testing">¿Por qué crear otra librería de testing?
&lt;a class="heading-anchor" href="#por-que-crear-otra-libreria-de-testing" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Ahora sé que existen otras librerías de testing para Bash. Pero cuando empecé con bashunit, no las conocía, y francamente, todavía no soy un experto en Bash. Para cuando me enteré de estas alternativas, ya era demasiado tarde, bashunit había ganado suficiente impulso y entusiasmo para seguir adelante.&lt;/p>
&lt;p>Mientras que esas otras librerías pueden servir casos de uso específicos, usar Bash moderno, o ser desarrolladas por desarrolladores de Bash más experimentados, bashunit aspira a diferenciarse ofreciendo una gran experiencia de desarrollador, moldeada por años de trabajo con varios frameworks de testing.&lt;/p>
&lt;p>Me preguntaron sobre las diferencias el 7 de septiembre de 2023, y aquí está mi respuesta:
&lt;a rel="external" href="https://github.com/TypedDevs/bashunit/issues/8">Pregunta: Diferencia con pgrange/bash_unit&lt;/a>.&lt;/p>
&lt;h2 id="como-esta-hoy-en-dia">¿Cómo está hoy en día?
&lt;a class="heading-anchor" href="#como-esta-hoy-en-dia" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Hoy, puedes &lt;a rel="external" href="https://bashunit.typeddevs.com/installation">instalar&lt;/a> bashunit via curl, Homebrew, MacPorts, descargando el último &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/releases">release de GitHub&lt;/a>, o incluso &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/blob/main/build.sh">compilándolo tú mismo&lt;/a> desde el código fuente. Completamente open-source.&lt;/p>
&lt;p>El proyecto está escrito en Bash 3.2 (de 2007) ya que esa es la versión por defecto en macOS, incluso ahora, en 2024. Esta compatibilidad significa que bashunit funciona sin problemas en esa versión, y planeo mantener el soporte para ella.&lt;/p>
&lt;p>Para asegurar la calidad, probamos cada característica con tests unitarios, funcionales y de aceptación, haciendo que bashunit sea su propio “primer usuario” de cada nueva característica. También tenemos varios workflows de CI usando &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/actions/workflows/tests.yml">GitHub actions&lt;/a> que ejecutan tests en diferentes plataformas para verificar compatibilidad y confirmar que todo funciona como se promete.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-ci.jpg" alt="bashunit-ci.jpg" />&lt;/p>
&lt;p>En junio de 2024, bashunit fue &lt;a rel="external" href="https://bashunit.typeddevs.com/blog/2024-06-21-phpstan-integration">integrado en PHPStan&lt;/a> para sus tests end-to-end, permitiendo el uso de las assertions de bashunit independientemente de su runner. Esta flexibilidad resultó ser muy útil.&lt;/p>
&lt;p>El verano pasado, fui invitado a hablar sobre bashunit en la &lt;a href="/es/talks/#may">International PHP Conference&lt;/a> en Berlín, junto con &lt;a rel="external" href="https://emmanuelvalverde.dev/">Manu&lt;/a>, otro contribuidor. Este proyecto ha abierto puertas y ha llevado a mucha gratitud de usuarios que aprecian el trabajo que hemos puesto en él.&lt;/p>
&lt;h2 id="caracteristicas-principales">Características principales
&lt;a class="heading-anchor" href="#caracteristicas-principales" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>bashunit incluye funciones clásicas del ciclo de vida como &lt;code>set_up&lt;/code>, &lt;code>tear_down&lt;/code>, &lt;code>set_up_before_script&lt;/code> y &lt;code>tear_down_after_script&lt;/code>.&lt;/p>
&lt;p>También soporta una amplia gama de &lt;a rel="external" href="https://bashunit.typeddevs.com/command-line">parámetros de línea de comandos&lt;/a>
y &lt;a rel="external" href="https://bashunit.typeddevs.com/configuration">valores de configuración&lt;/a>. Algunos de mis favoritos incluyen:&lt;/p>
&lt;ul>
&lt;li>&lt;code>--parallel&lt;/code>&lt;/li>
&lt;li>&lt;code>--filter&lt;/code>&lt;/li>
&lt;li>&lt;code>--stop-on-failure&lt;/code>&lt;/li>
&lt;li>&lt;code>--verbose&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>También proporcionamos &lt;a rel="external" href="https://bashunit.typeddevs.com/data-providers">data providers&lt;/a> para ejecutar los mismos casos de test con diferentes inputs.&lt;/p>
&lt;p>Para &lt;a rel="external" href="https://bashunit.typeddevs.com/test-doubles">dobles de test&lt;/a>, bashunit ofrece mocks y spies. Estos funcionan dentro del mismo proceso que el test, pero actualmente no funcionan entre procesos, un área para mejorar.&lt;/p>
&lt;p>Incluye potente &lt;a rel="external" href="https://bashunit.typeddevs.com/snapshots">testing de snapshots&lt;/a>, facilitando la verificación de salidas de comandos o scripts a lo largo del tiempo.&lt;/p>
&lt;p>bashunit ofrece un amplio conjunto de &lt;a rel="external" href="https://bashunit.typeddevs.com/assertions">assertions&lt;/a> nativas para casos de test, incluyendo:&lt;/p>
&lt;ul>
&lt;li>&lt;code>assert_same&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_equals&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_contains&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_matches&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_string_starts_with&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_array_contains&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_successful_code&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_general_error&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_file_exists&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_file_contains&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_match_snapshot&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Incluso puedes crear tus propias &lt;a rel="external" href="https://bashunit.typeddevs.com/custom-asserts">assertions personalizadas&lt;/a> para extender las capacidades de bashunit.&lt;/p>
&lt;p>Con más de &lt;strong>25&lt;/strong> contribuidores y más de &lt;strong>325&lt;/strong> estrellas en GitHub en solo un año de desarrollo en tiempo libre, estoy genuinamente orgulloso de lo que este proyecto se ha convertido.&lt;/p>
&lt;h2 id="lightning-tech-talk">Lightning tech talk
&lt;a class="heading-anchor" href="#lightning-tech-talk" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Recientemente, presenté una lightning tech talk en un meetup de hackers, haciendo una demo de bashunit a una audiencia de más de 100 personas. ¡Fue una experiencia increíble compartir esta herramienta con una audiencia tan comprometida!&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/SX7iNHaSsF0"
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;p>Logo original de bashunit diseñado por &lt;a rel="external" href="https://antonio.gg/">Antonio&lt;/a>.&lt;/p></content></entry></feed>