sábado, 30 de noviembre de 2013

Pruebas de performance

¿Qué son las pruebas de rendimiento?

De manera sencilla podemos definir las pruebas de rendimiento como un conjunto de pruebas que son realizadas a una aplicación para determinar el comportamiento del performance de la misma, identificar puntos potenciales de mejora o garantizar los niveles de servicios esperados por los clientes del sistema.  Actualmente este tipo de pruebas son realizadas en la mayoría de los proyectos de tecnología únicamente a aquellas aplicaciones de ejecución crítica que puedan afectar la operación del negocio, aunque cada vez más se evidencia la necesidad de realizar este tipo de pruebas para los diferentes aspectos del código producido y consecuentemente los proyectos de tecnología hacen cada vez un mayor uso de pruebas de stress y de carga en un mayor número de compontes de sus sistemas.   
Cabe recordar que las pruebas de rendimiento pueden realizarse en diferentes niveles del desarrollo, pueden planearse y ejecutarse mucho antes de que se haya finalizado el desarrollo en su totalidad, por ejemplo, podríamos realizar pruebas de rendimiento a cada uno de los componentes que integran el desarrollo en conjunto con las pruebas unitarias de los mismos y a medida que se vayan integrando podríamos realizar otras pruebas de integración entre componentes que aseguren que no existan problemas de rendimiento en la forma en la cual interactúan a partir del diseño del sistema.  Realizar pruebas de rendimiento de manera temprana es una buena forma de establecer garantías parciales en el mediano plazo que nos permitan avanzar hacia los objetivos de performance definidos con una incertidumbre menor.

¿Por qué son necesarias?

Podría pensarse que las pruebas de rendimiento pueden ser ejecutadas de manera posterior al despliegue de nuestras aplicaciones, sin embargo, debemos tener claro que las pruebas de rendimiento tienen como objetivo fundamental anticipar los problemas de performance que puedan ocurrir una vez la aplicación esté en producción.  Una vez que se haya llevado a cabo la entrega de un desarrollo, será mucho más difícil encontrar formas de sobrellevar problemas de desempeño detectados en la operación ya que en esta etapa contaremos con un menor control sobre las características que podremos cambiar para cumplir los nuevos objetivos.
Las pruebas de rendimiento adicionalmente nos ayudan a visualizar tiempos muertos de las aplicaciones que de otra manera no hubieran podido detectarse, redundando en un mayor conocimiento las tareas que consumen mayor tiempo, de los límites del código producido y adicionalmente en la identificación de los puntos más frágiles de la aplicación.  Cada uno de estos aspectos es de vital importancia si deseamos descubrir mejores formas de realizar las operaciones pertinentes. 

¿Cómo pueden ayudarnos?

Las pruebas de rendimiento pueden hacernos la vida más fácil o más difícil dependiendo de la forma en la que se gestione la ejecución de dichas pruebas, si no se tienen claros temas del proyecto relacionados con costos, tiempos de entrega y parámetros específicos de las pruebas realizadas podemos entrar en un ciclo infinito de pruebas rechazadas. 
Es importante entender los conceptos o las características que se están midiendo y como se alinearán dichas mediciones con los objetivos del proyecto antes de iniciar un plan de pruebas que probablemente arrojen resultados de poco valor que no nos permitan mejorar nuestros productos. 
Otra forma en la que las pruebas de performance pueden ayudarnos está relacionada con la capacidad de predecir comportamientos a partir de los volúmenes de datos u operaciones de manera tal que podamos ser capaces de entregar guidelines o documentación clara sobre el rendimiento que debe ser esperado por parte de los usuarios del sistema, por ejemplo, si hemos construido una aplicación para construir pantallas de captura de datos en la web y entregamos una documentación que establezca que el tiempo promedio de procesamiento para un control en una página tiene un tiempo promedio de 1 ms bajo ciertas condiciones, con seguridad podremos establecer los requisitos de hardware mínimos para que dicha premisa se cumpla y adicionalmente podremos evitar mediante políticas de desarrollo que los usuarios del sistema intenten construir páginas con 3000 controles que demorarían en promedio 3 segundos en cargar lo que podría ocasionar otro tipo de problemas en el desempeño general de la aplicación.

