Páginas

Mostrando entradas con la etiqueta pruebas automatizadas. Mostrar todas las entradas
Mostrando entradas con la etiqueta pruebas automatizadas. Mostrar todas las entradas

jueves, 30 de enero de 2020

Qué es Mocha para javascript en 2 minutos

Mocha es un framework para construir pruebas automatizadas de módulos javascript. Mocha se puede utilizar tanto para módulos que se ejecutan en NodeJS cómo los que se ejecutan en un browser.

Preparando un ejemplo de 2 minutos 

Este ejemplo se ha preparado en un equipo con Windows y NodeJS previamente instalados. 

Para instalar NodeJs en Windows ir a https://nodejs.org/en/ descargar el fichero y seguir los pasos de instalación. 

Pasos a seguir:

1. Crear un directorio PruebaMocha. Desde el directorio creado, para instalar Mocha usar el comando:

npm install mocha

cómo resultado del comando aparece un directorio node_modules que contiene las librerías del framework Mocha.

2. Para construir la prueba crear el fichero miprimermochatest.js con el siguiente contenido: 

    Var assert = require('assert'); 
    describe('Array', function() { 
      describe('#indexOf()', function() { 
        it('should return -1 when the value is not present',
            function(){
          assert.equal([1, 2, 3].indexOf(4), -1);
        });
        it('should return 0 when value 1 is present on position 0', 
            function() {
          assert.equal([1, 2, 3].indexOf(1), 0);
        });
      });
    }); 

3. Para ejecutar la prueba usar desde el directorio PruebaMocha el comando:

node_modules\.bin\mocha miprimermochatest.js 

Se obtiene el resultado: 

    Array
     #indexOf()
     √ should return -1 when the value is not present
     √ should return 0 when value 1 is present on position 0
    2 passing (12ms) 

Conclusión


Este código es un ejemplo muy sencillo para mostrar cómo se automatizan las pruebas. Aquí, el código probado está incluido en el propio módulo de prueba, sin embargo normalmente el código probado está en módulos aparte que constituyen el código del aplicativo que se está probando.

En definitiva se trata de hacer programas que prueban programas. Aprender a hacer programas que tienen pruebas automatizadas, no es baladí. Para que las pruebas sean funcionales y operativas, no solo se deben preparar pruebas bien diseñadas sino que los módulos a probar también tienen que estar diseñados de manera que sean testables. Pero esa, es otra historia.

miércoles, 25 de septiembre de 2019

Test Driven Development: ¡Además mejora el diseño!

Se puede escribir el código de las aplicaciones pensando que lo único importante es que se construya en el menor tiempo posible y con el menor coste. Esta forma de proceder, ha quedado patente durante los 70 años que se lleva escribiendo software, que lleva a aplicaciones que son difíciles de mantener, y el mantenimiento de las aplicaciones es, a menudo, una etapa de larga duración en el ciclo de vida de las aplicaciones.

Para que sea fácil arreglar los errores que surjan en las aplicaciones (webs, apps, microservicios, apis, etc.) es necesario que el software esté bien diseñado. Son muy peligrosos los códigos espagueti llamados así porque todo está enmarañado como en un plato de espaguetis. En estos casos los cambios de cualquier tipo son muy peligrosos porque son muy propensos a errores. Es difícil buscar errores o donde se hacen las cosas si se trata de modificar una funcionalidad. También es difícil de prever las consecuencias de modificar una parte de código, en cuanto a las consecuencias que esto tendrá en el resto del sistema.

Por todo esto la técnica de desarrollo Test Driven Development (TDD) puede venir a ayudar. TDD es una forma de desarrollo que por sus características mejora dos aspectos muy importantes del código: se tienen que construir y ejecutar constantemente las pruebas unitarias automatizadas y el diseño de los sistemas construidos mediante esta técnica tiende a ser "bueno".

Tener pruebas unitarias es bueno porque nos sirven de red de seguridad de nuestro código. Cuando cambiamos algo, podemos comprobar si las pruebas unitarias se siguen ejecutando con éxito. En caso contrario tenemos una alarma que detecta que algo en el cambio no ha ido bien.

Que el diseño sea "bueno" hace que los desarrolladores puedan comprender mejor el código y este pueda ser modificado con más versatilidad.

