Incluyendo Tests de SOAP UI dentro ciclo de vida de Maven

1
3802

En este tutorial vamos a ver cómo podemos ejecutar los tests de SoapUI dentro del ciclo de vida de Maven.

Índice de contenidos

1. Introducción

En este tutorial vamos a incluir tests de SOAP UI punto a punto dentro del ciclo de vida de Maven.

Para escribir este tutorial nos estamos basando en uno hecho por Alberto Moratilla donde hacía tests unitarios atacando a servicios REST.

En este tutorial intentamos aportar un ejemplo similar al de Alberto, atacando a servicios SOAP desarrollados con Spring Boot, además de la incorporación de casos de uso en nuestro proyecto de SOAP UI utilizando el TestCaseEditor que nos posibilita validar los diferentes casos de uso de nuestro desarrollo.

La motivación de este tutorial viene dada porque nosotros trabajamos con metodologías Agiles (Scrum). En Scrum intentas entregar valor al cliente en pequeños plazos de tiempo. Esos plazos de tiempo se llaman Sprint. En cada final de Sprint se realiza una demo al cliente donde se verifica el correcto funcionamiento del software entregado validando diferentes casos de uso. Para los desarrollos de WS solemos utilizar SOAP UI para demostrarle al cliente que el proyecto se comporta conforme a lo esperado. Pensamos que seria interesante utilizar esos proyectos de SOAP UI no sólo en la demo, e intentar integrarlos dentro del ciclo de vida de Maven para nuestro proyecto.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: MacBook Pro Retina 15′ (2,5 Ghz Intel Core i7, 16GB DDR3).
  • Sistema Operativo: Mac OS Sierra 10.12.5.
  • Entorno de desarrollo: Eclipse Neon.2 Release (4.6.2).
  • Java 1.8
  • Apache Maven 3.3.9
  • SOAP UI 5.3.0
  • Docker version 17.03.1-ce, build c6d412e
  • Docker Machine version 0.10.0, build 76ed2a6

3. Preparando el proyecto de SOAP UI

Un proyecto de SOAP UI se puede descomponer en «test suite». En nuestro caso, había un «test suite» por cada demostración o Sprint. Un «test suite» contiene varios «test cases». Un caso de uso podría ser la cancelación de una reserva de hotel, lo que implica dos operaciones al menos (alta y cancelación de la reserva). Y a su vez, un test case se compone de uno o varios «test steps». En nuestro ejemplo anterior habría un paso por cada operación.

Si no estas muy familiarizado con SOAP UI, te recomiendo que le eches un vistazo al siguiente tutorial antes.

3.1. El servidor

Como servidor utilizaremos una modificación del WS propuesto por Christoph Burmeister en su blog, incluyendo la operación de añadir ciudades.Nuestro WS tendrá dos operaciones:

  • getCityByCode: Devuelve el nombre de la ciudad, país, año en el que se fundo, código postal y población de un código de postal dado.
  • addCity: Dados el nombre de la ciudad, país, año en el que se fundó, código postal y población. Se habrá insertado correctamente si devuelve el código postal

El código del servidor lo podéis encontrar en mi repositorio de github.

Antes de desplegar el servicio SOAP es necesario levantar la BBDD de la que depende. Para ello, nosotros hemos optado por levantar un contenedor de docker de mysql.Para ello, abrimos un terminal, posicionándonos en /src/main/resources/ del proyecto ejecutamos el siguiente comando (cambiando la ruta a la que se referencia en el volumen):

$> docker run --name mysql -p 3306:3306 -v /Users/ddelcastillo/Downloads/CitiesWS/src/main/resources/data:/docker-entrypoint-initdb.d -e MYSQL_ROOT_PASSWORD=root -d mysql:5.6

Este comando nos precarga las siguientes ciudades en nuestro servicio:

3.2. Preparando los tests de SOAP UI

Nuestro proyecto de SOAP UI tendrá los siguientes casos de uso dentro del TestSuite «Tuto_CitiesWS» :

  • Casos de Uso OK:
    • getCityByCode: Consultar por una ciudad que exista.
    • addCity: Añadir una ciudad que no exista.
  • Caso de Uso KO:
    • getCityByCodeResponse: Consultar por una ciudad que no exista.
    • addCity: Intentar añadir una ciudad que exista.
  • Casos de Uso con TestCase Editor:
    • Inserta y Consultar (TestCase IC): Insertar una ciudad que no existe y consultar por la ciudad recién insertada.
    • Consultar, Insertar y Consultar (TestCase CIC): Consultar por una ciudad que no existe, insertarla y volver a consultar.

4. Creando el proyecto de Maven

Como podéis ver en el proyecto Maven de ejemplo, dentro de src/test/resources tenemos el proyecto de SOAP UI al que haremos referencia en los tests de JUnit.

4.1. Incluyendo dependencias

Las dependencias necesaria para utilizar tests de SOAP UI es la siguiente, tal y como podéis ver en el pom.xml

<dependency>
	<groupId>com.smartbear.soapui</groupId>
	<artifactId>soapui</artifactId>
	<version>5.2.1</version>
</dependency>

4.2. Creando perfil para los tests de SOAP UI

Debido a que los tests pueden penalizar por su tiempo de ejecución y por unos errores en tiempo de ejecución que comentaremos en el apartado 5.3. Hemos decido crear un perfil que únicamente ejecute los tests SOAP UI. Este perfil se podría ejecutar «bajo demanda» o incluir dentro del proceso de «liberación de Release».