Etapas generales de una prueba

Una prueba de rendimiento por lo general se encuentra divida en tres fases.  A continuación se presenta una breve descripción de cada una de ellas.
Construcción: En esta etapa de la prueba se identifican los casos que serán susceptibles de ser probados, se define la manera en la cual se realizará la prueba y se construyen scripts o artefactos que permitirán su ejecución. 
Ejecución:  El objetivo en esta fase es el de utilizar los artefactos construidos para la ejecución de la prueba con el fin de obtener información sobre las métricas, los casos y/o características definidas durante la construcción.
Análisis: Una vez que se haya recolectado la información que se ha obtenido durante las ejecuciones de las pruebas de rendimiento se deberá proceder a analizar la información según para poder tomar acciones los resultados encontrados.
A pesar de que puede parecer sencillo, la obtención de los datos de una prueba con un nivel de confianza relativamente bueno puede suponer algunos retos a la hora de poner en marcha el plan.  Temas como el aislamiento de los ambientes, el estados de los recursos, temas de configuración de la aplicación y los errores humanos pueden repercutir en la invalidez de las pruebas realizadas, derivando en la necesidad de repetir la prueba una y otra vez hasta que se logue la confianza suficiente en los datos y los procedimientos utilizados.



Validez de pruebas

Como se mencionó anteriormente las pruebas pueden invalidarse por un gran número de razones de diferente naturaleza, por esta razón sería una buena idea tener claros los escenarios más comunes que puedan presentarse para que una prueba pierda su validez.  En esta sección presentaremos algunos de estos escenarios e intentaremos detallar ejemplos asociados con los mismos.

Aislamiento del ambiente de pruebas

Un caso común en las áreas de tecnología de las empresas hoy en día corresponde al reúso de recursos para los ambientes de IT, ser reutiliza la infraestructura con el objetivo de reducir costos, por esta razón, encontramos ambientes virtualizados que comparten hardware entre sí con el fin de optimizar las operaciones, estas situaciones pueden representar un riesgo al momento de realizar pruebas de rendimiento, ya que si el ambiente que ha sido destinado para pruebas también se utiliza en otro tipo de tareas como por ejemplo como ambiente de desarrollo, los resultados de nuestras pruebas podrían no ser del todo confiables. 
Teniendo como base el planteamiento anterior podemos inferir que para que la validez de nuestras pruebas no se vean afectadas por operaciones sobre el ambiente externas a los escenarios probados es fundamental que el ambiente de pruebas esté físicamente aislado de otros ambientes.  Esto no quiere decir que el ambiente deba estar totalmente desconectado, por ejemplo, de la red de nuestra compañía o que deba ser privado de cualquier servicio de comunicación con otros elementos de la infraestructura, lo que realmente nos dice es que los recursos destinados para pruebas deben estar lo suficientemente disponibles para garantizar que la aplicación probada no presentará pérdidas de rendimiento debido a elementos externos a la misma prueba y a las condiciones naturales de la plataforma sobre la que opera. 

 

Disponibilidad de recursos suficientes

Aún cuando el ambiente se encuentre físicamente aislado durante la realización de las pruebas de rendimiento, es posible que existan elementos locales dentro de las máquinas utilizadas, por ejemplo, componentes ajenos a la prueba que puedan consumir intensivamente recursos computacionales como podrían ser instalaciones imprevistas de aplicativos, ejecución de análisis de antivirus o condiciones específicas del sistema operativo pueden provocar una disminución en los tiempos obtenidos en la prueba de manera, hecho que podría confundirse con mejoras o disminución del rendimiento al ser comparados con pruebas que hayan sido realizadas en ausencia de la ejecución de dichos componentes.  Entonces podemos decir que se debe verificar que los recursos locales no están siendo afectados de manera intensiva por aplicaciones externas a la prueba.  De igual manera otras tareas en ejecución como la descarga de grandes volúmenes de información de internet durante el tiempo de la prueba puede afectar  recursos utilizados por la aplicación probada como el acceso a la red.

Invariabilidad del hardware y software