Existen numerosas aproximaciones para hacer buenos diseños en ingeniería del software. Hay recomendaciones generales y otras enfocadas a algún paradigma de programación en particular. Algunos consejos generales para un buen diseño son:
  • Poco acoplamiento y mucha cohesión. Dos principios fundamentales de la ingeniería del software
  • No hagas lo que no necesitas: You Ain't Gonna Need It (acrónimo YAGNI.
Para más información ver el artículo de Martin Fowler's disponible en http://martinfowler.com/bliki/Yagni.html.
  • Reutiliza el código Don't Repeat Yourself (Acrónimo DRY) 
  • Keep it simple, stupid. Keep it simple, stupid (Acrónimo KISS)
  • Algunos principios para la programación orientada a objetos son los principios SOLID. Solid es un acrónimo formado con las palabras: Single responsability, Open-Close, Liskov substitution, Interface segregation y Dependency inversion. 

Con el objetivo de demostrar que TDD es una técnica de programación que ayuda a obtener buenos diseños de código, Alex García y Viktor Farcic en su libro Test-Driven Java Development, presentan una Kata TDD basada en el juego Conecta4.

La Kata consiste en hacer dos desarrollos del mismo juego, uno sin seguir TDD y otro siguiendo esta técnica de programación. El código de ambos desarrollos se puede descargar en  https://bitbucket.org/vfarcic/tdd-java-ch05-design.git

Conecta 4 es un juego de 2 jugadores en el que se dispone de un tablero de 7 columnas por 6 filas. Los jugadores juegan por turnos introduciendo sus fichas por la parte de arriba de cada columna. Las fichas se amontonan en las columnas. Gana el jugador que consigue colocar 4 fichas de su color en línea, ya sea vertical, horizontal o diagonal. Para más datos sobre las reglas del juego https://es.wikipedia.org/wiki/Conecta_4

Analizando el código descargado de bitbucket de ambas versiones se aprecia que efectivamente el diseño es distinto. Ambas implementaciones se resuelven en una clase escrita en Java, pero los métodos difieren. Para ilustrar esto se muestran los dos figuras siguientes. Una muestra los métodos empleados en la Kata no TDD


La  otra muestra los métodos empleados en la Kata TDD

Análisis de las diferencias entre las Katas

En las figuras se muestra mediante diagrama de secuencia los métodos que tiene cada una de las clases. Las flechas a la derecha representan las llamadas entre métodos.
 
La kata TDD resuelve con 9 métodos frente a la no TDD que se resuelve con 6. Este hecho ya tiene un aroma de mejor diseño. ¿Por qué? Pues por qué esto indicar que cada método hace menos cosas y por lo tanto es más sencillo. Pero detallando más ¿Qué tiene el diseño de connect4TDD que le hace mejor que el de connect4?
  • La modularización de las funciones se ha hecho adecuadamente esto cumple el principio "single responsability". Los métodos tienen una única misión cuya funcionalidad está bien encapsulada. Por ejemplo, hay un método checkPositionToInsert() que se encarga de comprobar si hay espacio en la columna para una nueva ficha. En la versión que se hizo sin TDD este método no existía y por lo tanto esta responsabilidad estará incluida en algún método que además hará más cosas o sea tendrá más responsabilidades.
  • Los métodos que hacen menos cosas cumplen el consejo KISS-Mantén el código lo más sencillo posible. Al tener más métodos cada uno tendrá menos funcionalidades que abordar y será más sencillo.
  •  Cumple el consejo YAGNI- No lo pongas si no lo necesitas, al implementar el código tras implementar la prueba unitaria, solo se codifica lo estrictamente necesario para que la prueba se ejecute con éxito. No hay código superfluo.
  • En el conector de Connect4TDD se ha incluido un argumento tipo PrintStream para especificar cúal es el canal de salida. De esta forma si se quiere hacer uso de la clase para mostrar el tablero por un PrintStream distinto a System.out se puede hacer simplemente indicando el canal al construir el objeto de la clase Connect4TDD. Esto se puede entender cómo un desacoplamiento de Connect4TDD y el canal de salida. Sin ser exactamente inyección de dependencias, está relacionado con este principio.

Conclusiones 

Emplear la técnica TDD mejora el diseño de las aplicaciones y proporciona aplicaciones que se pueden probar de forma automatizada. 

