Desde nuestra área de QSO, estamos constantemente explorando las tecnologías y herramientas más disruptivas. A lo largo de 2023, hemos sido testigos de la irrupción de la inteligencia artificial de manera tan impactante, que no podíamos dejar pasar la ocasión de ver cómo la IA nos ha afectado.

Al iniciar la redacción de este post, reflexioné sobre la mejor manera de abordar la tarea, y llegué a la conclusión de que ChatGPT, usando cualquiera de las versiones actuales de su motor, ejemplificaría cómo la inteligencia artificial potencia la interacción entre seres humanos y máquinas, brindando una experiencia fluida y adaptada. Aun así, estamos en un momento prematuro de este tipo de IA, por lo que, como usuarios de la misma, siempre tenemos que ser críticos con sus respuestas, ya que es frecuente encontrarse con respuestas erróneas o poco coherentes. Además, muestra sensibilidad a sutiles variaciones en las entradas puede hacer que tienda a enfangarse más de la cuenta en ocasiones. Por tanto, sería prudente emplear ChatGPT o cualquier interfaz similar con cautela y un poco de sentido común.

La inteligencia artificial, la IA generativa y los modelos de lenguaje son conceptos interrelacionados, pero distintos en el ámbito de la tecnología. La IA se refiere a la simulación de procesos de inteligencia humana por parte de máquinas, mientras que la IA generativa se basa en la creación de contenido original y nuevo por parte de las máquinas. De modo que la IA tradicional puede estar diseñada para realizar tareas específicas con datos predefinidos y la IA generativa busca generar datos, como texto, imágenes, música u otros tipos de contenido, de manera autónoma y creativa. Por otro lado, los modelos de lenguaje son un caso particular de IA generativa, capaces de comprender y generar texto de forma natural. Los modelos de lenguaje avanzados parecen comprender el contexto, pero su funcionamiento se basa en predecir palabras siguiendo patrones predefinidos

Indudablemente, uno de los ejemplos más notables es ChatGPT. Su impacto en nuestras vidas ha sido asombroso, atrayendo a millones de usuarios desde su inicio y superando en crecimiento incluso a plataformas como Instagram. En tan solo 40 días desde su lanzamiento, ChatGPT logró cautivar a más de 10 millones de usuarios diarios, que aprovecharon su capacidad para responder preguntas en diversos campos. La versatilidad de ChatGPT lo convierte en una herramienta valiosa para mejorar la calidad en diferentes áreas. Su capacidad para generar contenido relevante y coherente puede ser utilizada en multitud de campos de todo tipo y como no, en el desarrollo de software, su habilidad para sugerir líneas de código podría acelerar el proceso de creación y optimización.

Áreas clave del desarrollo de software con IA generativa enfocadas a calidad

No obstante, centrémonos en lo que verdaderamente nos concierne en este post: ¿cómo podemos aprovechar esta tecnología en el ámbito de la calidad?

La aplicación de la IA generativa en el ámbito de la calidad de software se puede aprovechar en tres áreas claves, tal y como la entendemos desde QSO:

En resumen, la integración de la IA generativa en la calidad del software impacta positivamente en la definición de los requerimientos funcionales, potencia la productividad del equipo de desarrollo y mejora la validación exhaustiva de tareas, consolidando así la excelencia en todo el proceso de desarrollo de software.

Requerimientos funcionales

En este ámbito, una herramienta que empleamos de manera recurrente son las sesiones de refinamiento, conocidas como ’3 amigos’. Estas reuniones culminan con la necesidad de tener una comprensión precisa sobre el objetivo de nuestras tareas, junto con criterios de aceptación exhaustivos. En este contexto inicial, existe una oportunidad para recurrir a la inteligencia artificial como un recurso que facilite la creación de casos de uso y, a partir de estos, la formulación de nuestras pruebas. Para ilustrar este enfoque, consideremos un ejemplo concreto.

Supongamos que estamos diseñando una web que tiene un formulario de registro sencillo con 5 campos: nombre, apellidos, teléfono, email y dirección. No nos engañemos, muchas veces, esta es toda la información que tenemos para un caso como este. Hagámosle la pregunta a la IA:

— Pregunta:

Dado un formulario de html con 5 campos. Nombre, apellidos, email, teléfono y dirección. Quiero generar un set de casos de prueba que cumpla toda la funcionalidad