Los cambios necesarios en el pom.xml para excluir estos test a únicamente el uso de este perfil de Maven son los siguientes:

<profiles>
	...
	<profile>
		<id>soapui</id>
		<properties>
			<environment.profile>soapui integration</environment.profile>
			<environment.name>Integration environment for soapui</environment.name>
			<skip.integration.tests>false</skip.integration.tests>
			<skip.unit.tests>true</skip.unit.tests>
		</properties>
		...
		<build>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-failsafe-plugin</artifactId>
					<executions>
						<execution>
							<id>integration-tests</id>
							<goals>
								<goal>integration-test</goal>
								<goal>verify</goal>
							</goals>
						</execution>
					</executions>

					<configuration>
						<argLine>-Dfile.encoding=${project.build.sourceEncoding}
							${failsafe.argLine}</argLine>
						<skipITs>${skip.integration.tests}</skipITs>
						<includes>
							<include>**/*SoapUITest.java</include>
						</includes>
						<excludes>
							<exclude>**/*IT.java</exclude>
							<exclude>**/*IntegrationTest.java</exclude>
						</excludes>
					</configuration>
				</plugin>
			</plugins>
		</build>
	</profile>
	...
</profiles>

5. Creando los tests de JUnit

En este punto podemos diferenciar dos métodos para ejecutar nuestros tests:

  • Ejecutar todos los casos de uso del proyecto de SOAP UI.
  • Ejecutar un caso de uso específico.

Como peculiaridad, en el apartado de caso de uso específico, crearemos un caso de uso que enlace dos pasos (operaciones) utilizando TestCase Editor de SOAP UI.

5.1. Ejecución de todo el proyecto de SOAP UI

Tal y como comenta Alberto en su tutorial, lo malo de ejecutar todos los casos de uso de un proyecto es que no puedes hacer asserts dentro del test de JUnit. El código para ejecutar todos los casos de uso sería el siguiente:

@Test
public void shouldExecuteAllTestCases() throws Exception {
	cityService.deleteCityByCode(1);
	SoapUITestCaseRunner runner = new SoapUITestCaseRunner();

	runner.setProjectFile(TEST_FILE);
	runner.setEndpoint("http://localhost:".concat(port + "").concat("/ws/cities"));
	runner.setPrintReport(true);
	runner.setJUnitReport(true);
	runner.setExportAll(true);
	runner.setOutputFolder("./target/surefire-reports");
	runner.setIgnoreError(true);
	runner.run();
}

Como podéis ver en el test, establecemos una serie de propiedades de configuración y para la generación de informes, de la misma manera que podríamos hacerlo en la opción «Launch TestRunner» de la parte gráfica, tal y como se puede ver en las siguientes imágenes:

5.2. Ejecución de un Test Case específico

La única diferencia entre este test y el anterior es que aquí le especificamos en las propiedades el caso de uso a ejecutar y podemos evaluar el test con asserts, tal y como se puede ver:

@Test
public void shouldExecuteICTestCase() throws Exception{
	long insertCode = 1;

	SoapUITestCaseRunner runner = new SoapUITestCaseRunner();

	cityService.deleteCityByCode(1);
	runner.setProjectFile(TEST_FILE);
	runner.setEndpoint("http://localhost:".concat(port + "").concat("/ws/cities"));
	runner.setPrintReport(true);
	runner.setJUnitReport(true);
	runner.setExportAll(true);
	runner.setOutputFolder("./target/surefire-reports");
	runner.setIgnoreError(true);
	runner.setTestSuite("Tuto_CitiesWS");
	runner.setTestCase("TestCase IC");
	runner.run();
	City city = cityService.getCityByCode(insertCode);
	assertNotNull(city);
	assertEquals(insertCode,city.getCode());
	assertEquals("TomorrowLand",city.getName());
	assertEquals("Chiquitistan",city.getCountry());
	assertEquals(1,city.getFounded());
	assertEquals(1,city.getPopulation());
}

El caso de uso que ejecutamos en este test conlleva la llamada de dos operaciones del WS (de Inserción y Consulta). Insertamos una nueva ciudad y consultamos por ella misma. Para realizar todos estos pasos y relacionar las operaciones en el caso de uso, utilizamos TestCase Editor, tal y como se puede ver en la siguiente imagen:

5.3. Errores al ejecutar los tests

Si habéis ejecutado el perfil de SOAP UI con Maven con el siguiente comando:

$> mvn clean install -P soapui

Os habrán salido un montón de errores aunque los tests se ejecuten satisfactoriamente como se puede ver:

Buscando por internet el error, vimos que nos faltaban unas clases que encontramos en este repositorio. Al empaquetarlas vimos que los errores dejaban de salir pero al ver que se hacia referencia a la version de pago de SOAP UI y viendo que los errores no eran bloqueantes, ya que los tests pueden ejecutarse. Optamos por la opción de crear un perfil solo para estos test.

Aun así, tal y como dice Alberto en su tutorial, no se recomienda el uso de estos tests en entornos productivos.

6. Conclusiones

Hemos visto como incorporar tests de SOAP UI a algo relativamente nuevo (SpringBoot) desarrollando algo relativamente viejo (WS SOAP). Se que son pocas diferencias con respecto al Tutorial de Moratilla pero como diría Newton:

Si he visto un poco más lejos es porque me he elevado a hombros de gigantes.

Y si necesitáis una justificación un poco mas contemporánea:

No he copiado el libro, seguro que ha sido un virus o algún error informático (Ana Rosa).

Espero haberos aportado algo más ;).

7. Referencias

1 COMENTARIO

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad