<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Johan Garcia</title>
    <description>The latest articles on DEV Community by Johan Garcia (@devjohanadrian).</description>
    <link>https://dev.to/devjohanadrian</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1330042%2Fe604656f-104b-4279-8285-06c5e42d59be.png</url>
      <title>DEV Community: Johan Garcia</title>
      <link>https://dev.to/devjohanadrian</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devjohanadrian"/>
    <language>en</language>
    <item>
      <title>Camino a CI/CD pruebas (Testing)</title>
      <dc:creator>Johan Garcia</dc:creator>
      <pubDate>Fri, 10 Apr 2026 05:09:40 +0000</pubDate>
      <link>https://dev.to/devjohanadrian/camino-a-cicd-pruebas-testing-3ohn</link>
      <guid>https://dev.to/devjohanadrian/camino-a-cicd-pruebas-testing-3ohn</guid>
      <description>&lt;p&gt;El stage de testing es, en la mayoría de pipelines, la etapa que sigue después de la compilación o build. En este punto, el sistema ya es ejecutable, pero aún no es confiable.&lt;/p&gt;

&lt;p&gt;Aquí es donde entra el testing: no como un paso opcional, sino como el filtro que evita que errores, regresiones o comportamientos inesperados lleguen a producción.&lt;/p&gt;

&lt;p&gt;En esta sección, se busca responder una pregunta clave:&lt;/p&gt;

&lt;p&gt;¿Qué debería tener un pipeline a nivel de testing para considerarse realmente sólido?&lt;/p&gt;




&lt;h2&gt;
  
  
  Tipos de Testing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Testing Funcional&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;El testing funcional valida que el sistema haga lo que se espera que haga. Es decir, se enfoca en el comportamiento, no en cómo está implementado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unit Testing (Pruebas Unitarias)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Las pruebas unitarias validan las piezas más pequeñas del sistema: funciones, métodos o componentes individuales.&lt;/p&gt;

&lt;p&gt;Su objetivo es detectar errores lo más temprano posible, antes de que escalen.&lt;/p&gt;

&lt;p&gt;Qué cubren normalmente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lógica de negocio aislada&lt;/li&gt;
&lt;li&gt;Validaciones&lt;/li&gt;
&lt;li&gt;Transformaciones de datos&lt;/li&gt;
&lt;li&gt;Casos borde&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqaalrornlbg0c5btc7uh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqaalrornlbg0c5btc7uh.png" alt=" " width="800" height="1140"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aquí no importa el sistema completo, solo que esa unidad funcione correctamente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgbbcvd9naupvf0n5ia30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgbbcvd9naupvf0n5ia30.png" alt=" " width="800" height="791"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integration Testing (Pruebas de Integración)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aquí se sube un nivel: ya no se prueba una pieza aislada, sino cómo interactúan varias partes del sistema.&lt;/p&gt;

&lt;p&gt;El objetivo es validar que los componentes colaboren correctamente.&lt;/p&gt;

&lt;p&gt;Qué suele incluir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Componentes + servicios&lt;/li&gt;
&lt;li&gt;Acceso a base de datos&lt;/li&gt;
&lt;li&gt;APIs simuladas (MSW, mocks controlados)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ejemplo conceptual:&lt;/p&gt;

&lt;p&gt;Un componente llama a un servicio → el servicio consulta datos → el resultado se renderiza correctamente.&lt;/p&gt;

&lt;p&gt;Si alguna de esas piezas falla en conjunto, el test lo detecta.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1dwn9ovgsqodq9rgxtny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1dwn9ovgsqodq9rgxtny.png" alt=" " width="800" height="1105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffcvrq4fhtwbd76hgft25.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffcvrq4fhtwbd76hgft25.png" alt=" " width="800" height="1385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;End-to-End Testing (E2E)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Las pruebas E2E validan el sistema completo desde la perspectiva del usuario.&lt;/p&gt;

&lt;p&gt;Simulan flujos reales en un entorno lo más cercano posible a producción.&lt;/p&gt;

&lt;p&gt;Ejemplo típico:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El usuario entra a la app&lt;/li&gt;
&lt;li&gt;Hace login&lt;/li&gt;
&lt;li&gt;Crea un registro&lt;/li&gt;
&lt;li&gt;Lo visualiza en pantalla&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si todo eso funciona, el sistema cumple su propósito en ese flujo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv39e5qhlfqw86ipjs9eh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv39e5qhlfqw86ipjs9eh.png" alt=" " width="800" height="1487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Smoke Testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;El smoke testing responde una única pregunta:&lt;/p&gt;

&lt;p&gt;¿El sistema funciona lo suficiente como para seguir probándolo?&lt;/p&gt;

&lt;p&gt;Se ejecuta justo después del build, y actúa como un primer filtro.&lt;/p&gt;

&lt;p&gt;Si falla aquí, no tiene sentido continuar.&lt;/p&gt;

&lt;p&gt;Ejemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;¿La app levanta?&lt;/li&gt;
&lt;li&gt;¿El login responde?&lt;/li&gt;
&lt;li&gt;¿una ruta principal carga?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No valida lógica profunda ni reglas complejas.&lt;/p&gt;