Una vez que se ha garantizado que las condiciones físicas y locales del ambiente de pruebas se perciben como estables podemos comenzar a realizar nuestras pruebas, pero en caso de utilizar diferentes ambientes para realizar las mismas debemos garantizar que las mediciones de tiempos se realicen utilizando recursos de hardware equivalentes, es decir, asegurar que a pesar de que las pruebas se hayan realizado en diferentes máquinas, las especificaciones del hardware utilizado sean exactamente iguales o muy similares, en caso de ser diferentes las pruebas son incomparables a menos que los resultados de las pruebas se evalúen en términos relativos, como porcentaje del tiempo consumido. 
Si una aplicación se prueba dos veces en ambientes con especificaciones de software diferentes, como por ejemplo, máquinas con sistemas operativos diferentes o con diferencias en parches instalados del sistema, es posible que las operaciones realizadas en ambas pruebas no se realicen de la misma manera, por lo cual nuevamente las pruebas no son comparables entre sí.  Lo más cómodo en términos generales al momento de ejecutar un conjunto de pruebas es seleccionar un único ambiente, aislado y controlado para ejecutar todas las pruebas pertinentes, de esta manera no deberemos preocuparnos por las diferencias de hardware o software pues el ambiente será igual para todas las muestras recolectadas haciendo que los resultados entre pruebas puedan se comparables entre si y tengamos una mayor confianza en los datos obtenidos.

Representatividad del tamaño de muestras

Aún cuando el ambiente esté aislado, las condiciones locales del sistema sean uniformes y no existan diferencias de hardware o software entre las pruebas realizadas, debemos entender que el estado de las máquinas en la que se hospedan nuestras aplicaciones está sujeto a variaciones no predecibles, como por ejemplo el uso de la memoria virtual, caídas repentinas de la disponibilidad de ciertos servicios como la red o tecnologías asociadas con la reducción del consumo energético de los equipos y procesadores. 
Por el motivo anteriormente expresado, es necesario tener un tamaño de muestreo representativo, con el fin de descartar los casos atípicos y poder establecer un comportamiento promedio o general de las características que deseamos cuantificar.  Mientras mayor sea el número de muestras recolectadas tendremos una visión más completa del comportamiento medido.  Determinar el número de pruebas a realizar para obtener un nivel de confianza aceptable puede llevarnos a un análisis más formal y estadístico, aunque usualmente este tipo de métodos no son utilizados con frecuencia por lo que se trata de realizar las pruebas con el mayor número posible de iteraciones o usuarios, por ejemplo por encima del número promedio real.  Tener un número muy bajo de pruebas puede invalidar los resultados obtenidos a partir de las mismas.

Repetitividad o repetibilidad de Casos

Otro factor que suele ser determinante para identificar la validez de una prueba puede estar relacionado con la capacidad que tiene la prueba de ser "repetible", para exponer la importancia de este concepto, plantearemos un escenario en el cual una aplicaciones realiza un conjunto de tareas diferentes de manera aleatoria, si realizamos las pruebas de dicha aplicación ¿cómo podemos asegurar que todas las pruebas miden los mismos aspectos?, de hecho, no lo hacen, por lo que se evidencia la necesidad de que los casos probados sean perfectamente reproducibles de modo que podamos establecer comparaciones sobre los resultados obtenidos.  En algunas ocasiones la repetibilidad puede estar asociada a los diferentes caminos lógicos que una aplicación puede tomar durante su ejecución y en otras ocasiones dichos cambios dependerán de los datos suministrados como entrada de los algoritmos implementados. 
Algunas veces es casi imposible lograr que el número de llamados a todas las funciones sean exactamente igual entre pruebas, sobre todo si lo que intentamos comparar está relacionado con mejoras debido a modificaciones sobre los algoritmos codificados.  En estos casos es posible realizar las comparaciones normalizando los datos, por ejemplo  si una aplicación ejecutó diez veces el método A() en la prueba 1 y 30 veces el mismo método en la prueba 2 podremos comparar los resultados dividiendo el tiempo T1(A) entre 10 lo que nos dará el tiempo promedio de A durante la prueba 1 y podemos hacer lo mismo para la prueba número 2 obteniendo el tiempo promedio de A durante la prueba 2 al restar T2(A) - T1(A) podremos establecer la diferencia entre los tiempos promedio aún cuando las dos pruebas no coincidan en el número de llamados. 
Analizar tiempos de funcionalidades entre pruebas con diferente número de llamados y sin normalizar los tiempos puede ser un factor para invalidar las conclusiones obtenidas en las pruebas realizadas.

