Testabilidad es un concepto que nace con ASIC (industria de semiconductores) como un proceso que incorpora reglas y técnicas en el diseño de un producto para facilitar su testeo.

Inicios de la Industria de semiconductores

En los inicios de la industria de semiconductores, las empresas desarrollaban el semiconductor y delegaban el testing a otras empresas o al cliente, que encontraba fallas en los productos generando una alta tasa de devoluciones, fallas y quejas.

Por otra parte, en la industria de la tecnología, el time to market es muy valioso (quien consiga entregar productos de calidad en un tiempo corto de desarrollo tiene mayor ventaja competitiva) y diseñar y fabricar el producto para luego enviarlo a un tercero que lo probara, significaba un retraso de 6 meses en el lanzamiento al mercado como podemos observar en este documento.

 

También se requería hardware especial y complejo (ATE automatic test equipment) para cada tipo de board o dispositivo, en el que no habían un estandar y las condiciones de testing eran complejas de dominar en sus dos aspectos principales a cubrir: Observación y Control.

 

Observación y Control

Para testear cualquier sistema es necesario llevar al sistema en un estado conocido, proveer datos/condiciones de entrada (test data) y observar el sistema para verificar que funciona (se comporta) como fue diseñado y construido.

Si no podemos controlar y observar, entonces no podemos estar seguros que el sistema funciona como debería.

 

Estableciendo Estrategias de Testabilidad

La industria de semiconductores decidió adoptar principios de “testabilidad” en etapas tempranas del proceso de diseño para asegurar la máxima testabilidad con el mínimo esfuerzo. Esto significó cambios a todo el proceso de desarrollo de los semiconductores.

La estrategia que siguieron estuvo basado en estos principales aspectos:

  1. Selección de tecnología. Al seleccionar una tecnología o proveedor, se asegurarían que había suficiente rendimiento y margen “gate-count” para permitir la inserción de testabilidad.
  2. Comprometerse con las prácticas de diseño de pruebas. Compromiso para diseñar practicas de testabilidad, usarlas y revisarlas cada tanto tiempo (mejorarlas) antes de iniciar el diseño de nuevos productos; y para auditarlas (como parte del review de procesos de desarrollo de productos).
  3. Establecer un requisito “grado de falla”. Se trata de establecer cuál era el grado de tolerancia a fallas para cada dispositivo, que también debe ser definido en la etapa de diseño ya que dirige muchas de las decisiones en el desarrollo de la estrategia de prueba. Se considera que el requisito de grado de falla es un índice del costo del dispositivo. El no lograrlo impactaba en las ganancias a lo largo de la vida útil del dispositivo.
  4. Establecer patrones de testing.
  5. Elegir/construir herramientas estructuradas: Al establecer patrones de testing, también lograron hardware estandar para testear. En este caso fue “scan testing” la preferida para probar secuencias lógicas.
  6. Establecer un conjunto de patrones para acelerar la depuración.

Además se establecieron distintos niveles de pruebas:

Si quieres profundizar más acerca de cada uno de estos niveles de testing de semiconductores, consulta el IEEE Std 1149-1 (JTAG) Testability

Más consideraciones de Testabilidad

Como consecuencia de la implementación de una estrategia de Testabilidad, el hardware de los dispositivos cambió al agregar más lógica para testear, lo que añadió más cantidad de partes y materiales en cada dispositivo.

También se estableció el fault simulation y test-application criteria.

Metodología de Testing

Design-for-Testing fue establecido en IEEE Std 1149.1 como metodología para simplificar problemas asociados con desarrollo de producto y a todos los niveles de testing. El diseño de cualquier producto nuevo debe pensarse para ser testeado en todas las fase del ciclo de vida del producto.

 

Testabilidad en Software

Cuando llevamos testabilidad al software estamos hablando de decisiones de diseño y de arquitectura que nos van a permitir testear fácil y efectivamente nuestro sistemas.

Podemos ir más allá y establecerla como un proceso que incorpora reglas y técnicas desde el diseño de un producto (de software) para facilitar su testeo, creando ciclos de retroalimentación rápidos en el proceso de desarrollo para encontrar y eliminar fallas en el código, o aún mejor evitarlas.

Se trata de facilitar (reducir incertidumbre y complejidad) el testing en todas y cada una de las etapas/fases del proceso de desarrollo, desde el diseño hasta que recibimos retroalimentación de nuestros usuarios/clientes.

Analogías con el testing de semiconductores

Observación y Control

En software también necesitamos observación y control.

Para testear cualquier sistema (de información, en este caso) es necesario llevar al sistema en un estado conocido, proveer datos/condiciones de entrada (test data, variables de entorno) y observar el sistema para verificar que se comporta tal como lo hemos diseñado y construido (mejor conocidos como criterios de aceptación).