En el canal DevOps es fundamental de disponer de pruebas automatizadas para optimizar el trabajo de los equipos de desarrollo y operaciones. Esta técnica pone pues una primera piedra para realizar mejorar que consiguen que las áreas de tecnologías de la información sean más productivas y por consiguiente más competitivas.


miércoles, 18 de septiembre de 2019

Mejorar el canal DevOps: Cómo tratar la seguridad y proteger el canal de despliegue


En “The DevOps handbook” de Jez Humble, John Willis, Patrick Debois y Gene Kim publicado por IT Revolution Press en 2016, tratan dos temas en la parte VI del libro. Uno de ellos es como integrar los trabajos que incorporan seguridad a los sistemas en Dev y en Ops, el otro como proteger el entorno del canal de despliegue formado por servidores en los que residen los entornos en los que se construye y explota el software. En este post se hace un resumen de lo propuesto en este texto.

Tratando la seguridad

Un pretesto para no implementar los principios y patrones de DevOps es a menudo "la seguridad de la información y el cumplimiento de las normas no nos lo permiten". Paradójicamente Devops puede ser una de las mejores formas de integrar la seguridad de la información en el trabajo diario.

El ratio de ingenieros de desarrollo, de operaciones y de seguridad en una organización suele ser respectivamente de 100:10:1. Cuando seguridad no dispone de procesos de automatización y de gestión de la seguridad en el día a día de Dev y Ops, lo único que puede hacer es validar si lo desarrollado y desplegado cumple con ciertos niveles de seguridad. Esto no es muy útil ya que se obtiene información de cómo incorporar seguridad cuando todo está ya construido y es difícil o imposible de resolver.
Para que esto no ocurra se recomienda tomar las siguientes acciones:
  • Integrar a seguridad en las demos

Invitando a los especialistas en seguridad a las demos cuando finalizan los sprints, se consigue que asesoren a los desarrolladores en etapas tempranas de la construcción del código. De esta forma, el desarrollo se hará teniendo en cuenta las  necesidades de seguridad. Esto es más sencillo y barato que esperar hasta que todo está construido y después modificarlo para incorporar seguridad.
  • Integrar a ingenieros de seguridad en seguimiento de defectos y en reuniones Post-Morten

Tras el acaecimiento de un fallo se debe organizar una reunión post-morten para analizar qué motivos lo provocaron y que solución se ha adoptado. Mediante la información recopilada en estas reuniones la organización va atesorando una fuente de conocimiento que la ayudará a trabajar mejor en el futuro. El objetivo es que no se vuelvan a provocar fallos parecidos y si se producen saber cúal puede ser la solución a aplicar.
Con el objetivo de tener en cuenta en los aspectos de seguridad, es adecuado invitar a ingenieros de seguridad a estas reuniones post-morten.
  • Añadir mecanismos y herramientas que ayuden a asegurar que las aplicaciones y entornos están seguros.

Se tienen que proporcionar librerías y servicios de seguridad que proporcionen autenticación, autorización, gestión de contraseñas, encriptación de datos, etc. Se pueden incluir:

    - Modos de acceso seguro (por ejemplo, 2FA, bcrypt password. logging)
    - Herramientas para almacenar y proteger tokens, contraseñas, etc. (Por ejemplo: usando                        herramientas cómo Vault, sneaker, Keywhiz, credstash, Trousseau, Red October)
    - Paquetes para securizar (por ejemplo, NTP para sincronización de la hora de servidores,                     versiones seguras de OpenSSL, OSSEC para detección de intrusos)

  • Integrar a seguridad en el canal DevOps 

Antes de DevOps para conseguir aplicaciones seguras se revisaban las cuestiones de seguridad una vez que el desarrollo estaba completado. Normalmente el resultado eran informes con decenas o cientos de hojas en los que se indicaban las vulnerabilidades de la aplicación. Muchas veces abordar los cambión necesarios para eliminar todas estas vulnerabilidades era imposible. Solucionar esto se consigue integrando a los especialistas de seguridad en etapas tempranas del desarrollo y la implantación  que asesoren a Dev y Ops. 
  • Asegurar la seguridad de la aplicación