Confiabilidad de herramientas y mediciones


Bueno, como último aspecto a considerar para evitar que nuestra prueba sea confiable tenemos la confiabilidad de las herramientas que son utilizadas para realizar las mediciones de las características que deseamos evaluar.  Obtener datos a partir de herramientas que puedan retrasar en demasía los tiempos de la aplicación a probar puede llevarnos a conclusiones erróneas sobre el comportamiento de la misma.  En los posible las herramientas utilizadas deben estar certificadas o ser reconocidas como herramientas que arrojan resultados confiables y que tienen el menor efecto posible en la prueba.

Performance de Aplicaciones

Generalidades del performance

Día a día se escuchan en las áreas de tecnología de las grandes empresas frases que asociamos con el rendimiento de las aplicaciones, en algunos casos por ejemplo escuchamos que el performance de cierta característica de nuestra aplicación es bueno o malo, de igual manera relacionamos términos como "cuellos de botella" , "contención" y "throughput" con temas de rendimiento de aplicaciones, sin embargo, cuando nos detenemos a pensar sobre lo que significa el performance de  aplicaciones solemos no tener una idea clara sobre lo que realmente significa y esta será la pregunta que nos ocupará durante la lectura de este capítulo.

¿Qué es el performance de aplicaciones?

En primera instancia podemos definir el performance desde el punto de vista del usuario como la capacidad que tiene una aplicación de realizar las operaciones que le competen cumpliendo a cabalidad con las expectativas de procesamiento de los usuarios.  Teniendo en cuenta esta primera aproximación se evidencia que el buen o mal rendimiento por parte de una aplicación será una categorización subjetiva dependiendo de los requerimientos técnicos esperados por parte de los usuarios, llevándonos a concluir que lo que para un usuario es un rendimiento aceptable para un sitio web para otro puede no serlo, normalmente la percepción del rendimiento está asociada al volumen de operaciones y datos que dicho usuario opera y dicha percepción irá cambiando a medida que los volúmenes de información y cálculos se van incrementando en el tiempo. 
De lo anterior se puede intuir que nuestras expectativas a la hora de diseñar y construir una aplicación determinan en cierta medida el resultado que se obtendrá en términos de desempeño, sin embargo, podemos observar que el hecho de que los volúmenes de información manejados por dos aplicaciones distintas sean similares no quiere decir que el rendimiento de ambas aplicaciones sea igual, aunque al usuario pueda percibirlas por igual en producción, aún mas, que el performance de una aplicación se perciba como bueno no implica que la manera en la que dicho software realiza sus operaciones sea la óptima.  Teniendo en cuenta este segundo punto tendremos que buscar definir el rendimiento de una manera más objetiva de modo tal que frente a dos aplicaciones se pueda establecer cual cuenta con el mejor rendimiento. 

Subjetividad y objetividad de los datos

