En todo proyecto de desarrollo software es muy importante la realización de planes de pruebas que garanticen que se cumplen los requisitos funcionales de la aplicación. Pero no todo el trabajo de un QA son las pruebas funcionales. Además de éstas, existen otras que pueden marcar la calidad de una aplicación: de seguridad, de usabilidad, de rendimiento.

Las pruebas de rendimiento son, desde la perspectiva más evidente, las que se realizan para determinar lo rápido que un sistema realiza una tarea en unas determinadas condiciones de trabajo. En este post hablaremos sobre su utilidad, los tipos que existen y cómo realizarlas con JMeter.

 

 

¿PARA QUÉ SIRVEN LAS PRUEBAS DE RENDIMIENTO?

Para alcanzar un buen nivel de rendimiento de un sistema es fundamental que las pruebas comiencen en el inicio del desarrollo del software. Al igual que en las pruebas funcionales, el coste de solucionar defectos se ve aumentado conforme más se tarde en detectarlos.

Además, si queremos que los resultados sean lo más fiables posible, nuestro entorno de pruebas debe ser lo más parecido posible al de producción, y no cruzarlo nunca con el de desarrollo ni el de otras pruebas.

La pruebas de rendimiento sirven, entre otras cosas, para:

  • Demostrar que el sistema cumple los criterios de rendimiento.
  • Validar y verificar atributos de la calidad del sistema: escalabilidad, fiabilidad, uso de los recursos.
  • Comparar dos sistemas para saber cuál de ellos funciona mejor.
  • Medir qué partes del sistema o de carga de trabajo provocan que el conjunto rinda mal.

 

 

TIPOS DE PRUEBAS DE RENDIMIENTOS

PRUEBA DE CARGA

Éste es el tipo más sencillo de pruebas de rendimiento. Una prueba de carga se realiza generalmente para observar el comportamiento de una aplicación bajo una cantidad esperada de peticiones. Esta carga puede ser el número esperado de usuarios concurrentes, utilizando la aplicación que realizan un número específico de transacciones, durante el tiempo que dura la carga. Esta prueba puede mostrar los tiempos de respuesta de todas las transacciones importantes de la aplicación. Si también se monitorizan otros aspectos como la base de datos, el servidor de aplicaciones, etc., entonces esta prueba puede mostrar el cuello de botella en la aplicación.

 

PRUEBA DE ESTRÉS

Se utiliza normalmente para romper la aplicación. Se va doblando el número de usuarios que se agregan a la aplicación y se ejecuta una prueba de carga hasta que se rompe. Este tipo de prueba se realiza para determinar la solidez de la aplicación en los momentos de carga extrema. Esto ayuda a los administradores para determinar si la aplicación rendirá lo suficiente en caso de que la carga real supere a la carga esperada.

 

PRUEBA DE ESTABILIDAD (SOAK TESTING)

Normalmente se hace para determinar si la aplicación puede aguantar una carga esperada continuada. Generalmente esta prueba se realiza para determinar si hay alguna fuga de memoria en la aplicación.

 

PRUEBA DE PICO (SPIKE TESSTING)

La prueba de picos, como el nombre sugiere, trata de observar el comportamiento del sistema variando el número de usuarios, tanto cuando bajan como cuando tiene cambios drásticos en su carga. Esta prueba se recomienda que sea realizada con un software automatizado que permita realizar cambios en el número de usuarios mientras que los administradores llevan un registro de los valores a ser monitorizados.

 

 

METODOLOGÍA

Según Microsoft Developer Network, la metodología de las pruebas de rendimiento consiste en las siguientes actividades:

  1. Identificar el entorno de pruebas. Identificar el entorno físico de pruebas y el entorno de producción, así como las herramientas y recursos de que dispone el equipo de prueba. El entorno físico incluye hardware, software y configuraciones de red. Tener desde el principio un profundo conocimiento de todo el entorno de prueba permite diseños de pruebas más eficientes. Facilita también la planificación y ayuda a identificar problemas en las pruebas en fases tempranas del proyecto. En algunas situaciones, este proceso debe ser revisado periódicamente durante todo el ciclo de vida del proyecto.
  2. Identificar los criterios de aceptación de rendimiento. Determinar el tiempo de respuesta, el rendimiento, la utilización de los recursos y los objetivos y limitaciones. En general, el tiempo de respuesta concierne al usuario, el rendimiento al negocio, y la utilización de los recursos al sistema.  Identificar cuáles serían criterios de éxito de rendimiento del proyecto para evaluar qué combinación de la configuración da lugar a un funcionamiento óptimo.
  3. Planificar y diseñar las pruebas. Identificar los principales escenarios, determinar la variabilidad de los usuarios y la forma de simular esa variabilidad, definir los datos de las pruebas y establecer las métricas a recoger. Consolidar esta información en uno o más modelos de uso del sistema a implantar, ejecutarlo y analizarlo.
  4. Configurar el entorno de prueba. Preparar el entorno de prueba, las herramientas y recursos necesarios para ejecutar cada una de las estrategias, así como las características y componentes disponibles para la prueba. Asegurarse de que el entorno de prueba se ha preparado para la monitorización de los recursos según sea necesario.
  5. Aplicar el diseño de la prueba. Desarrollar las pruebas de rendimiento de acuerdo con el diseño del plan.
  6. Ejecutar la prueba. Ejecutar y monitorizar las pruebas. Validar las pruebas, los datos de las pruebas y recoger los resultados. Ejecutar pruebas válidas para analizar, mientras se monitoriza la prueba y su entorno.
  7. Analizar los resultados, realizar un informe y repetirlo. Consolidar y compartir los resultados de la prueba. Analizar los datos, tanto individualmente como con un equipo multidisciplinario. Volver a priorizar el resto de las pruebas y a ejecutarlas en caso de ser necesario. Cuando todas las métricas estén dentro de los límites aceptados, ninguno de los umbrales establecidos hayan sido rebasados y toda la información deseada se ha reunido, las pruebas han acabado para el escenario definido por la configuración.

 

 