Consiste en establecer los medios de aseguramiento necesarios para que cuando el código llegue a producción esté en las condiciones óptimas y cumpla con todas las normas de seguridad. Para ello es oportuno establecer validaciones y verificaciones que pueden ser:
- Análisis estáticos. Con alguna herramienta revisar el código buscando debilidades, puertas traseras y código potencialmente malicioso.
- Análisis dinámicos. Los análisis dinámicos monitorizan elementos tales como la memoria, el comportamiento funcional, los tiempos de respuesta y el rendimiento del sistema. Estos análisis emulan lo que suele hacer el software malicioso y detecta vulnerabilidades.
- Búsquedas de amenazas en dependencias. Los sistemas hacen uso de librerías de terceras partes. Es necesario comprobar que dichas librerías están libres de vulnerabilidades.
- Integridad del código y firma del desarrollador. El repositorio de código es muy vulnerable, los commits deberían estar firmados para asegurarnos que han sido realizados por las personas autorizadas.
  • Asegurar la seguridad de la cadena de suministro de software

Los desarrolladores utilizan múltiples librerías que realizan funcionalidades que necesitan. Realmente en gran parte construyen sus sistemas ensamblando partes de librerías de terceros. La cadena de suministro que proporciona esas librerías también hay que asegurarla. Es necesario controlar que durante el proceso de adquisición de estas librerías no se produzcan brechas en la seguridad.
  • Asegurar la seguridad del entorno

Se trata de establecer controles que monitoricen las instancias de producción, para controlar que todos los entornos están en el estado esperado. Esto se consigue a través de pruebas automatizadas para asegurar que las configuraciones de bases de datos, sistemas operativos, redes, etc. son las adecuadas. Estas pruebas buscan vulnerabilidades.
  • Vigilar la información de seguridad añadida a la telemetría de producción 

A veces los controles de seguridad son inefectivos para detectar brechas en el momento oportuno. Esto puede deberse a que tenemos puntos ciegos en nuestra monitorización o porque nadie examina la telemetría a diario.

Marcus Sachs, uno de los investigadores de brechas en seguridad de Verizon Data dijo en 2010, "Año tras año, en la vasta mayoría de las brechas en la seguridad de los datos, las organizaciones las detectan pasados meses. Y lo que es peor las brechas se detectan desde fuera de la organización porque algún socio o cliente es víctima de alguna transacción fraudulenta. Una de las causas de que esto ocurra es que nadie en la organización revisa regularmente los ficheros de log."
  • Crear telemetria para controlar la seguridad de los entornos

Dentro del programa de mediciones a obtener, es interesante obtener medidas dedicadas a mantener los sistemas seguros. Se pueden medir:
- Cambios a los sistemas operativos
- Cambios a los grupos de seguridad
- Cambios a las configuraciones
- Cambios a la infraestructura de la nube 
- Intentos XSS (“cross-site scripting attacks”)
- Intentos SQLi (“SQL injection attacks”)
- Errores de servidor Web (4XX y 5XX)

Estas medidas pueden servir para detectar vulnerabilidades. Por ejemplo, se han detectado en marzo el doble de cambios en configuraciones que en febrero. Esta información sirve para indicar que hay que vigilar si es correcto que se haya duplicado el número de cambios. 
  • Proteger los entornos y servidores

La infraestructura que soporta la integración continua y el despliegue continuo presenta una nueva área de vulnerabilidad a los ataques. Por ejemplo si alguien compromete algún servidor que aloja las credenciales para el sistema de control de versiones, puede ocurrir que alguien robe el código fuente. Peor todavía si en estos servidores hay permiso de escritura, un atacante podría inyectar cambios maliciosos en el repositorio de código.

Protegiendo el canal de despliegue

  • Integrar seguridad y cumplimiento en el proceso de cambios

En las organizaciones suele existir un proceso para gestionar los cambios y que estos no disturben el normal suceder de los acontecimientos. ITIL clasifica los cambios en tres tipos: estándar, normal o urgente. Cada uno de ellos implica un nivel de riesgo distinto. Los cambios pequeños que implican poco riesgo se deberían automatizar o por lo menos eliminar la necesidad de aprobaciones por parte de comités o personas antes de su implantación, esto se suele convertir en cuellos de botella o traducir en tiempos de entrega largos. Los normales, sí se tratan a través de algún proceso de aprobación y los urgentes tendrán un proceso aparte donde se intente que no conduzcan a resultados no deseados.
  •  Re categorizar la mayoría de los cambios de bajo riesgo como cambios estándar