&lt;p&gt;Solo verifica lo esencial.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9297woq920oeh8g320xy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9297woq920oeh8g320xy.png" alt=" " width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este test no valida:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;expiración del token&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;roles&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;seguridad avanzada&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Solo valida algo clave: “¿el login funciona?”,  Si esto falla, todo lo demás deja de tener sentido.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity Testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;El sanity testing es un chequeo rápido y enfocado después de un cambio puntual.&lt;/p&gt;

&lt;p&gt;No busca validar todo el sistema, sino algo muy concreto:&lt;/p&gt;

&lt;p&gt;¿Lo que se modificó sigue funcionando sin romper lo demás?&lt;/p&gt;

&lt;p&gt;Se usa cuando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hay un bug fix&lt;/li&gt;
&lt;li&gt;Se hace un refactor pequeño&lt;/li&gt;
&lt;li&gt;Se ajusta una funcionalidad específica&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Características:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dirigido (no exploratorio)&lt;/li&gt;
&lt;li&gt;Ligero (no exhaustivo)&lt;/li&gt;
&lt;li&gt;Rápido (busca confianza inmediata)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgfluh0az925gttpchsg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgfluh0az925gttpchsg.png" alt=" " width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regression Testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;El regression testing protege el sistema a medida que evoluciona.&lt;/p&gt;

&lt;p&gt;Cada cambio introduce riesgo, y este tipo de pruebas actúa como una red de seguridad.&lt;/p&gt;

&lt;p&gt;Valida que:&lt;/p&gt;

&lt;p&gt;Lo que funcionaba → siga funcionando&lt;br&gt;
Los cambios → no generen efectos colaterales&lt;/p&gt;

&lt;p&gt;No se enfoca en lo nuevo, sino en evitar que lo existente se rompa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fulr4s0aycf25l5w7cayu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fulr4s0aycf25l5w7cayu.png" alt=" " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Acceptance Testing (UAT)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Es la fase donde el sistema deja de evaluarse como “código que funciona” y pasa a validarse como “producto que resuelve un problema real”. Aquí ya no importa tanto si la lógica interna está bien implementada, sino si lo que se construyó realmente cumple con lo que el usuario o el negocio esperaba.&lt;/p&gt;

&lt;p&gt;En otras palabras, es el momento en el que alguien del lado del negocio no necesariamente un desarrollador usa la aplicación en escenarios reales y responde una pregunta clave: ¿esto sirve para lo que se necesitaba?&lt;/p&gt;

&lt;p&gt;A diferencia de otros tipos de testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No se centra en funciones aisladas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No valida detalles técnicos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No busca bugs “técnicos” principalmente.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se enfoca en algo mucho más importante:&lt;/p&gt;

&lt;p&gt;Validar que el sistema cumple con los requisitos funcionales desde la perspectiva del usuario final.&lt;/p&gt;

&lt;p&gt;Ejemplo&lt;/p&gt;

&lt;p&gt;Contexto: Un módulo de inventario.&lt;/p&gt;

&lt;p&gt;Requisito de negocio:&lt;br&gt;
“El usuario debe poder registrar un producto y verlo reflejado en el inventario.”&lt;/p&gt;

&lt;p&gt;UAT:&lt;br&gt;
Escenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El usuario crea un producto: Nombre: “Laptop” Cantidad: 5&lt;/li&gt;
&lt;li&gt;Guarda el registro&lt;/li&gt;
&lt;li&gt;Va al listado de inventario&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Resultado esperado:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El producto aparece&lt;/li&gt;
&lt;li&gt;La cantidad es correcta&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No hay inconsistencias&lt;/p&gt;

&lt;p&gt;Si eso pasa, el sistema cumple el requisito, aunque internamente pueda tener mejoras técnicas pendientes.&lt;/p&gt;