JMETER

Existen numerosas herramientas, tanto open source como privativas, para realizar las pruebas de rendimiento: NeoLoad, LoadRunner, LoadUI, WebLOAD, etc. Una de las más populares es JMeter (open source), en la cual nos centraremos en este post.

Rendimiento JMeter - JMeter - SDOS

 

En JMeter, un plan de pruebas es una jerarquía de componentes en forma de árbol (panel de control de la izquierda). Cada nodo del árbol es un componente. A su vez, un componente es una instancia de un tipo de componente en la que quizás se han configurado algunas de sus propiedades (en el panel de control de la derecha).

Los diferentes componentes de los que puede constar un plan de pruebas son:

  • Test Plan. Es el tipo de componente que representa la raíz del árbol.
  • Thread Group. Representa un grupo de usuarios. En JMeter cada thread es un usuario virtual.
  • Controllers (Sampler, Logic Controler). Los samplers realizan peticiones contra la aplicación y los logic controlers establecen el orden en que se ejecutan éstos.
  • Config Element. Establecen propiedades de configuración que se aplican a los samplers a los que afectan.
  • Assertion. Comprueban condiciones que aplican a las peticiones que realizan contra la aplicación los samplers a los que afectan.
  • Listeners. Recopilan datos de las peticiones que realizan los samplers a los que afectan.
  • Timer. Añaden tiempo extra a la ejecución de las peticiones que realizan contra la aplicación los samplers a los que afectan
  • Pre-Processor element. Realizan acciones o establecen configuraciones previa a la ejecución de los samplers a los que afectan.
  • Post-Processor element. Realizan acciones o establecen configuraciones posteriormente a la ejecución de los samplers a los que afectan.

 

 

EJEMPLO BÁSICO CON JMETER

Para preparar el escenario de las pruebas en JMeter cargamos una plantilla. Vamos a File>Template. Se abre una pequeña ventana nueva para elegir qué plantilla deseamos cargar. Elegimos la primera (‘Recording‘). Ésta sirve para “grabar” la navegación de un sitio web.

Rendimiento JMeter - Defined variables - SDOS

 

Para nuestro ejemplo básico, podemos eliminar algunos componentes como ‘User Defined Variables‘, ‘HTTP Request Default‘ y ‘HTTP Cookie Manager‘. Para la recepción de los datos, botón derecho sobre ‘Thread Group‘ y Add>Listener>Graph Results. Podemos añadir algunos receptores de datos más. Nosotros, finalmente trabajamos con este esquema:

Rendimiento JMeter - Esquema - SDOS

 

Para la configuración, vamos a ‘HTTP(S) Test Script Recorder‘ y en el campo del puerto escribimos el que queramos usar. En nuestro caso, 8181.

Rendimiento JMeter - Settings Port - SDOS

 

Pulsamos, ahora, en ‘Thread Group‘ y en ‘Number of Threads‘ escribimos el número de usuarios concurrentes que queremos que hagan las peticiones. En nuestro caso, 10. En ‘Loop Count‘ (repeticiones) pondremos 100. Ya tendríamos configurado correctamente JMeter.

Rendimiento JMeter - Thread Group - SDOS

 

Antes de empezar a grabar, debemos configurar el proxy de nuestro navegador con el puerto que escribimos anteriormente y la dirección IP de nuestro equipo:

Rendimiento JMeter - Configuracion Proxy - SDOS

 

Ya tenemos todo listo para empezar a ‘grabar‘ las peticiones que hagamos desde nuestra aplicación. En JMeter, pulsamos sobre ‘HTTP(S) Test Script Recorder‘ y hacemos click en ‘Start‘. Ya estamos ‘escuchando’.