Teniendo un canal DevOps que funciona adecuadamente, el área de TI tendrá buena reputación. Los despliegues y puestas en marcha se harán de forma rápida y segura. Se dispondrá de una historia de cambios de éxito y en el caso de problemas de un tiempo de resolución pequeño.
Estando en esta situación es bueno intentar que clasifiquemos de estándar todos los cambios que podamos. Esto es porque no hay mucho riesgo de que produzcan problemas y si los producen se resolverán de forma inmediata.
  • Qué hacer cuando los cambios se catalogan como cambios normales

Para aquellos cambios que no se puedan clasificar de estándar se seguirá realizando las aprobaciones que se requieran, pero es importante asegurarse de que se automatiza todo lo que se pueda para que los despliegues sean lo más rápidos posible.
Para su correcta gestión debemos añadir a estos cambios toda la información que sea necesaria para que las aprobaciones sean lo más ágiles posible.
Es importante mantener un historial de cambios ejemplar, de esta forma podemos ganar la confianza de la organización y convertir una gran mayoria de los cambios en cambios estándar.
  • Reducir la división de tareas

La separación de tareas a menudo reduce el feedback que los ingenieros reciben de su trabajo. Esto hace que sea más difícil que se sientan responsables de su trabajo. Se debe intentar donde se pueda evitar la separación de tareas, en su lugar preparar formas de trabajo colaborativas, por ejemplo pair programming, peer review, sesiones de trabajo de ingenieros dev y ops conjuntas.

  • Proveer documentación y pruebas para auditores y agentes responsables de cumplimiento

Bill Shinn es arquitecto de soluciones de seguridad de Amazon Web Services y dice " En DevOps se trata de tender un puente entre Dev y Ops. Además existe el reto todavía más grande de tender el puente entre DevOps y los auditores y agentes de cumplimiento. Por ejemplo, cuantos auditores entienden el código y cuantos desarrolladores se han leído la norma NIST 800-37 del instituto de estándares y tecnología de Estados Unidos.
Hay que buscar los medios para suministrar la información a auditores y agentes dentro del canal DevOps.

Conclusiones


Los principios DevOps se pueden aplicar a la seguridad de la información, haciendo que el trabajo de los ingenieros de seguridad se integre en el de los de desarrollo y operaciones. Esto se consigue haciendo que la seguridad sea parte del trabajo diario de todos. Además se integran los controles de seguridad en los planes de métricas que debe utilizar el canal DevOps para mantener los entornos en un estado protegido y con un bajo perfil de riesgo.

Que con buenas prácticas DevOps la seguridad mejore hace que cuidemos mejor de los datos, también que sea posible recuperarse de los incidentes que producen las brechas de seguridad antes de que sean catastróficos y lo más importante de todo que la seguridad de nuestos datos y sistemas sea mejor que ha sido nunca.

viernes, 13 de septiembre de 2019

Mejorar el canal DevOps: Empleando técnicas de aprendizaje.


Aprender de los éxitos y los fracasos permite mejorar en todos los aspectos de la vida. Emplear esta filosofía es aplicable a los equipos que realizan las actividades en el canal DevOps para conseguir gestionar el ciclo de vida de los sistemas, las aplicaciones, los micro-servicios, las apps, las bases de datos, los sistemas operativos, las redes y demás componentes que conforman la plataforma tecnológica de la información en las organizaciones.

En “The DevOps handbook” de Jez Humble, John Willis, Patrick Debois y Gene Kim publicado por IT Revolution Press en 2016 se proponen tres formas para mejorar el canal DevOps. La primera forma está resumida en el post “Cómo mejorar el canal DevOps. Primeros pasos.” de este blog. La segunda forma está resumida en el post “Mejorar el canal DevOps: Manejando el feedback.” La tercera y última es la que se va a resumir en este post. 

Los autores de este libro recomiendan para mejorar el canal DevOps empleando técnicas de aprendizaje:

  •  Facilitar e inyectar aprendizaje en el día a día 
  •  Inyectar fallos en producción para crear resistencia a fallos
  • Convertir descubrimientos locales en mejoras globales
  •  Reservar tiempo para conseguir aprender y mejorar

Facilitar e inyectar aprendizaje en el día a día