— Respuesta:

Generar un conjunto completo y exhaustivo de casos de prueba puede ser un proceso complejo y depende en gran medida de la funcionalidad específica que quieras probar en tu formulario HTML. Sin embargo, aquí te proporcionaré un conjunto básico de casos de prueba que abarca diversas situaciones comunes que podrían ser relevantes para un formulario como el que describiste.
Supongamos que tienes un formulario con los siguientes campos: Nombre, Apellidos, Email, Teléfono y Dirección. Y deseas probar funcionalidades como validaciones, envío de datos, etc. Aquí tienes un conjunto de casos de prueba que podrías considerar:

Caso de prueba de campos vacíos:

Caso de prueba de campos obligatorios:

Caso de prueba de longitud máxima:

Caso de prueba de formato de email:

Caso de prueba de formato de teléfono:

Caso de prueba de dirección válida:

Caso de prueba de dirección inválida:

Caso de prueba de entrada válida:

Caso de prueba de límites de entrada:

Caso de prueba de caracteres especiales:

Caso de prueba de campo de email único:

Caso de prueba de validación exitosa:

———————

A medida que se le va dando más información al intérprete, la respuesta tendrá cada vez mayor sentido y se podrá aproximar más a lo que estábamos buscando.

— Pregunta:

Dado un formulario de html con 5 campos. Nombre, apellidos, email, teléfono y dirección. Quiero generar un set de casos de prueba que cumpla toda la funcionalidad. Nombre, apellidos y email son campos obligatorios. El resto son opcionales. Hay 2 botones, uno para enviar y otro para limpiar el formulario y empezar de nuevo. Al enviar el formulario, se le notifica por mail al usuario y en la navegación el usuario llega a una pantalla donde se le indica que revise el correo

— Respuesta:

Entendido, estás buscando un conjunto completo de casos de prueba que cubran todas las funcionalidades de tu formulario HTML. Aquí tienes un conjunto amplio de casos de prueba que abarcan los escenarios que has mencionado:

  1. Enviar el formulario con todos los campos en blanco.
  2. _Enviar el formulario con el nombre y apellidos en blanco.
  3. Enviar el formulario con el nombre, apellidos y email en blanco.
  4. Enviar el formulario con el nombre, apellidos y dirección en blanco.
  5. Enviar el formulario con el nombre, apellidos, email y teléfono en blanco.
  6. Enviar el formulario con el nombre, apellidos, teléfono y dirección en blanco.
  7. Enviar el formulario con el nombre, apellidos, email y dirección en blanco.
  8. Enviar el formulario con el email en blanco.
  9. Enviar el formulario con el email y dirección en blanco.
  10. Enviar el formulario con el email y teléfono en blanco.
  11. Enviar el formulario con el email, teléfono y dirección en blanco.

Campos Opcionales:

  1. Enviar el formulario con todos los campos completos.
  2. Enviar el formulario con el nombre, apellidos, email y teléfono completos.
  3. Enviar el formulario con el nombre, apellidos, email y dirección completos.
  4. Enviar el formulario con el nombre, apellidos, teléfono y dirección completos.
  5. Enviar el formulario con el nombre, apellidos, email, teléfono y dirección completos.

Botones:

  1. Llenar el formulario y hacer clic en el botón "Enviar".
  2. Llenar el formulario y hacer clic en el botón "Limpiar".

Notificación por Correo Electrónico:

  1. Enviar el formulario y verificar que se reciba una notificación por correo electrónico al usuario.
  2. Navegación a la Pantalla de Revisión:
  3. Después de enviar el formulario, verificar que la navegación lleve al usuario a la pantalla de revisión en la que se le indique que revise su correo electrónico.

———————

¿Qué ocurre si ahora queremos trabajar con un modelo de lenguaje como BDD? Este nos servirá como punto de partida para nuestras automatizaciones de pruebas:

— Pregunta:

¿Puedes traducir estos casos de prueba al modelo de lenguaje BDD, con sentencias Given, When, Then en español?

— Respuesta:

Funcionalidad: Validación de Campos Obligatorios

Funcionalidad: Campos Opcionales

Funcionalidad: Botones

Funcionalidad: Notificación por Correo Electrónico

Funcionalidad: Navegación a la Pantalla de Revisión