La manera más sensata de conseguir una aproximación objetiva podría ser establecer métricas que se encuentren directamente relacionadas con las expectativas de un único usuario de referencia, por ejemplo, para un usuario gerente de un banco y para una aplicación web de su intranet una buena métrica podría ser el número de créditos que pueden ser ingresados al sistema durante una hora, para un usuario en una planta de producción una buena métrica podría estar relacionada con el número de piezas revisadas por minuto.  Estas métricas que se han definido podrían diferenciar claramente las características de rendimiento entre dos aplicaciones de funcionalidades similares, sin embargo para poder establecer un criterio de evaluación realmente objetivo que nos permita determinar las características y límites de performance de las aplicaciones, dicho criterio deberá abstraerse de las condiciones y las expectativas del negocio, llevándonos a clasificar las métricas para la evaluación del desempeño en dos categorías, la primera de ellas serían las métricas de negocio y las segunda categoría estaría dada por las métricas de técnicas ambas relacionadas con el performance. 
Una combinación efectiva de ambos tipos de métricas nos ayudarán a evaluar las condiciones de rendimiento de manera objetiva sin alejarnos de los objetivos de negocio que perseguimos con la implantación de nuestra solución en la organización. 
Todo esto está muy bien, pero ¿Qué tipo de métricas técnicas nos permiten evaluar el desempeño de nuestras aplicaciones de manera objetiva? bueno, las métricas indicadas estarán relacionadas con las operaciones (computacionalmente hablando) que realice la aplicación en cuestión.  Para una aplicación web es muy probable que el número de solicitudes procesadas por segundo sea una buena medida de cuanto es capaz de hacer dicha aplicación. 
En términos generales podríamos decir que el rendimiento general de una aplicación será mejor mientras más operaciones por unidad de tiempo realice, sin embargo, aunque pareciera que esta métrica únicamente dependiera de el número de operaciones procesadas por nuestro software y del tiempo,  la realidad es que otros aspectos como el la cantidad de recursos que son consumidos por el sistema pueden hacer que el número de operaciones por segundo disminuya sustancialmente razón por la cual nos interesará establecer métricas relacionadas con el consumo de recursos como memoria, cpu, red.
El performance de las aplicaciones por tanto puede concebirse como  el conjunto de valores asociados con métricas claramente definidas que determinan la capacidad de procesamiento del sistema computacional en cuestión así como su calidad y el análisis de performance podría verse como el conjunto de las técnicas y herramientas orientadas al estudio del mejoramiento de los valores para cada una de dichas métricas.

Importancia del performance

Como se ha mencionado en el capitulo anterior, el performance de las aplicaciones que construimos es una parte importante dentro de los objetivos de negocio de una organización, temas como la ejecución de las operaciones críticas de una empresa pueden estar siendo afectadas por  pérdidas en el rendimiento de los sistemas de información utilizados para gestionar dichas operaciones y estos temas de negocio son en general los que deben motivarnos a realizar planes para el mejoramiento del desempeño.  La importancia de obtener aplicaciones con un buen performance se visualiza de manera más evidente cuando se contemplan los riesgos asociados, es decir, los problemas potenciales que pueden provocarse por no tener en cuenta el desempeño de los sistemas construidos.  A continuación se presentan algunos de los riesgos que pueden generar este tipo de problemas.

Daños en las relaciones con los clientes

La manera más obvia en la que nos afecta un bajo desempeño del software está ligada con la disminución en la capacidad que posee una organización para proveer sus productos o servicios a los clientes, una disminución en los niveles de servicio, tiempos de entrega o productos fabricados puede afectar la imagen de la organización de manera tal que los consumidores asocien una empresa con un mal manejo de la actividad comercial a la que se dedica, los daños en la imagen pueden tomar mucho tiempo en repararse y comúnmente reparar las causas de los daños no mejora inmediatamente la percepción de los consumidores. Para el caso específico del software como producto, una aplicación que ha sido identificada como de bajo rendimiento hará que los usuarios antiguos dejen de utilizarla y probablemente desviará el mercado potencial hacia otras alternativas equivalentes, es decir,  nuestra competencia.

Efectos en la comunicación

En el mundo de las arquitecturas empresariales de hoy, las aplicaciones suelen estar conectadas entre sí ejecutando sus tareas de manera colaborativa y coordinada, de esta manera la velocidad del sistema general puede comenzar a presentar una disminución en las operaciones realizadas debido al bajo rendimiento de una de muchas aplicaciones dentro del ecosistema.  Este tipo de situaciones, por lo general terminarán afectando los tiempos de respuesta de algunos servicios de la organización y a todas sus dependencias, haciendo más difícil el cálculo de la pérdida y multiplicando la misma.

Pérdidas de dinero

Los problemas relacionados con la capacidad en la operación de una organización no solamente afectan la imagen y la confianza de nuestros consumidores en la calidad de los productos, en ocasiones, los retrasos producidos en las entregas o transacciones en general pueden desencadenar pérdidas significativas de dinero para las empresas ya sea por el pago de multas, clausulas de incumplimiento, por reprocesamiento innecesario de trámites o por términos pactados con anterioridad en las contrataciones relacionados con los niveles de servicio.  A veces, los ingresos de la organización puede estar relacionado de manera directa con el volumen de información que es capaz de procesar un sistema de información específico.