Para que los equipos puedan aprender de sus errores hay que implantar una cultura de “no búsqueda de culpables”.  Es decir, cuando las respuestas a incidentes y accidentes se gestionan principalmente con la búsqueda de culpables se dificulta la realización de las investigaciones adecuadas, promoviendo más bien el miedo que la atención plena de las personas que están realizando trabajos. Teniendo en cuenta que estos trabajos suelen ser críticos para la organización, que los ejecutores de los mismos vivan atemorizados no es útil. Que las personas estén atemorizadas promueve organizaciones más burocráticas que resolutivas, cultivando el secretismo, la evasión de responsabilidades y la auto-protección.”

En lugar de buscar culpables es mejor recopilar información tras los fallos, se pueden realizar reuniones post-morten. Es importante difundir los detalles del  motivo y resolución del fallo para que cualquiera pueda consultarlos.

Se debe fomentar la investigación constante analizando el motivo de cada fallo por pequeño que este sea. A medida que se van solucionando fallos se deben investigar fallos más leves actuando de esta manera de forma sostenida y tratando cada vez fallos de más bajo nivel.

Los fallos son inevitables, cuantos más cambios se hacen más probable es cometer fallos. Esto no quiere decir que no debamos hacer cambios, al revés los cambios son la única forma de mejorar pero pueden tener efectos colaterales. Entonces lo más cabal es promover los cambios y actuar calibrando el riesgo que hay que asumir. Cómo ejemplo:

“Hubo una gran caída en Netflix  que fue causada por un error francamente tonto.  El error fue provocado por un ingeniero que había tirado Netflix 2 veces en los últimos 18 meses. Pero este ingeniero es de mucha utilidad para Netflix. En estos 18 meses había trasformado el estado de las operaciones mejorando la automatización de los procesos. Su trabajo ha permitido hacer despliegues más seguros en producción”. Es decir el ingeniero provocó problemas pero por qué estaba haciendo cambios que finalmente han reportado muchos beneficios.

Inyectar fallos en producción para crear resistencia a fallos

Otras técnicas que pueden ayudar a aprender son: provocar errores a propósito para aprender a resolverlos e institucionalizar días de trabajo dedicados a experimentar fallos. A este propósito existe una herramienta llamada Chaos Monkey construida por Netflix que simula caídas de servidores sobre sistemas en producción. Trabajando en los problemas generados  las instalaciones consiguen sistemas más robustos preparados para cualquier eventualidad.

Convertir descubrimientos locales en mejoras globales

Cuando se descubre algo de interés en un punto de la organización, es importante hacerlo llegar al resto. Para ello es mejor buscar medios que sirvan para que todos los miembros de la organización puedan acceder a la información. Por ejemplo, es mejor utilizar un chat que la utilización del email para compartir información acerca de la resolución de incidentes. De esta forma todo el mundo está al tanto de los incidentes que han acaecido y aprenden de su solución.

Otra forma de difundir conocimiento es automatizar procesos que sean exitosos. De esta manera es más fácil hacerlos llegar a todos los rincones de la organización.

Utilizar un solo repositorio de código para toda la organización consigue que todos los equipos compartan el código. Google lo hace para más 25.000 desarrolladores. Para que el trabajo fluya de forma consistente es necesario establecer políticas de uso del repositorio. Por ejemplo, para el uso de ramas, para la gestión de dependencias, la gestión de versiones, etc.

También las pruebas automatizadas son útiles para transmitir información.  Las pruebas unitarias sirven de documentación del código. Usar TDD entre otras ventajas consigue que las pruebas automatizadas existan y estén al día respecto al código que testean
.
Por otra parte, los desarrolladores deberían acompañar a operaciones en el despliegue y puesta en marcha del software. Cuando los desarrolladores conocen la problemática del área de operaciones, diseñan sistemas que colaboran en su puesta en producción.

Disponer de herramientas de automatización que  por ejemplo extraigan el código del repositorio, lo desplieguen en el entorno de pre-producción, ejecuten las pruebas unitarias, realicen un análisis de código estático y marquen cómo disponible el código para producción o no. Estas herramientas facilitan que los desarrolladores puedan tener un self-service de puesta en producción, es decir ellos mismos liberan software en producción.

También es interesante acordar un marco arquitectónico entre desarrollo y operaciones. Este marco no debe ser rígido, pero si marcar los límites a no traspasar si los desarrolladores quieren acogerse a las áreas soportadas por operaciones. El marco arquitectónico se refiere a las tecnologías empleadas para desarrollar: lenguajes, bases de datos, frameworks, sistemas operativos, etc. Para ilustrar mejor esta idea, considerar que respecto al uso de distintas tecnologías ponemos las que actualmente están soportadas separadas por una boyas de las que no. Los desarrolladores son libres de traspasar la boya, pero ahí tendrán menos soporte que dentro del perímetro señalizado. La metáfora de las boyas sirve para indicar que entre las tecnologías soportadas y las no soportadas no hay un muro in-traspasable.