Rendimiento JMeter - Grabar peticiones - SDOS

 

Ya solo nos queda navegar a través de la web que queramos probar. Para nuestro ejemplo, hemos navegado en una página de prueba: Blazedemo.

Las peticiones se van guardando en nuestro Test Plan:

Rendimiento JMeter - Test plan - SDOS

 

Cuando tengamos las peticiones, paramos la grabación pulsando en ‘Stop‘. Finalmente, para ejecutar nuestro plan de pruebas simplemente hay que pulsar el botón de ‘Run‘.

Rendimiento JMeter - Ejecutar plan de pruebas - SDOS

 

Los resultados pueden observarse en los ‘Listeners‘ que añadimos anteriormente:

Rendimiento JMeter - Resultado listeners 1 - SDOS

 

Rendimiento JMeter - Resultado listeners 2 - SDOS

 

 

EJEMPLO BÁSICO CON JMETER + MAVEN

Para usar JMeter dentro de un proyecto Maven, vamos a utilizar el plugin jmeter-maven-plugin.

La configuración de éste en el archivo POM es la siguiente:

<plugins>
	<plugin>
		<groupId>com.lazerycode.jmeter</groupId>
		<artifactId>jmeter-maven-plugin</artifactId>
		<version>2.7.0</version>
		<executions>
			<execution>
				<id>jmeter-tests</id>
				<goals>
					<goal>jmeter</goal>
				</goals>
				<phase>verify</phase>
			</execution>
		</executions>
		<configuration>
				
			<generateReports>false</generateReports>
			<resultsFileFormat>xml</resultsFileFormat>
			<testResultsTimestamp>false</testResultsTimestamp>
					
		</configuration>
	</plugin>

 

Por defecto, JMeter crea un reporte a través de un archivo .csv. Para que esto no ocurra tenemos que poner a false el generateReports. El siguiente plugin que vamos a utilizar necesita leer los datos de un archivo .xml, de ahí la configuración de resultFileFormat.

El otro plugin que usamos es jmeter-graph-maven-plugin que nos mostrará los distintos resultados en forma de gráficas. En el archivo POM indicamos cuál será el archivo de entrada y los de salida que corresponderá a cada una de las gráficas que añadamos:

<plugin>
	<groupId>de.codecentric</groupId>
	<artifactId>jmeter-graph-maven-plugin</artifactId>
	<version>0.1.0</version>
	<executions>
		<execution>
			<id>create-graphs-collection</id>
			<goals>
				<goal>create-graph</goal>
			</goals>
			<phase>verify</phase>
			<configuration>
				<inputFile>${project.build.directory}/jmeter/results/EjemploBlaze.jtl</inputFile>
				<graphs>
					<graph>
						<pluginType>ThroughputVsThreads</pluginType>
						<width>1920</width>
						<height>1080</height>
						<outputFile>${project.build.directory}/jmeter/results/ThroughputVsThreads.png</outputFile>
					</graph>
					<graph>
						<pluginType>ResponseCodesPerSecond</pluginType>
						<width>1920</width>
						<height>1080</height>
						<outputFile>${project.build.directory}/jmeter/results/ResponseCodesPerSecond.png</outputFile>
					</graph>

 

Las distintas gráficas y su significado pueden verse en jmeter-plugins.org.

Para ejecutar nuestro plan de pruebas de JMeter, debemos guardarlo dentro de /src/test/jmeter del proyecto Maven. Desde la terminal, accedemos a la raíz del proyecto Maven y ejecutamos: $mvn verify.

Una vez ejecutado, aparecerá algo como:

Rendimiento JMeter - Maven - SDOS

 

Y las gráficas aparecerán donde indicamos en la configuración del plugin. Estos son algunos ejemplos:

  • Bytes throughput over time. Cantidad de bytes enviados y recibidos por JMeter durante la prueba de carga.
    Rendimiento JMeter - Bytes throughput over time - SDOS

 

  • Server hits per second. Hits enviados por el plan de prueba al servidor por segundo.
    Rendimiento JMeter - Server hits per second - SDOS

 

  • Response codes per second. Código de respuesta por segundo devuelto durante la prueba.
    Rendimiento JMeter - Response codes per second - SDOS

 

El código de este proyecto lo puedes encontrar en nuestro repositorio.

 

 

EN RESUMEN

Está claro que las pruebas funcionales son las más importantes, ya que son las que garantizan que la aplicación realizará las funciones marcadas por el cliente. Pero asegurar la calidad de una aplicación es mucho más que eso.

Por esto, QA y desarrolladores tienen que colaborar estrechamente no sólo para que la aplicación haga esta cosa o la otra, sino también para que lo haga en el mínimo de tiempo posible. Ahí puede estar la diferencia entre una buena aplicación y otra mejor, entre una buena y mejor satisfacción del cliente.

En definitiva, no sólo de pruebas funcionales vive el QA.