Estos escenarios utilizan la estructura Given-When-Then para describir las condiciones, las acciones y los resultados esperados en cada caso de prueba. Asegúrate de adaptarlos según las características y el comportamiento específico de tu formulario.

———————

Podemos decir que en este primer escenario hemos podido generar partiendo de una definición de un requisito una serie de criterios de aceptación, pruebas útiles. Como condición, cuanto mayor sea el grado de detalle, mayor debería ser el acierto de la IA a la hora de definir los casos.

Desarrollo

En este punto es importante tener en cuenta que se debe conocer muy bien la funcionalidad que se está llevando a cabo. Y la incorporación de una IA de lenguaje como ChatGPT para optimizar la creación de pruebas unitarias constituye un enfoque prometedor. Al centrarnos en un escenario concreto para generar los test unitarios se podrían seguir los siguientes pasos:

Podemos empezar pidiéndole que nos sugiera los test unitarios que se podrían implementar en nuestro caso:

— Pregunta:

¿Podrías ponerme algún ejemplo en python de test unitarios para el formulario de antes?

— Respuesta:

¡Por supuesto! Aquí tienes algunos ejemplos de cómo podrían ser implementados los casos de prueba unitarios en Python utilizando el framework de pruebas unittest:

import unittest

# Supongamos que tienes una clase llamada 'Formulario' que contiene la lógica del formulario

lass TestFormulario(unittest.TestCase):

    def test_campos_obligatorios_completos(self):
        formulario = Formulario()
        resultado = formulario.enviar_formulario('Nombre', 'Apellidos', 'correo@example.com', None, None)
        self.assertTrue(resultado)

    def test_campos_obligatorios_incompletos(self):
        formulario = Formulario()
        resultado = formulario.enviar_formulario('Nombre', 'Apellidos', None, None, None)        
        self.assertFalse(resultado)
    
    def test_limpiar_formulario(self):
        formulario = Formulario()
        formulario.llenar_campos('Nombre', 'Apellidos', 'correo@example.com', '123456789', 'Dirección')
        formulario.limpiar_formulario()
        self.assertEqual(formulario.nombre, '')
        self.assertEqual(formulario.apellidos, '')
        self.assertEqual(formulario.email, '')
        self.assertEqual(formulario.telefono, '')
        self.assertEqual(formulario.direccion, '')
  
    def test_correo_enviado(self):
        formulario = Formulario()
        formulario.llenar_campos('Nombre', 'Apellidos', 'correo@example.com', None, None)
        resultado = formulario.enviar_formulario()
        self.assertTrue(resultado)
        self.assertTrue(formulario.correo_enviado)
  
    def test_redireccion_pantalla_confirmacion(self):
        formulario = Formulario()
        formulario.llenar_campos('Nombre', 'Apellidos', 'correo@example.com', None, None)
        resultado = formulario.enviar_formulario()
        self.assertTrue(resultado)
        self.assertEqual(formulario.pantalla_actual, 'Confirmacion')
  
if __name__ == '__main__':
    unittest.main()

Estos son ejemplos simplificados y genéricos de cómo podrías estructurar tus pruebas unitarias utilizando unittest en Python. Recuerda que debes adaptar estos ejemplos a la estructura y lógica específica de tu código y tu formulario.

———————

La respuesta no siempre es perfecta. De hecho, a menudo es mejorable por el propio usuario, pero sirve como punto de partida para tener en cuenta ciertos casos que posiblemente no se hubieran tenido en cuenta. En nuestro caso queremos seguir profundizando y dando mayor calidad a nuestros test unitarios. Y una manera de mejorar nuestros test es teniendo en cuenta que se pueden pasar unos test de mutación. Vamos a pedirle a nuestro intérprete que nos oriente en este sentido:

— Pregunta:

Teniendo estos test unitarios, quiero pasar un framework de test de mutación, para poder validar la calidad de mis tests. ¿Cómo mejorarías estos test para pasar la mayor cantidad de test de mutación posible?

— Respuesta:

Por supuesto! Para mejorar la capacidad de tus pruebas unitarias para superar pruebas de mutación, aquí tienes algunas estrategias:

  1. Pruebas más Finas:
    Divide tus casos de prueba en unidades más pequeñas y específicas. Esto permite que las mutaciones afecten de manera más precisa las partes individuales del código que deseas probar.
  2. Utiliza Asertos Más Detallados:
    Utiliza asertos específicos para las condiciones que estás probando. Por ejemplo, en lugar de simplemente verificar si algo es verdadero o falso, verifica condiciones específicas dentro de tus objetos o estructuras de datos.
  3. Cubre todos los Ramales Lógicos:
    Asegúrate de que tus casos de prueba cubran todas las ramas lógicas del código. Esto incluye diferentes caminos que pueden tomarse en función de condiciones, bucles, etc.
  4. Pruebas de Equivalencia:
    Proporciona casos de prueba que representen diferentes clases de equivalencia de entrada. Por ejemplo, para un campo de entrada de número, prueba con valores negativos, cero y positivos.
  5. Pruebas de Valores Límite:
    Agrega casos de prueba que prueben los valores límite y los valores justo fuera de los límites. Esto ayuda a asegurarte de que tu código maneje correctamente condiciones límite.
  6. Pruebas de Cobertura:
    Asegúrate de tener una alta cobertura de código con tus pruebas. Cuanto más código cubras, más oportunidades habrá para detectar mutaciones.
  7. Proporciona Comentarios Descriptivos:
    Agrega comentarios detallados en tus casos de prueba para indicar qué aspectos específicos del código están siendo probados. Esto ayuda a que las herramientas de mutación enfoquen sus cambios en esas áreas.
  8. Refactoriza tus Pruebas:
    Asegúrate de que tus pruebas estén limpias y sean fáciles de entender. Esto no solo ayuda a la legibilidad, sino que también facilita la detección de mutaciones.
  9. Utiliza Datos de Prueba Variados:
    Proporciona una variedad de datos de prueba en diferentes formatos y tamaños. Esto aumenta las posibilidades de que las mutaciones afecten los valores de entrada.
  10. Pruebas Negativas:
    Agrega pruebas que intenten forzar el fracaso del código, por ejemplo, proporcionando entradas inválidas o incorrectas.

Al seguir estas estrategias, puedes aumentar la probabilidad de que tus pruebas unitarias sean robustas frente a las mutaciones, lo que a su vez mejora la calidad de tus pruebas y la detección de posibles errores en tu código.

———————

Es importante saber lo que se está haciendo, como para ser capaces de decidir si la solución planteada es válida o no. En este punto, el desarrollador puede tener una mente mucho más abierta y creativa y proponer diferentes soluciones para un mismo problema. Sin embargo, parece un buen punto de partida el seguir las orientaciones dadas por el asistente.

Validación de tareas

Hasta este momento, contamos con una base sólida establecida por los casos en BDD, los test unitarios y las recomendaciones de los test de mutación. A partir de esta base, procedamos a consultar a nuestra IA para que nos ayude a generar una tabla de casos de prueba basados en la información que tenemos previamente. Además, nos interesa asignarle una severidad a cada caso.

— Pregunta:

A partir del BDD anterior quiero generar casos de prueba en una tabla que tenga los siguientes campos:

— Respuesta:

Aquí tienes los escenarios BDD que proporcioné anteriormente convertidos en casos de prueba con los campos que mencionaste: Nombre del caso de prueba, Descripción del caso de prueba, Pasos, Resultado y Severidad.

Nombre del caso de prueba Descripción del caso de prueba Pasos Resultado Severidad
CP1 Enviar formulario con campos en blanco Dado que un usuario desea enviar un formulario con campos obligatorios. Cuando el usuario intenta enviar el formulario con todos los campos en blanco. Se muestra un mensaje de error indicando que el nombre es obligatorio. Alta
CP2 Enviar formulario con nombre y apellidos en blanco Dado que un usuario desea enviar un formulario con campos obligatorios. Cuando el usuario intenta enviar el formulario con el nombre y apellidos en blanco. Se muestran mensajes de error indicando que el nombre y apellidos son obligatorios. Alta
CP3 Enviar formulario con nombre, apellidos y email en blanco Dado que un usuario desea enviar un formulario con campos obligatorios. Cuando el usuario intenta enviar el formulario con el nombre, apellidos y email en blanco. Se muestran mensajes de error indicando que el nombre, apellidos y email son obligatorios. Alta
CP4 Enviar formulario con todos los campos completos Dado que un usuario desea enviar un formulario con campos opcionales. Cuando el usuario envía el formulario con todos los campos completos. El formulario se envía exitosamente. Media
CP5 Enviar formulario con nombre, apellidos, email y teléfono completos Dado que un usuario desea enviar un formulario con campos opcionales. Cuando el usuario envía el formulario con el nombre, apellidos, email y teléfono completos. El formulario se envía exitosamente. Media
CP6 Enviar formulario y hacer clic en el botón "Enviar" Dado que un usuario desea interactuar con los botones del formulario. Cuando el usuario llena el formulario y hace clic en el botón "Enviar". El formulario se envía. Baja
CP7 Llenar formulario y hacer clic en el botón "Limpiar" Dado que un usuario desea interactuar con los botones del formulario. Cuando el usuario llena el formulario y hace clic en el botón "Limpiar". Todos los campos del formulario se borran. Baja
CP8 Enviar formulario y verificar notificación por correo electrónico Dado que un usuario ha enviado el formulario y espera una notificación por correo electrónico. Cuando el usuario envía el formulario. Se recibe una notificación por correo electrónico. Media
CP9 Verificar navegación a pantalla de revisión Dado que un usuario ha enviado el formulario y debe revisar su correo electrónico. Cuando el usuario envía el formulario y sigue las instrucciones para revisar su correo electrónico. La navegación lleva al usuario a una pantalla de revisión que indica que debe revisar su correo electrónico. Baja