Reservar tiempo para conseguir aprendizaje y mejorar

Blitz improvement proviene del ciclo Kaizen cuyo objetivo es la mejora. El término Blitz improvement se puede traducir como “bombardeo de mejoras”. Aplicar esta técnica, consiste en reservar un tiempo para que los equipos ideen mejoras para problemas conocidos. Existen muchos casos de éxito asociados al uso de esta técnica.

También se puede dedicar un tiempo periódicamente a eliminar deuda técnica, se trata de dedicar cierto tiempo a trabajar en los sistemas sin ampliar ni modificar funcionalidades. 

Formas de aprender también se pueden conseguir organizando eventos en los que los profesionales enseñen lo que saben a otros y escuchen lo que otros les puedan enseñar. Además es interesante participar en eventos DevOps externos a la organización, compartir experiencias con otros será enriquecedor.

Difundir las buenas prácticas que se hayan puesto en funcionamiento en algún lugar de la organización a todos los demás se puede hacer asignando consultores internos especializados a equipos que necesiten aplicar dichas prácticas. También se pueden contratar consultores externos con especialidad en alguna técnica en la que los equipos no tengan experiencia.

Conclusiones

La tercera forma, explora prácticas que ayudan a crear una cultura de aprendizaje y experimentación. Aprender de los incidentes, crear repositorios únicos para todos los desarrolladores y compartir los descubrimientos entre todos es esencial cuando se trabaja en sistemas complejos, ayudando a caminar hacia una cultura más justa de trabajo en las cuales no se busquen culpables y hacer sistemas más seguros y robustos.



lunes, 9 de septiembre de 2019

Mejorar el canal DevOps: Manejando el feedback.


En el contexto de este post feedback o retroalimentación significa: recoger datos de la ejecución de las tareas realizadas en el área de Tecnologías de la Información, analizar estos datos para obtener conclusiones objetivas sobre el resultado de las actividades y en base a estos datos planificar maneras de mejorar.

Por otro lado el canal DevOps es el conjunto de procesos y actividades que se realizan en una instalación para cubrir el ciclo de vida del software, desde su concepción hasta su puesta en producción

 Sentando las bases

La Real Academia Española de la Lengua define retroalimentación cómo “el retorno de parte de la energía o de la información de salida de un circuito o un sistema a su entrada”.

Wikipedia  define retroalimentación cómo “un mecanismo por el cual una cierta proporción de la salida de un sistema se redirige a la entrada, con señales de controlar su comportamiento”.

Un ejemplo, se dispone de una web de comercio electrónico de venta de libros. Se planifica mejorar la web con el objetivo de vender más libros. Para ello:
  • Se realiza el conteo de libros vendidos cada día.
  • Se calcula el número medio de libros vendidos a la semana.
  • Se aplica algún cambio sobre la web. Por ejemplo se decide incorporar descuentos para los mejores clientes.
  • Se compara el número medio de libros vendidos en las semanas anteriores y posteriores a la mejora.
  • Si se han vendido más libros después del cambio, podemos en general sacar la conclusión de que el cambio ha sido un éxito.
En esencia esta es la base. Viendo la retroalimentación desde este punto de vista, esta puede ayudar a mejorar el canal DevOps o cualquier otro proceso en las organizaciones.

¿Qué sé puede hacer para mejorar el canal DevOps?

En el libro “The DevOps handbook” de Jez Humble, John Willis, Patrick Debois y Gene Kim publicado por IT Revolution Press en 2016 proponen tres formas para mejorar el canal DevOps. La primera forma está comentada en el post “Cómo mejorar el canal DevOps. Primeros pasos.” de este blog. La segunda forma consiste en manejar adecuadamente la retroalimentación. Para realizar una correcta gestión de la retroalimentación, el libro la enfoca desde distintos puntos de vista:

Crear telemetría para permitir encontrar y después resolver problemas