Perdida de la competitividad

Sumado a los problemas anteriormente descritos, es probable que se comience a tener problemas de velocidad respecto a nuestros competidores y a la oferta de los productos o servicios en el mercado.



Performance como estrategia de mercadeo

Cualquier producto o servicio que se esté presente en el mercado es susceptible de tener competencia y como es algo natural los productos y servicios relacionados con el software no son la excepción.  Aún cuando nuestros productos sean lo suficientemente innovadores y novedosos como para que no exista competidor alguno, la posibilidad de competencia siempre está presente cada vez que se abre un nuevo nicho en el mercado y si queremos conservar nuestra ventaja competitiva tendremos que mejorar permanentemente las características de dichos productos de manera que satisfagan las necesidades de nuestros consumidores.  El rendimiento de nuestras aplicaciones no está exento de esta problemática de manera tal que en ocasiones las evaluaciones de desempeño nos proporcionan herramientas para presentar a nuestros consumidores la eficiencia con la que nuestro software realiza las operaciones esperadas.  
Debemos tener en cuenta que los usuarios de las aplicaciones persiguen un objetivo claro y es el de poder hacer más en el menor tiempo posible y el hacer más estará directamente relacionado con dos características principales del producto.  En primera instancia tenemos la cantidad de operaciones de negocio que podemos procesar, la cual se relaciona directamente con el rendimiento de las aplicaciones, el segundo aspecto en el cual pueden estar interesados nuestros clientes, está relacionado con la capacidad que brinde nuestros sistemas para poder crecer el volumen de las operaciones a medida que los negocios crecen, este aspecto claramente se relaciona con la escalabilidad del sistema.   En esta sección se discutirán algunos temas sobre como exponer a nuestros usuarios las ventajas de rendimiento y escalabilidad de nuestras aplicaciones.

Hablar un mismo idioma

Cuando intentamos presentar la eficiencia de nuestros productos, como ya hemos dicho anteriormente debemos tener en cuenta que a los consumidores de nuestras aplicaciones no les interesa saber cuántos bytes por segundo, accesos a bases de datos o transacciones pueden realizar nuestros programas de computadora,  se debe tratar de expresar las características de performance en términos de beneficios para la operación del negocio si realmente deseamos diferenciarnos, por ejemplo, si nuestra aplicación web puede procesar un promedio de 100 solicitudes por segundo podremos presentar esta información en términos de el número de aprobaciones para créditos que se pueden realizar al día en nuestro sistema de información, de esta manera tendrá más valor para el usuario saber que en un día laboral podrá procesar 2'880.000 de créditos que saber el número de consultas a la base de datos.  De esta manera se debe hablar en el idioma del negocio y no en términos técnicos que puedan confundir o ahuyentar a quienes serán los usuarios del sistema ofertado.

Performance como factor diferenciador


Algunas veces las empresas productoras de software liberan distintas versiones de sus productos con el objetivo de generar popularidad o recordación entre los usuarios potenciales, de esta manera, encontramos versiones de evaluación y algunas con limitaciones respecto a sus funcionalidades.  Nuevamente trabajar en el performance y en la escalabilidad de nuestras aplicaciones nos dará herramientas para convencer y conectarnos con aquellos usuarios que han estado atentos a las versiones limitadas y que están buscando poder obtener el mayor rendimiento posible para su operación, es una forma de plantear que si está contento con las limitantes, ¿podría imaginar lo que haría funcionando al máximo de capacidad?  Este concepto utiliza el performance como un factor diferenciador entre lo que ofrecemos como muestra y lo que ofrecemos como producto.  Algunas veces las diferencias están asociadas a limitaciones en el uso, por ejemplo, un sistema cuya versión gratuita se distribuye con una limitante en el número de usuarios que pueden operar en ella, atrayendo a usuarios con mayores necesidades a utilizar la versión paga con un número de usuarios indefinidos en producción.