Estos casos de prueba cubren los diferentes escenarios que describiste en tu BDD. Puedes ajustar los detalles según las necesidades y características específicas de tu aplicación. La columna de "Severidad" indica la importancia relativa de cada caso de prueba.

———————

El siguiente paso que queremos dar es en la dirección de darle más profundidad a los casos. Queremos llegar un poco más allá. Sobre todo queremos tener algún caso de prueba de seguridad y nos preocupa cumplir con los estándares de accesibilidad.

— Pregunta:

¿Puedes generar más casos de prueba? y añadir además alguno relacionado con seguridad, validación xhtml y cumplimiento del estándar AA en cuanto a accesibilidad

— Respuesta:

Nombre del caso de prueba Descripción del caso de prueba Pasos Resultado Severidad
CP10 Enviar formulario con caracteres especiales en el nombre Dado que un usuario desea enviar un formulario con campos opcionales. Cuando el usuario envía el formulario con un nombre que contiene caracteres especiales. El formulario se envía exitosamente y los caracteres especiales se manejan correctamente. Media
CP11 Enviar formulario con número de teléfono inválido Dado que un usuario desea enviar un formulario con campos opcionales. Cuando el usuario envía el formulario con un número de teléfono en un formato incorrecto. Se muestra un mensaje de error indicando que el número de teléfono es inválido. Alta
CP12 Intento de inyección de SQL en el campo de dirección Dado que un usuario desea enviar un formulario con campos opcionales. Cuando el usuario intenta introducir un código malicioso de inyección de SQL en el campo de dirección. Se bloquea el intento de inyección de SQL y se muestra un mensaje de error. Alta
CP13 Validación XHTML del formulario Dado que se quiere asegurar la validez del XHTML en el formulario. Cuando se verifica el código fuente HTML del formulario con un validador XHTML. El validador XHTML no muestra errores y el código es válido. Media
CP14 Cumplimiento de estándar de accesibilidad nivel AA Dado que se busca cumplir con el estándar de accesibilidad nivel AA. Cuando se evalúa el formulario utilizando una herramienta de auditoría de accesibilidad para verificar el cumplimiento del estándar AA. La herramienta no muestra errores de nivel AA y el formulario cumple con este estándar. Alta

———————

Y podríamos estar así todo el día, añadiendo diferentes casuísticas, por ejemplo pruebas de bases de datos, pruebas a nivel del servicio o eventos que se consumen, pruebas de rendimiento, etc. Las posibilidades son infinitas.

Sin embargo, hay una parte importante a la hora de afrontar las pruebas y que es la que más a menudo suele dar problemas antes o después. El set de datos de pruebas que se va a usar. Para nuestro caso sencillo, podemos tener en un criterio escrito los tipos de usuarios que se van a poder logar, los que van a poder solicitar una cuenta, si un usuario ha sido dado de baja, etc.:

— Pregunta:

Para este formulario necesito saber las diferentes casuísticas que voy a necesitar en base a los siguientes criterios: Puede haber usuarios dados de alta que acceden a la app - Puede haber usuarios que estando dados de alta aún no hayan activado su cuenta - etc. Por favor sé creativo con los criterios más normales y genera una lista de los diferentes tipos de usuarios que voy a necesitar pedir al equipo de desarrollo