Un hecho real es que pequeños cambios pueden desestabilizar un sistema y conducir a caídas o fallos globales. No es fácil que alguien tenga suficiente conocimiento para tener una visión global de la instalación y poder saber donde se encuentra el problema. Los sistemas suelen ser complejos y el fallo puede estar en muchos sitios distintos. Para resolver el problema es necesario tener información y esta información está disponible si se han previsto los mecanismos necesarios para guardarla.
Uno de los descubrimientos del informe “State of DevOps” de 2015 fue que los equipos de operaciones que consiguen solucionar los problemas más rápidamente, emplean dos técnicas: el uso de un sistema de control de versiones y otra haciendo mediciones y monitorizándolas proactivamente en el entorno de producción.

Analizar la telemetría para anticiparse a los problemas y alcanzar los objetivos

Es deseable prever los problemas para evitar que se produzcan. Esto se puede conseguir monitorizando el funcionamiento de los sistemas y produciendo alertas cuando se detecte alguna anomalía.
Se pueden usar medias, desviaciones estándar, patrones de comportamiento de los datos, cualquier mecanismo puede ser bueno para detectar si se está produciendo una anomalía e intentar resolverla antes de que provoque caídas o efectos no deseados.

Habilitar feedback para que desarrollo y operaciones puedan desplegar código de forma segura

Es necesario que los equipos de desarrollo sepan las consecuencias del despliegue de los cambios que efectúan en el código. Para ello es conveniente que los desarrolladores participen en las tareas de puesta en marcha.
Se pueden establecer medios para que los desarrolladores puedan desplegar en producción los sistemas por sí mismos. La clave está en la automatización, hay muchas herramientas disponibles para poder controlar automáticamente múltiples aspectos del código antes de desplegarlo: pruebas automatizadas a todos los niveles, cobertura de pruebas, análisis estático de código, gestión de dependencias, etc. Todas estas herramientas contribuyen a qué la puesta en producción pueda estar en manos de los equipos de desarrollo.

Integrar desarrollo conducido por la hipótesis y A/B testing en el trabajo diario

Hay funcionalidades que se ponen en producción y nadie las utiliza. Poner en producción código que no es útil a los usuarios es negativo, porque es trabajo inútil y porque además es un código que sin ser útil hay que mantener.  
El A/B testing puede minimizar esta problemática. A/B testing consiste en poner en producción distintas versiones de una misma funcionalidad. Cada versión se le ofrece a un grupo de usuarios diferente. Luego se estudia que versión funcionó mejor y es la que se implanta.
Un paso más allá es el desarrollo conducido por la hipótesis. Este consiste en partiendo de una necesidad detectada por los expertos en negocio, realizar un experimento de implementación (no completa) y ponerlo en producción de forma controlada. Con la aceptación o no aceptación de los usuarios de las funcionalidades suministradas en el experimento, se valida si la hipótesis es una necesidad real o no. En función del resultado del experimento se actúa continuando con la implementación o abandonando la hipótesis.

Crear procesos de coordinación y revisión que incrementen la calidad del trabajo

Con el objetivo de anticiparse a los problemas que un cambio puede producir en producción, es adecuado establecer los medios de revisión y coordinación necesarios.
Ahora bien, no se trata de implantar burocráticos procesos realizados por terceras partes, ajenas al proceso de construcción y despliegue del código. Los procesos realizados por terceros tienden a alargar los procesos de despliegue y a no ser efectivos. Es difícil averiguar los problemas que tiene un código al que se es ajeno.
Es más útil preparar procesos de revisión entre compañeros o iguales (peer review). Un ejemplo de revisión entre compañeros es el pair programming, en esta técnica dos desarrolladores trabajan sobre el mismo código. De esta forma el código cuando está terminado ya está revisado y validado por dos programadores.

Conclusiones

Se ha abordado la retroalimentación desde distintos puntos de vista:
  • Retroalimentación recogiendo datos sobre ejecución de tareas y análisis de los mismos para mejorar
  • Retroalimentación a los equipos de desarrollo no ajenos a las consecuencias de la implantación de su código en producción
  • Retroalimentación sobre los efectos de un cambio con A/B testing
  • Retroalimentación para asegurar hipótesis antes de implementar mediante desarrollo dirigido por la hipótesis
  • Retroalimentación partiendo de revisiones para obtener información de las consecuencias de la implantación
Todas estas formas de aprovechar las ventajas de la retroalimentación pueden ser fuente de inspiración para la mejora del canal DevOps.