Al igual que con los semiconductores, si no podemos controlar y observar, entonces no podemos estar seguros que el sistema funciona como debería, no estamos testeando en realidad.

Cambios de software

Asi como los semiconductores agregaron nueva lógica para facilitar el testing, nuestros frameworks modernos de desarrollo ahora incorporan librerías para unit test, API y UI tests y que además, facilitan la automatización.

Pero aún hay muchísimas cosas en las que podemos mejorar la testibilidad de nuestro software.

Niveles de Pruebas

No se parecen los niveles de prueba de semiconductores a nuestra pirámide de testing?

Requisitos

No se parecen los requisitos a nuestra definición de requisitos funcionales y no funcionales?

Testing en nuestros ciclos actuales de desarrollo de software

Así como en la industria de semiconductores, testear desde el diseño les permitió mejorar su time to market entregando productos de alta calidad, implementar el testing desde el mismo diseño de software nos permite alcanzar ciclos de desarrollo altamente eficientes con retroalimentación constante y con la confianza que estamos entregando a nuestros clientes/usuarios el más alto valor con la mayor calidad posible.

Desde que planeamos funcionalidades, debemos empezar a pensar en testing (casos, escenarios, estrategias, datos, y sobre todo, estableciendo buenos criterios de aceptación); en desarrollo, agregamos test unitarios y de integración; en testing, refinamos y ejecutamos casos y escenarios, automatizamos pruebas; nos vamos a release y estamos constantemente monitoreando/observando qué va pasando en producción para tomar decisiones acertadas.

 

Siempre que estamos diseñando un producto nuevo pensamos en cada detalle de arquitectura, si es monolítico o microservicios, cuál es la base de datos qué mejor se adapta a nuestras necesidades (relacional o no relacional), qué framework se adapta mejor a lo que queremos construir, qué herramientas nos van a dar el mejor soporte cuando necesitemos escalar, qué third parties nos ayuda a mejorar nuestros tiempos de desarrollo y de entrega. Pero, cuántas veces nos detenemos a pensar en:

  • Qué tipo de test requieren nuestros productos y negocios?
  • Cómo podemos automatizar los tests de nuestro producto? UI, API?
  • Evaluamos la testabilidad cuando estamos evaluando third parties para interactuar con nuestro software? Cómo los vamos a testear? cómo podemos automatizarlos? cómo vamos a monitorearlos?
  • Qué herramientas de testing se adaptan mejor a nuestras necesidades?
  • Qué herramientas facilitan nuestras actividades de testing?
  • Cómo vamos a monitorear el comportamiento de nuestros ambientes?
  • Qué herramientas nos permiten observar constatemente el estado de nuestros sistemas?
  • Están nuestros ambientes/procesos preparados para simular fallas?
  • Estamos proveyendo el mejor soporte posible a los testers?
  • Estamos siendo eficientes (máxima testabilidad con mínimo esfuerzo)?
  • Tan siquiera pensamos en manejo de desastres? cuál es nuestro peor escenario? Ley de Murphy siempre presente.
  • Consideramos aspectos de testing como parte de la arquitectura de nuestro software (qué, cuándo y cómo vamos a testear)?
  • Tenemos tolerancia a errores en nuestro equipo y software?
  • Hacemos reviews de nuestros procesos de testing para cambiarlos/mejorarlos?

 

Conclusiones

  • Inspirémonos en la industria de semiconductores y establezcamos nuestros estándares de testabilidad.
  • Testabilidad en software es decisiones de diseño y de arquitectura que nos van a permitir testear fácil y efectivamente nuestro sistemas. Se trata de facilitar (reducir incertidumbre y complejidad) el testing en todas y cada una de las etapas/fases del proceso de desarrollo, desde el diseño hasta que recibimos retroalimentación de nuestros usuarios/clientes.
  • Cuando las actividades de testing son de baja prioridad en nuestro proceso de desarrollo, el resultado es aplicaciones/sistemas difíciles de testear. Con el diseño correcto y las herramientas/técnicas correctas podemos lograr eficiencia (máxima testabilidad con mínimo esfuerzo).
  • Testing no es una fase o una actividad aislada, es todo un conjunto de actividades a lo largo del proceso de desarrollo y por lo tanto, todo el equipo debe estar involucrado y todos somos responsables de la calidad del software.
  • Mientras más temprano comencemos a pensar en testing va a ser más fácil, más económico y más beneficioso para equipos, proyectos y productos.
  • Podemos crear entornos en los que testear no solo sea fácil y eficiente, sino que también automaticemos todo lo que podamos automatizar.
  • Hagamos reviews constantes de nuestros procesos para traer (experimentar) herramientas y técnicas que hagan nuestros tests más eficientes y valiosos dentro de todo el proceso de desarrollo.