&lt;p&gt;Tipos de UAT que suelen aparecer&lt;br&gt;
Aunque muchas veces se agrupan como uno solo, en la práctica se ven variantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alpha Testing → interno (equipo del producto)&lt;/li&gt;
&lt;li&gt;Beta Testing → usuarios reales&lt;/li&gt;
&lt;li&gt;Business UAT → validación contra requisitos del negocio&lt;/li&gt;
&lt;li&gt;Operational UAT → validación en condiciones reales (ambiente, datos, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consideraciones &lt;/p&gt;

&lt;p&gt;El UAT no lo hace el desarrollador&lt;/p&gt;

&lt;p&gt;Normalmente lo ejecutan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Stakeholders&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;QA con enfoque de negocio&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cliente final&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Porque lo que se valida no es el código, sino la utilidad real del sistema.&lt;/p&gt;

&lt;p&gt;Su finalidad es&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ejecutarse en entornos de staging&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ser parcialmente manual (aunque puede automatizarse con criterios de aceptación)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Actuar como último gate antes de producción&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Contract Testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Este tipo de testing se vuelve crítico en arquitecturas distribuidas.&lt;/p&gt;

&lt;p&gt;Valida que dos sistemas que se comunican (por ejemplo, frontend y backend) respeten un contrato.&lt;/p&gt;

&lt;p&gt;Ese contrato define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request&lt;/li&gt;
&lt;li&gt;Response&lt;/li&gt;
&lt;li&gt;Tipos de datos&lt;/li&gt;
&lt;li&gt;Campos obligatorios&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Problema típico que resuelve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;El backend funciona, sus tests pasan… pero el frontend se rompe.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;El contract testing evita ese tipo de desalineaciones.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fysurvetl2txvtytsued0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fysurvetl2txvtytsued0.png" alt=" " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;El backend funciona &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Los tests del backend pasan &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pero el frontend se rompe &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aquí es donde el Contract Testing evita el desastre.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tipos de Contract Testing&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Consumer-Driven Contract Testing (el más usado)&lt;/strong&gt;&lt;br&gt;
El consumidor (frontend) define lo que necesita.&lt;/p&gt;

&lt;p&gt;Ejemplo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs7v6fxmbrb19vk5rxcc5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs7v6fxmbrb19vk5rxcc5.png" alt=" " width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Provider Verification&lt;/strong&gt;&lt;br&gt;
El backend valida que cumple ese contrato.&lt;/p&gt;

&lt;p&gt;Ejemplo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk1zrki9igdi9ynx71u6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk1zrki9igdi9ynx71u6.png" alt=" " width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;2. Testing No Funcional&lt;/strong&gt;&lt;br&gt;
Aquí no se valida qué hace el sistema, sino cómo se comporta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance Testing&lt;/strong&gt;&lt;br&gt;
Se centra en evaluar cómo se comporta una aplicación bajo distintas condiciones de carga, no desde la lógica funcional, sino desde atributos como tiempo de respuesta, throughput, uso de recursos y estabilidad. En términos prácticos, lo que se busca es responder preguntas como: ¿cuántos usuarios simultáneos puede soportar el sistema?, ¿qué tan rápido responde bajo presión?, ¿en qué punto comienza a degradarse? Este tipo de pruebas es clave en sistemas reales porque muchos fallos no aparecen en desarrollo, sino cuando el sistema enfrenta tráfico real. Dentro de este enfoque se incluyen variantes como load testing, stress testing y spike testing, cada una orientada a distintos patrones de carga.&lt;/p&gt;

&lt;p&gt;Ejemplo &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjv6bjmz9vmk0hhgjin0v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjv6bjmz9vmk0hhgjin0v.png" alt=" " width="800" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El el ejemplo anterior se simulan 50 usuarios concurrentes durante 30 segundos haciendo peticiones al mismo endpoint. Si el sistema responde rápido y sin errores, el comportamiento es aceptable. Si el tiempo de respuesta aumenta significativamente o aparecen errores (timeouts, 500), entonces ya se está evidenciando un problema de rendimiento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Testing&lt;/strong&gt;&lt;br&gt;
Aunque forma parte del testing, muchas veces se maneja como un stage independiente.&lt;/p&gt;

&lt;p&gt;Incluye:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SAST - Static Application Security Testing (análisis estático)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DAST - Dynamic Application Security Testing (análisis dinámico)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SCA - Software Composition Analysis&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secrets Detection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Container Security&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IaC, API, y Compliance &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security Headers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependency Scanning&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Mutation Testing (Pruebas de Mutación)&lt;/strong&gt;&lt;br&gt;
El mutation testing pregunta: "Si introduzco un pequeño bug en mi código, ¿mis pruebas realmente lo detectarán?" Esto revela la diferencia crítica entre cobertura de pruebas y efectividad de pruebas. &lt;/p&gt;

&lt;p&gt;El resultado se mide con el mutation score.&lt;/p&gt;

&lt;p&gt;Ejemplo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm200awuipzk35zebo1mi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm200awuipzk35zebo1mi.png" alt=" " width="800" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Herramientas
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Testing Unitario e Integración&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jest (JavaScript/TypeScript)&lt;/li&gt;
&lt;li&gt;Pytest (Python):&lt;/li&gt;
&lt;li&gt;JUnit (Java)&lt;/li&gt;
&lt;li&gt;NUnit (C#/.NET)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Testing E2E y UI&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selenium: Arquitectura empresarial de Selenium Python con Pytest, Allure y patrones de diseño GitHub&lt;/li&gt;
&lt;li&gt;Cypress&lt;/li&gt;
&lt;li&gt;Playwright&lt;/li&gt;
&lt;li&gt;Puppeteer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Contract Testing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Pact: Flujo típico con Pact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El frontend define el contrato&lt;/li&gt;
&lt;li&gt;Se guarda como archivo (.json)&lt;/li&gt;
&lt;li&gt;El backend ejecuta tests contra ese contrato
Si algo no coincide → falla el pipeline&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Testing Performance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Locust (Python)&lt;/li&gt;
&lt;li&gt;K6 (JavaScript/TS): Ofrece integración nativa con CI/CD y la nube.&lt;/li&gt;
&lt;li&gt;Gatling (Java/Kotlin/JS/Scala)&lt;/li&gt;
&lt;li&gt;Apache JMeter Java/GUI): Ideal para equipos QA tradicionales y empresas, siendo opensource.&lt;/li&gt;
&lt;li&gt;Atillery (Node.js/YAML)&lt;/li&gt;
&lt;li&gt;Vegeta (Go)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Alternativas en la nube para Testing performance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BlazeMeter: Permite ejecutar scripts de JMeter, k6, Locust y Gatling en la nube&lt;/li&gt;
&lt;li&gt;LoadNinja: Se enfoca en pruebas con navegadores reales en lugar de simular protocolos, lo que da métricas de experiencia de usuario más precisas. No requiere programación&lt;/li&gt;
&lt;li&gt;Azure Load Testing: Un servicio gestionado por Microsoft que permite subir scripts de JMeter y ofrece integraciones profundas con el ecosistema de Azure.&lt;/li&gt;
&lt;li&gt;OctoPerf: Diseñado específicamente para usuarios de JMeter que quieren una interfaz web moderna&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Testing Mutation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PIT (PITest) para Java con escalabilidad empresarial.&lt;/li&gt;
&lt;li&gt;Stryker Mutator con soporte multi-lenguaje (JavaScript, TypeScript, C#, Scala).&lt;/li&gt;
&lt;li&gt;MutPy para Python. &lt;/li&gt;
&lt;li&gt;Infection para PHP.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Un buen stage de testing no se define por la cantidad de herramientas o tests, sino por su capacidad de generar confianza.&lt;/p&gt;

&lt;p&gt;Al final, todo se resume en esto:&lt;/p&gt;

&lt;p&gt;Detectar errores lo antes posible, con el menor costo posible, y antes de que impacten al usuario.&lt;/p&gt;

&lt;p&gt;Si el pipeline logra eso, entonces está bien diseñado.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>testing</category>
      <category>programming</category>
    </item>
    <item>
      <title>Como potenciar tu VS Code con Continue.dev Cline</title>
      <dc:creator>Johan Garcia</dc:creator>
      <pubDate>Fri, 25 Apr 2025 05:36:10 +0000</pubDate>
      <link>https://dev.to/devjohanadrian/como-potenciar-tu-vs-code-con-continuedev-cline-lic</link>
      <guid>https://dev.to/devjohanadrian/como-potenciar-tu-vs-code-con-continuedev-cline-lic</guid>
      <description>&lt;p&gt;Hoy en día, vemos la inteligencia artificial (IA) en todas partes, y no es de extrañar que, en el mundo del desarrollo de software, se estén explorando una gran variedad de usos. Un claro ejemplo son los editores de código con integración de IA, como Cursor.ai, Windsurf o el más reciente Firebase Studio. Estas herramientas ofrecen funcionalidades avanzadas, como autocompletado inteligente y generación o edición de código a partir de prompts.&lt;/p&gt;

&lt;p&gt;Hace unas semanas estuve probando tanto Cursor como Windsurf en algunos de mis proyectos personales, y, sinceramente, es increíble lo que se puede lograr cuando sabes bien lo que estás haciendo. Investigando un poco más, encontré una forma de darle “músculo” a Visual Studio Code —recordemos que Cursor y Windsurf están basados en VS Code—, ya que este, por defecto, no incluye muchas de las características que sí ofrecen estas versiones modificadas de pago.&lt;/p&gt;

&lt;h2&gt;
  
  
  La solución: integrar Continue.dev y Cline, dos extensiones poderosas y open source para VS Code, que transforman tu editor en un verdadero IDE con esteroides. En este artículo te voy a mostrar cómo configurarlas paso a paso, qué modelos puedes usar, sus limitaciones y por qué esta combinación puede convertirse en tu nuevo entorno favorito para programar con IA.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;REQUISITOS PREVIOS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tener Visual Studio Code instalado.&lt;/li&gt;
&lt;li&gt;Contar con una cuenta gratuita en Groq y OpenRouter.&lt;/li&gt;
&lt;li&gt;En el apartado de extensiones de VS Code, buscar la extensión Continue y asegurarte de seleccionar al desarrollador: Continue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Al instalarla, se creará una carpeta llamada .continue/ en la raíz de tu espacio de trabajo, que suele ubicarse en C:\Users\user. (Es importante tener presente este punto)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Luego, en el mismo apartado de extensiones de VS Code, buscar la extensión Cline y seleccionar al desarrollador: Cline.bot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Existen otros proveedores de modelos de IA, como Together AI, pero, al parecer, este no ofrece modelos open source.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cómo funciona Continue.dev?&lt;/strong&gt;&lt;br&gt;
Continue.dev actúa como un asistente inteligente dentro de Visual Studio Code. Sus principales funciones incluyen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leer y analizar tu código fuente.&lt;/li&gt;
&lt;li&gt;Completar funciones o bloques de código completos.&lt;/li&gt;
&lt;li&gt;Editar fragmentos mediante prompts.&lt;/li&gt;
&lt;li&gt;Responder preguntas técnicas o sugerir mejoras.&lt;/li&gt;
&lt;li&gt;Leer el contexto del proyecto (archivos, terminal, errores, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Está especialmente orientado a desarrolladores que desean integrar modelos de lenguaje (LLMs) para mejorar su flujo de trabajo, particularmente en proyectos de tamaño mediano a grande.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cómo funciona Cline?&lt;/strong&gt;&lt;br&gt;
Cline es un complemento para VS Code que permite crear un agente personalizado impulsado por LLMs, capaz de ejecutar comandos, navegar entre archivos y mantener conversaciones contextuales. A diferencia de Continue.dev —que se enfoca principalmente en la edición y el completado de código—, Cline está orientado a establecer un flujo de trabajo interactivo bajo un enfoque agente-usuario.&lt;/p&gt;

&lt;p&gt;Con Cline puedes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chatear con un agente inteligente directamente desde el editor.&lt;/li&gt;
&lt;li&gt;Ejecutar tareas específicas mediante comandos configurables.&lt;/li&gt;
&lt;li&gt;Definir skills (habilidades) que combinan instrucciones con ejecución de código.&lt;/li&gt;
&lt;li&gt;Personalizar completamente el comportamiento del agente mediante archivos YAML.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Está pensado para usuarios avanzados que buscan automatizar flujos repetitivos o construir asistentes que no solo respondan con texto, sino que también ejecuten acciones dentro del entorno de desarrollo.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Archivo config.yaml: explicación completa&lt;/strong&gt;&lt;br&gt;
El archivo .continue/config.yaml es el núcleo de la configuración de Continue.dev. A través de este archivo puedes definir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Los modelos a utilizar: como Groq, OpenRouter u otros compatibles con Continue.&lt;/li&gt;
&lt;li&gt;El comportamiento de cada modelo: incluyendo roles, mensajes del sistema, temperatura, y otras configuraciones específicas que controlan cómo responde el modelo.&lt;/li&gt;
&lt;li&gt;El contexto que tendrá el agente: qué archivos, errores o entradas del terminal podrá leer para generar respuestas más precisas y útiles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ejemplo con Groq y OpenRouter:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipncfrr7l2dgtft4hanc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipncfrr7l2dgtft4hanc.png" alt="Config.yaml" width="800" height="772"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explicación de propiedades clave del archivo config.yaml&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name: Nombre visible del asistente o modelo en la interfaz de Continue.&lt;/li&gt;
&lt;li&gt;provider: Proveedor del modelo, como groq, openrouter, entre otros.&lt;/li&gt;
&lt;li&gt;model: Identificador del modelo específico ofrecido por el proveedor.&lt;/li&gt;
&lt;li&gt;apiKey: Clave de autenticación necesaria para conectarse con el proveedor.&lt;/li&gt;
&lt;li&gt;roles: Define las funciones que puede desempeñar el modelo, como chat, autocomplete o edit.&lt;/li&gt;
&lt;li&gt;systemMessage: Mensaje base que establece el comportamiento general del asistente (por ejemplo, su tono, propósito o enfoque).&lt;/li&gt;
&lt;li&gt;context: Determina qué fuentes de información se usarán como contexto, como archivos de código, terminal, errores, etc.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;apiBase: Dirección base para la conexión con la API, necesaria en algunos proveedores como Groq.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Limitaciones de Continue.dev&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No todos los modelos soportan todas las funciones. Por ejemplo, algunos modelos no permiten funciones como edición (edit) o autocompletado (autocomplete). En estos casos, Continue mostrará una alerta indicando qué modelo y qué rol no son compatibles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No permite entrenamiento ni afinado de modelos desde la interfaz.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Algunas integraciones pueden requerir configuración manual (por ejemplo, definir rutas o parámetros específicos).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Depende en gran medida del modelo seleccionado: si el modelo es limitado, la calidad de las respuestas también lo será.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Limitaciones de los modelos: Groq vs OpenRouter&lt;br&gt;
Groq&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Totalmente gratuito y sin necesidad de tarjeta de crédito.&lt;/li&gt;
&lt;li&gt;Modelos disponibles: LLaMA 3, Mixtral, Gemma.&lt;/li&gt;
&lt;li&gt;Ofrece alta velocidad de respuesta, ideal para flujos interactivos.&lt;/li&gt;
&lt;li&gt;Limitado a los modelos disponibles en su plataforma.&lt;/li&gt;
&lt;li&gt;No permite configuración avanzada, como ajuste fino (fine-tuning).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;OpenRouter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Funciona como un proxy que da acceso a múltiples modelos (Claude, Mistral, GPT, entre otros).&lt;/li&gt;
&lt;li&gt;Algunos modelos ofrecen un uso gratuito limitado, mientras que otros requieren pago por uso.&lt;/li&gt;
&lt;li&gt;Dispone de una versión gratuita diaria, aunque esta puede agotarse rápidamente si hay alta demanda.&lt;/li&gt;
&lt;li&gt;Mayor flexibilidad de modelos, pero con una experiencia menos homogénea según el proveedor seleccionado.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Cuando accedemos a Continue.dev dentro de Visual Studio Code, inicialmente solo contaremos con un asistente por defecto llamado "My First Assistant". Este asistente viene preconfigurado y es completamente funcional desde el primer momento.&lt;br&gt;
Además, desde el sitio web de Continue.dev, es posible seleccionar otros modelos disponibles con uso limitado gratuito, sin necesidad de configurarlos manualmente. Sin embargo, para un control total y acceso a modelos más potentes o personalizados, lo ideal es editar el archivo config.yaml como vimos anteriormente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpcmqjb2w5k3f0i0sywbq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpcmqjb2w5k3f0i0sywbq.png" alt="Continue default assistant" width="701" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En nuestro caso, crearemos un agente personalizado de manera local, el cual dependerá directamente de la configuración definida en nuestro archivo config.yaml (como se mostró en la imagen anterior).&lt;/p&gt;

&lt;p&gt;Este archivo será la clave para conectar con proveedores como Groq u OpenRouter, permitiéndonos aprovechar modelos avanzados de lenguaje de forma gratuita o bajo demanda, según el proveedor elegido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hb8x7dmz4wnpao1wvqh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hb8x7dmz4wnpao1wvqh.png" alt="Continue local assistants" width="700" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez que hayamos seleccionado y configurado los modelos que vamos a utilizar dentro de Continue.dev, deberíamos tener una vista similar a la que se muestra en la imagen superior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Con esta configuración, Continue.dev ya estará funcionando correctamente, y solo nos queda comenzar a probar sus funcionalidades: autocompletado, chat o edición, siempre y cuando el modelo seleccionado lo permita.
&lt;/h2&gt;

&lt;p&gt;Ahora continuaremos con Cline. Utilizar esta extensión es mucho más sencillo, siempre y cuando hayamos creado correctamente nuestras API keys en Groq, OpenRouter u otro proveedor de modelos.&lt;/p&gt;

&lt;p&gt;Para agregar un modelo en Cline, simplemente seleccionamos la opción "Use your own API key", y desde ahí podemos conectar el modelo que deseamos utilizar con la extensión.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9ogrsrtwqhcddqj0zoq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9ogrsrtwqhcddqj0zoq.png" alt="Cline" width="696" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si seleccionamos la opción "Get started for free", obtendremos acceso al modelo Claude 3.7 con ciertas limitaciones. Este acceso forma parte del free trial que ofrece Cline, el cual es ideal para hacer pruebas rápidas y conocer el funcionamiento de la herramienta.&lt;/p&gt;

&lt;p&gt;Una vez que se agote el periodo gratuito, podemos continuar usando Cline integrando un proveedor externo, como Groq o OpenRouter, utilizando nuestra propia API key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5uprrikmfqk7lb9pv22y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5uprrikmfqk7lb9pv22y.png" alt="Cline default settings" width="703" height="941"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recomiendo usar OpenRouter como proveedor dentro de Cline, ya que ofrece una amplia gama de modelos disponibles, como Qwen 2.5, LLaMA 3 o Gemini 2.5 Flash. Es importante tener en cuenta que la disponibilidad de estos modelos puede variar dependiendo del momento en que realices la implementación dentro de VS Code.&lt;/p&gt;

&lt;p&gt;Por lo tanto, es recomendable verificar qué modelos están accesibles al momento de configurar el agente para asegurarse de elegir el más adecuado según las necesidades del proyecto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2baodan72f43v9y8v0aj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2baodan72f43v9y8v0aj.png" alt="cline available providers" width="698" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Es importante tener en cuenta que, dado que estamos utilizando modelos opensource, la principal limitación es el tiempo de respuesta o los timeouts, especialmente debido al alto volumen de uso por parte de la comunidad.&lt;/p&gt;

&lt;p&gt;Cline está diseñado específicamente para realizar cambios en tu código, lo que lo convierte en un asistente AI. Ambas extensiones, Continue.dev y Cline, pueden ser particularmente útiles en situaciones donde no tengamos acceso a internet y estemos trabajando con un modelo alojado localmente en nuestra PC.&lt;/p&gt;

&lt;p&gt;Ahora bien, las letras pequeñas de usar un modelo local son las siguientes: deberás seleccionar un modelo que se ajuste a las especificaciones de tu computadora. Es crucial tener en cuenta los recursos de tu equipo (memoria, procesador, etc.) para evitar problemas de rendimiento.&lt;/p&gt;

&lt;p&gt;Cuando trabajamos con un modelo local, podemos integrarlo tanto a Continue.dev como a Cline, lo que nos permite aprovechar las ventajas de ambas herramientas incluso sin conexión a internet.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>continue</category>
      <category>cline</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Internacionalización en Aplicaciones React con i18next</title>
      <dc:creator>Johan Garcia</dc:creator>
      <pubDate>Sat, 18 Jan 2025 22:53:57 +0000</pubDate>
      <link>https://dev.to/devjohanadrian/internacionalizacion-en-aplicaciones-react-con-i18next-286k</link>
      <guid>https://dev.to/devjohanadrian/internacionalizacion-en-aplicaciones-react-con-i18next-286k</guid>
      <description>&lt;p&gt;Cada dia  el mundo esta conectado, ofrecer contenido accesible en múltiples idiomas se ha convertido en una necesidad fundamental para aplicaciones modernas. En este artículo, abordaremos cómo implementar internacionalización en aplicaciones React utilizando i18next, una biblioteca flexible y poderosa para la gestión de traducciones.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;¿Qué es la internacionalización de aplicaciones web?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Con la internacionalización (i18n) damos la capacidad a nuestras aplicaciones de ser adaptables a diferentes idiomas y regiones sin la necesidad de realizar cambios en su código fuente.&lt;/p&gt;

&lt;p&gt;Esto incluye la traducción de textos, la adaptación de formatos de fecha, moneda, números y cualquier otro aspecto que varíe según la localización cultural de los usuarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;¿Qué es i18next y por qué utilizarlo?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;i18next es una solución popular de internacionalización que simplifica la gestión de traducciones en aplicaciones web, móviles y de escritorio. Ofrece soporte para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Carga dinámica de idiomas.&lt;/li&gt;
&lt;li&gt;Interpolación de variables en textos.&lt;/li&gt;
&lt;li&gt;Gestor de recursos centralizado para traducciones.&lt;/li&gt;
&lt;li&gt;Cambio de idioma en tiempo real.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Existen otras opciones a i18next, como lo son react-intl, LinguiJS, Polyglot.js, MessageFormat.js y Globalize, pero nos centraremos en i18next, ya que es una librería muy popular, cuenta con un buen número de descargas semanales en npm.js y destaca por su simplicidad a la hora de ser configurada en una aplicación de React.js.&lt;/p&gt;

&lt;p&gt;A lo largo de este artículo, exploraremos cómo configurar y utilizar i18next en una aplicación React paso a paso.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Instalación y configuración&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Comenzaremos instalando i18next junto con su paquete adaptador para React:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwyrypo53d3gj1jp7ksy3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwyrypo53d3gj1jp7ksy3.png" alt="npm install" width="744" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una vez instalados los paquetes necesarios para la configuración de i18next, configuraremos la instancia principal de i18next en un archivo dedicado, por ejemplo, i18n.js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3luzdiyslrfu6kxwfjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3luzdiyslrfu6kxwfjr.png" alt="i18n.js." width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora crearemos los archivos que van a contener nuestras traducciones (es.json y en.json). Para ello, crearemos una carpeta en la raíz de nuestro proyecto React.js llamada locale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnbtu0elxs36w4mtdofaw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnbtu0elxs36w4mtdofaw.png" alt="folder tree" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;es.JSON&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpk0hbxbmxdo37fy0hag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpk0hbxbmxdo37fy0hag.png" alt="es.JSON" width="744" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;en.JSON&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F590vms14xzka5bp4e8ma.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F590vms14xzka5bp4e8ma.png" alt="en.JSON" width="744" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Configurar el proveedor global&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Para que las traducciones sean accesibles en toda la aplicación, envolveremos el componente principal con el proveedor I18nextProvider. Este paso se realiza en el archivo principal, como index.jsx.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq93tk6iy5suewpz7irek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq93tk6iy5suewpz7irek.png" alt="index.jsx" width="735" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con esta configuración, todas las traducciones estarán disponibles en los componentes React.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Uso en componentes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Para traducir textos en los componentes, utilizaremos el hook useTranslation que proporciona react-i18next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu05ny9bvci80r3wi9ela.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu05ny9bvci80r3wi9ela.png" alt="Uso en componentes" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En este ejemplo, t es la función que busca las traducciones en el idioma actual.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cambiar de idioma&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Podemos implementar una funcionalidad para cambiar el idioma de la aplicación en tiempo real utilizando el método changeLanguage de la instancia de i18next:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F223eblaks6p1j0d3hh1f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F223eblaks6p1j0d3hh1f.png" alt="changinglanguage" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con esto, los usuarios podrán alternar entre idiomas sin recargar la aplicación.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusión&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;En este artículo, hemos explorado los fundamentos para implementar internacionalización con i18next en una aplicación React. Hemos configurado el entorno para que funcione con I18nextProvider, pero existen enfoques diferentes, como Context API o HOC (Higher-Order Component). Si desean explorar estos acercamientos, pueden consultarlos en la documentación de &lt;a href="https://react.i18next.com/" rel="noopener noreferrer"&gt;react-i18next.&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Rutas relativas y absolutas en programación</title>
      <dc:creator>Johan Garcia</dc:creator>
      <pubDate>Mon, 13 Jan 2025 22:36:45 +0000</pubDate>
      <link>https://dev.to/devjohanadrian/rutas-relativas-y-absolutas-en-programacion-15nh</link>
      <guid>https://dev.to/devjohanadrian/rutas-relativas-y-absolutas-en-programacion-15nh</guid>
      <description>&lt;p&gt;Una ruta es el método mediante el cual podemos referenciar un recurso o directorio en un sistema de archivos dentro de un sistema operativo. Teniendo esto claro, ¿por qué es importante conocer más sobre las rutas? Porque estas te ayudan a evitar errores y a referenciar de forma exacta los recursos o directorios necesarios para ser utilizados en nuestras aplicaciones.&lt;/p&gt;

&lt;p&gt;Al saber indicar la localización exacta de un archivo o directorio mediante una cadena de caracteres, podemos trabajar de manera más eficiente y precisa.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Árbol de directorios&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Antes de continuar, es importante definir un término clave para entender las rutas absolutas y relativas: el árbol de directorios. Este concepto representa una estructura jerárquica de directorios y archivos en un sistema operativo. Es un enfoque común cuando trabajamos directamente con sistemas de archivos, exploradores de carpetas o comandos de terminal, y es independiente de una aplicación específica.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concepto del Árbol de Rutas&lt;/strong&gt;&lt;br&gt;
Un sistema de archivos está organizado en una estructura de árbol, donde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cada nodo es un directorio o un archivo.&lt;/li&gt;
&lt;li&gt;El nodo raíz (/ en sistemas basados en UNIX o una unidad como C:\ en Windows) es el punto de inicio.&lt;/li&gt;
&lt;li&gt;Cada rama conecta un directorio con sus subdirectorios o archivos.&lt;/li&gt;
&lt;li&gt;Cada archivo o directorio tiene una ruta única que describe su posición en el árbol.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Estructura Jerárquica del Árbol&lt;/strong&gt;&lt;br&gt;
La estructura típica de un árbol de rutas en un sistema operativo puede representarse como:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6dhh1n2n8e4pke6imd9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6dhh1n2n8e4pke6imd9y.png" alt="Estructura Jerárquica del Árbol" width="800" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dentro de este árbol de directorios se encuentran las rutas absolutas y relativas, que es lo que veremos a continuación.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rutas Absolutas&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Comienzan desde el directorio raíz (/ en sistemas basados en UNIX o C:\ en Windows).&lt;/li&gt;
&lt;li&gt;Proporcionan la localización completa del archivo o directorio en el sistema.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ejemplos&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En UNIX: /home/user/documents/file1.txt&lt;/li&gt;
&lt;li&gt;En Windows: C:\Users\User\Documents\file1.txt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Rutas Relativas&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se definen en relación con el directorio actual.&lt;/li&gt;
&lt;li&gt;Ejemplo: Si estás en /home/user, la ruta relativa a file1.txt sería documents/file1.txt.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Rutas&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Existen dos formas de expresar una ruta, su forma relativa y su forma absoluta que cumplen funciones distintas, en su mayoria las rutas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rutas Relativas&lt;/strong&gt;&lt;br&gt;
Una ruta relativa indica la ubicación de un archivo o recurso en relación con el directorio actual, o lo que sería lo mismo, la posición en la que nos encontramos dentro del sistema operativo (o el contexto actual). Estas rutas son más flexibles y se utilizan para acceder a archivos más cercanos o relacionados con la misma jerarquía de directorios en la que estamos trabajando.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referenciación&lt;/strong&gt;&lt;br&gt;
Utilizaremos . para referenciar el directorio actual. Es útil para referirse a archivos o subdirectorios dentro del mismo directorio donde estás ubicado.&lt;/p&gt;

&lt;p&gt;Utilizaremos .. para referenciar al directorio padre. Representa el directorio inmediatamente superior al actual.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplos&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;../file.txt se refiere a file.txt en el directorio padre.&lt;/li&gt;
&lt;li&gt;../../anotherfile.txt retrocede dos niveles en la jerarquía y busca el archivo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tomaremos este directorio como ejemplo para explicar el uso de rutas relativas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft08h3mlxjkqyi6nwb71l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft08h3mlxjkqyi6nwb71l.png" alt="Directorio de ejemplo" width="570" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Supongamos que estamos trabajando dentro de Header.js y queremos utilizar las funcionalidades que se encuentran en helpers.js. Haríamos referencia de la siguiente forma:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07mlsz0o7ik5hg6r38fl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07mlsz0o7ik5hg6r38fl.png" alt="Importacion de recursos" width="744" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Las ventajas de utilizar las rutas relativas son que no requieren un conocimiento completo de la estructura global del árbol de directorios.&lt;/p&gt;

&lt;p&gt;Una desventaja sería utilizarlas en proyectos grandes, donde puede ser difícil mantener rutas que son especialmente largas, como (../../../).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rutas Absolutas&lt;/strong&gt;&lt;br&gt;
Una ruta absoluta indica o señala la ubicación completa de un archivo, recurso o directorio desde la raíz del sistema de archivos. Estas rutas son independientes del directorio actual, más claras y explícitas sobre la ubicación del recurso. Además, pueden ser configuradas en algunos entornos, como TypeScript o Webpack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo&lt;/strong&gt;&lt;br&gt;
Si no estuviéramos trabajando con TypeScript o Webpack, haríamos uso de la raíz de nuestro árbol de archivos para ubicarnos en el recurso que necesitáramos (por ejemplo: C:\usuarios\usuario1\project\src\utils\helpers).&lt;/p&gt;

&lt;p&gt;Sin embargo, en este caso estaremos utilizando TypeScript y haremos uso de baseUrl en tsconfig.json para configurar una URL base desde la cual podemos partir al utilizar rutas absolutas dentro de nuestro proyecto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85buxgsmvjxbcuds00pe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85buxgsmvjxbcuds00pe.png" alt="Directorio de ejemplo con tsconfig" width="640" height="708"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ahora continuaremos con la configuración de nuestro &lt;strong&gt;tsconfig.json&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq3i4jz359e3vr04bopi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq3i4jz359e3vr04bopi.png" alt="Configuracion de tsconfig" width="744" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Con esta configuración dentro de TypeScript y tsconfig.json, podremos utilizar los alias en nuestras rutas absolutas sin necesidad de referenciar todo el árbol de rutas existente (C:\usuarios\usuario1\project\src\utils\helpers), lo que evitará definir rutas extensas y difíciles de mantener, o el uso de rutas relativas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusión&lt;/strong&gt;&lt;br&gt;
Es esencial que comprendamos el árbol de directorios y las diferencias entre las rutas relativas y absolutas, ya que este conocimiento facilitará enormemente la navegación y gestión de archivos en cualquier sistema operativo o entorno de desarrollo. Las rutas absolutas les ofrecen una referencia precisa y clara a archivos y directorios, lo que asegura que siempre puedan acceder a ellos sin depender del directorio en el que se encuentren. Por otro lado, las rutas relativas son ideales para trabajar dentro del mismo contexto o proyecto, proporcionando flexibilidad y simplicidad.&lt;/p&gt;

&lt;p&gt;Saber cuándo y cómo utilizar cada tipo de ruta no solo mejora la organización de sus proyectos, sino que también optimiza la mantenibilidad y reduce los errores relacionados con la ubicación de recursos. En proyectos grandes, las rutas absolutas y los alias bien configurados pueden simplificar las referencias y hacer que el código sea más limpio y fácil de comprender.&lt;/p&gt;

&lt;p&gt;Entender estos conceptos es crucial para mejorar la eficiencia y precisión al trabajar con archivos y al desarrollar aplicaciones, garantizando un flujo de trabajo más ágil y un código más robusto.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Si el proyecto es pequeño o no quieres modificar configuraciones, usa rutas relativas.&lt;/li&gt;
&lt;li&gt;Si trabajas en un proyecto grande o quieres mejorar la claridad del código, configura rutas absolutas.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