— Respuesta:

¡Por supuesto! Aquí tienes una lista de diferentes tipos de usuarios que podrías considerar para tu aplicación basándote en los criterios que mencionaste:

  1. Usuarios Dados de Alta y Activados:
    _Usuarios que se han registrado en la aplicación y han activado su cuenta mediante un proceso de verificación por correo electrónico.
  2. Usuarios Dados de Alta pero No Activados:
    Usuarios que se han registrado en la aplicación pero aún no han activado su cuenta. Necesitarán completar el proceso de activación a través de un enlace enviado por correo electrónico.
  3. Usuarios Inactivos:
    Usuarios que se registraron y activaron su cuenta en el pasado, pero no han interactuado con la aplicación durante un tiempo prolongado.
  4. Usuarios Administradores:
    Usuarios con permisos elevados que tienen acceso a funciones de administración y gestión en la aplicación.
  5. Usuarios Premium o de Pago:
    Usuarios que han adquirido una suscripción premium o realizan pagos por características adicionales.
  6. Usuarios Anónimos:
    Usuarios que navegan por la aplicación sin estar autenticados. Pueden tener un acceso limitado a ciertas áreas.
  7. Usuarios Nuevos:
    Usuarios que han creado una cuenta recientemente y están explorando la aplicación por primera vez.
  8. Usuarios de Soporte:
    Usuarios que proporcionan soporte a otros usuarios. Pueden tener acceso a funciones adicionales para ayudar a resolver problemas.
  9. Usuarios con Perfiles Completos:
    Usuarios que han llenado todos los campos de su perfil, incluyendo nombre, foto, dirección, etc.
  10. Usuarios con Perfiles Incompletos:
    Usuarios que se han registrado pero no han proporcionado toda la información requerida en su perfil.
  11. Usuarios con Historial de Compras:
    Usuarios que han realizado compras o transacciones en la aplicación en el pasado.
  12. Usuarios con Carritos Abandonados:
    Usuarios que agregaron productos al carrito de compras pero no completaron la compra.
  13. Usuarios con Interacciones Recientes:
    Usuarios que han interactuado con la aplicación en los últimos días, como haber realizado una compra o haber dejado comentarios.
  14. Usuarios con Sesiones Activas:
    Usuarios que están actualmente conectados a la aplicación y tienen una sesión activa.
  15. Usuarios con Acceso Limitado:
    Usuarios que tienen restricciones de acceso a ciertas funcionalidades debido a su nivel de suscripción o permisos.
  16. Usuarios con Accesibilidad Requerida:
    Usuarios que utilizan tecnologías de asistencia y necesitan una experiencia de usuario accesible de acuerdo con los estándares.
  17. Usuarios con Historial de Problemas:
    Usuarios que han tenido problemas técnicos en el pasado y han interactuado con el equipo de soporte.
  18. Usuarios que Utilizan Múltiples Dispositivos:
    Usuarios que acceden a la aplicación desde diferentes dispositivos, como computadoras, tabletas y teléfonos móviles.
  19. Usuarios que Interactúan con Notificaciones:
    Usuarios que responden a notificaciones push o correos electrónicos enviados por la aplicación.
  20. Usuarios con Preferencias de Privacidad:
    Usuarios que han configurado sus preferencias de privacidad y datos personales en la aplicación.
  21. Usuarios que Comparten Contenido:
    Usuarios que comparten contenido de la aplicación en redes sociales u otras plataformas.

———————

Conclusión

Se puede afirmar que el impacto en la tecnología, proporcionado por los motores de IA es innegable en lo que respecta a la calidad. Su capacidad para abordar diversas tareas y su potencial para asistir en la mejora continua convierten a esta herramienta en un recurso valioso en la búsqueda de la excelencia en varios campos.

En el ámbito de la calidad, esta herramienta puede ser aprovechada en todas las áreas del proceso de desarrollo e incluso en la fase de validación, de manera que abarca el ciclo completo de cómo comprendemos la calidad según el círculo de QSO. Es importante considerar que estas soluciones raras veces son perfectas y, por lo general, siempre se pueden mejorar. No obstante, son un recurso excelente para tomar como punto de partida para refinamientos, casos de prueba o automatizaciones.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.