Está en la página 1de 31

PORTADA

ÍNDICE

1. INTRODUCCIÓN....................................................................................................................5
2. PRUEBAS DE INTEGRACIÓN..................................................................................................6
2.1. ¿Por qué realizar pruebas de integración?...................................................................7
2.2. Ventajas de las pruebas de integración........................................................................8
2.3. Desafíos de las pruebas de integración........................................................................8
2.4. Directrices para las pruebas de integración.................................................................8
2.5. Técnicas de prueba de integración...............................................................................9
2.6. Mejores prácticas para pruebas de integración...........................................................9
2.7. Un ejemplo de prueba de integración........................................................................10
2.8. Ejemplo Prueba de integración con C# y Docker........................................................10
2.9. Implementar la base de datos en Docker...............................................................10
2.10. Creación de un test de integración con Visual Studio.........................................12
2.11. Integración y pruebas incrementales.....................................................................15
2.12. ¿En qué orden llevamos a cabo la integración de los componentes?....................16
3. TIPOS DE PRUEBAS DE INTEGRACIÓN................................................................................16
3.1. Integración descendente............................................................................................16
3.2. Integración ascendente..............................................................................................17
3.3. Integración Ad-hoc.....................................................................................................18
3.4. Integración del esqueleto...........................................................................................18
4. PRUEBAS DE INTERFACES...................................................................................................19
5. PRUEBAS DE ESFUERZO O RENDIMIENTO..........................................................................22
5.1. ¿Qué son las pruebas de esfuerzo?............................................................................22
5.2. Tipos de pruebas de esfuerzo o rendimiento.............................................................23
5.2.1. Pruebas de carga................................................................................................23
5.2.2. Pruebas de estrés...............................................................................................23
5.2.3. Pruebas de capacidad.........................................................................................23
5.2.4. Pruebas de escalabilidad....................................................................................24
5.2.5. Spike testing.......................................................................................................24
5.2.6. Pruebas de resistencia........................................................................................24
5.2.7. Pruebas de concurrencia....................................................................................24
5.3. Qué objetivos tienen las pruebas de rendimiento......................................................25
5.4. Herramientas para realizar pruebas de rendimiento.................................................25
6. CONCLUSIÓN......................................................................................................................27
7. GLOSARIO DE TÉRMINOS...................................................................................................28
8. BIBLIOGRAFÍA.....................................................................................................................30

3
ÍNDICE DE ILUSTRACIONES
1. INTRODUCCIÓN

En el año 2012 se celebró el año de Turing coincidiendo con el centenario de su nacimiento. A


raíz de esto el periódico ‘El País’ publicó una noticia (Orejas, 2012) cuyo titular decía: ¿Es
posible construir software que no falle? El artículo continuaba explicando que hoy en día
estamos acostumbrados a que el software falle.

Al construir software habitualmente se cometen errores. En la industria, la técnica para


solucionar los problemas derivados de dichos errores, serán las pruebas de software (‘testing’),
que consistirán en una serie de pasos realizados antes y después de la construcción de este
software.

Históricamente, por la ausencia o por la incorrecta realización de las pruebas de software, se


han producido varios desastres que han llegado, no solo a tener consecuencias económicas
nefastas, sino a producir la pérdida de vidas humanas.

Las pruebas son parte fundamental de cualquier proyecto, ya que nos ayudarán a tener
mejores resultados, ofreceremos una calidad mayor de nuestro producto y en consecuencia
los clientes estarán más satisfechos.

Según (Terra, 2022) los consumidores de hoy quieren más software, quieren que haga más y lo
quieren ahora. Como resultado, algunos desarrolladores tienden a apresurar las
pruebas, argumentando que es mejor lanzar software malo en la fecha de lanzamiento (o lo
más cerca posible) que retrasarlo por mucho tiempo.

Sin embargo, el software defectuoso puede provocar pesadillas catastróficas de relaciones


públicas y reacciones violentas. Por lo tanto, los desarrolladores deben lanzar software y
aplicaciones que hayan sido probadas exhaustivamente.

Con ese fin, hoy nos estamos enfocando en un aspecto específico de las pruebas: las pruebas
de integración. En esta investigación se define las pruebas de integración, por qué son
necesarias, el enfoque correcto, las mejores prácticas y directrices para las pruebas de
integración, técnicas, herramientas, e incluso un ejemplo de prueba de integración.

5
2. PRUEBAS DE INTEGRACIÓN

Las pruebas de integración son el segundo nivel de las pruebas dentro del modelo en V,
después de las pruebas unitarias o pruebas de componentes.

La diferencia entre las pruebas de integración y las pruebas unitarias radica en que las
primeras ejercitan la capacidad de dos, o más, componentes de software para funcionar
conjuntamente, lo que también se conoce como su "integración". Estas pruebas funcionan en
un espectro más amplio del sistema que se prueba, mientras que las unitarias se centran en
componentes individuales. Las pruebas de integración suelen incluir problemas con la
infraestructura. (Microsoft, s.f.)

En casi toda la documentación consultada, se hacen siempre la siguiente pregunta: ¿por qué
las pruebas de integración son necesarias si ya hemos probado que los componentes
individualmente funcionan? Aunque los componentes funcionen bien individualmente, puede
darse el caso de que al juntar los diferentes componentes del sistema ocurran errores que no
teníamos contemplados en un primer momento. (Sánchez Peño, 2015)

Ilustración 1. Modelo en V (Schaefer, Linz, & Spillner, 2014)

Se utiliza el modelo en V como referencia para ver cómo se integran las pruebas dentro del
ciclo de vida del software. En la ilustración 1 vemos que contiene dos ramas, una representa
las actividades de desarrollo (izquierda) y la otra representa las actividades de integración y
pruebas (derecha). (Sánchez Peño, 2015)

El ISTQB nos dice que las pruebas de integración se ocupan de probar las interfaces entre los
componentes, las interacciones con distintas partes de un mismo sistema, como el sistema
operativo, el sistema de archivos, el hardware y las interfaces entre varios sistemas. (Sánchez
Peño, 2015)

6
Implican la verificación de componentes individuales o unidades de un proyecto de software
en busca de defectos y problemas para verificar que funcionen juntos según lo planeado.
(Terra, 2022)

Se definen como un tipo de prueba en la que los módulos de software están lógicamente
integrados y se prueban como un grupo. Un proyecto de software usualmente consta de varios
módulos codificados por diferentes programadores. El propósito de este nivel de prueba es
detectar defectos en la interacción entre estos módulos de software cuando están integrados.
(Hamilton, 2022)

Para realizar este tipo de prueba, se hace uso de objetos que simulen en muchos casos los
datos que contenga la aplicación como, por ejemplo: stubs, drivers, subsistemas, bases de
datos, API’s, microservicios, etc. (Moreno Ó. , 2019)

Generalmente, un proyecto de software típico consta de muchos módulos de software,


muchos de los cuales son creados por diferentes programadores. Las pruebas de integración le
muestran al equipo cómo estos diferentes elementos funcionan juntos. Después de todo, cada
unidad puede funcionar por separado, pero la pregunta sigue siendo: "¿Pero pueden
ensamblarse y funcionar sin problemas?"

Por lo tanto, las pruebas de integración son nuestra forma de determinar si las diferentes
partes de una aplicación de software funcionan bien juntas. (Terra, 2022)

2.1. ¿Por qué realizar pruebas de integración?

Además de la verdad fundamental de que los desarrolladores deben probar todas las
aplicaciones de software antes de lanzarlas al público, existen algunas razones específicas por
las que los desarrolladores deben realizar pruebas de integración.

 La incompatibilidad entre módulos de software puede causar errores.


 Los desarrolladores deben confirmar que cada módulo de software puede interactuar
con la base de datos.
 Los requisitos cambian, gracias a la intervención del cliente. Sin embargo, tal vez esos
nuevos requisitos aún no se hayan probado a fondo y deberían serlo.
 Cada desarrollador de software tiene su comprensión y lógica de programación. Las
pruebas de integración aseguran que estas diversas unidades funcionen sin problemas.
 Puede haber problemas potenciales con la compatibilidad del hardware.
 Los módulos a menudo interactúan con API o herramientas de terceros, por lo que
necesitamos pruebas de integración para verificar que los datos que aceptan estas
herramientas son correctos.

(Terra, 2022)

7
2.2. Ventajas de las pruebas de integración

 Las pruebas de integración aseguran que cada módulo integrado funcione


correctamente.
 Las pruebas de integración descubren errores de interfaz.
 Los evaluadores o (‘testers’) pueden iniciar las pruebas de integración una vez que se
completa un módulo y no es necesario esperar a que se complete otro módulo y esté
listo para la prueba.
 Los evaluadores pueden detectar errores, defectos y problemas de seguridad.
 Las pruebas de integración brindan a los evaluadores un análisis integral de todo el
sistema, lo que reduce drásticamente la probabilidad de problemas graves de
conectividad. (Terra, 2022)

2.3. Desafíos de las pruebas de integración

Desafortunadamente, las pruebas de integración también tienen algunas dificultades que


superar.

 Si la prueba implica tratar con dos sistemas diferentes creados por dos proveedores
diferentes, habrá preguntas sobre cómo estos componentes se afectarán e
interactuarán entre sí.
 La integración de sistemas nuevos y legacy exige muchos esfuerzos de prueba y
cambios potenciales.
 Las pruebas de integración se vuelven complejas debido a la variedad de componentes
involucrados (por ejemplo, plataformas, entornos, bases de datos).
 Las pruebas de integración requieren probar no solo los enlaces de integración sino
también el entorno en sí mismo, lo que agrega otra capa de complejidad al proceso.

(Terra, 2022)

2.4. Directrices para las pruebas de integración

Si está intentando realizar pruebas de integración, tenga en cuenta estas pautas:

 En primer lugar, no inicie las pruebas de integración hasta que cada módulo se haya
sometido primero a pruebas funcionales.
 Las pruebas de módulos deben seguir una secuencia aceptada para no pasar por alto
ningún escenario de integración.
 Acordar una estrategia de caso de prueba para preparar y ejecutar casos de prueba
junto con los datos de prueba.
 Estudie la arquitectura y la estructura de la aplicación, identificando los módulos más
importantes que se probarán primero. Además, identifique todos los escenarios
posibles.
 Diseñe casos de prueba que crearán una verificación detallada de la interfaz.
 La entrada de datos es fundamental para la realización de pruebas de integración
confiables, así que elija sabiamente las entradas de ejecución de su caso de prueba.

8
 Crear un informe sobre los errores o bugs encontrados. Envíe un informe sobre dichos
errores al desarrollador, pídale que los corrija y vuelva a probar.

(Terra, 2022)

2.5. Técnicas de prueba de integración

Existen muchas técnicas diferentes de prueba de software reconocidas que los desarrolladores
pueden usar en las pruebas de integración. A continuación, se muestra una colección de
algunas técnicas comunes disponibles en las pruebas de software. Estos métodos no deben
confundirse con los tipos de pruebas de integración.

Pruebas de caja negra

 Pruebas de todos los pares


 Análisis de valor límite
 Gráfico de causa y efecto
 Técnica de la tabla de decisiones
 Partición de equivalencia
 Adivinando errores
 Técnica de transición de estado

Pruebas de caja blanca

 Pruebas de Cobertura de Sucursales


 Pruebas de flujo de control
 Pruebas de flujo de datos
 Prueba de cobertura de decisiones

(Terra, 2022)

2.6. Mejores prácticas para pruebas de integración

Antes de comenzar las pruebas de integración, tenga en cuenta las siguientes prácticas
recomendadas.

 Inicie las pruebas de integración lo antes posible


 Determine qué estrategia de prueba desea utilizar
 Estudie el diseño arquitectónico de la aplicación e identifique los módulos críticos
 Asegúrese de tener datos simulados o (‘mock data’) a la mano
 Toma y guarda notas. Registrar extensivamente

(Terra, 2022)

9
2.7. Un ejemplo de prueba de integración

Aquí hay un ejemplo de integración de pruebas que involucran un sitio web que presenta
funciones de "Página de inicio de sesión", "Buzón de correo" y "Eliminar correos electrónicos".

ID de caso de prueba Objetivo del caso de Descripción del caso Resultado Esperado
prueba de prueba
1 Validar el inicio de Ingrese las El control se
sesión y el enlace de credenciales de transfiere al buzón.
la interfaz del inicio de sesión
módulo del buzón. requeridas y haga
clic en el botón de
inicio de sesión.
2 Validar el buzón y los Seleccione un correo El correo electrónico
enlaces de la interfaz electrónico del elegido se envía a la
del módulo Eliminar buzón, luego haga carpeta
correos. clic en "eliminar". Eliminado/Papelera.

2.8. Ejemplo Prueba de integración con C# y Docker

El motivo por el que vamos a implementar las pruebas de integración con Docker es porqué
para su ejecución necesitamos una base de datos completamente limpia, para comprobar que
nuestros casos y nuestro escenario funciona correctamente.

Este método nos permite además en caso de tener CI/CD repetiremos el proceso en uno de los
pasos, asegurándonos que el código en su conjunto también funciona en el servidor o en la
nube.

2.9. Implementar la base de datos en Docker

Primero que nada, decir que NO es recomendable tener una base de datos en Docker para
producción, pero obviamente si para las pruebas.

La idea principal es replicar nuestro servidor de bases de datos en una máquina, pero gracias a
Docker no necesitamos una máquina como tal, sino que simplemente hacemos la imagen y la
corremos. En ella indicamos la base de datos y la contraseña.

FROM mysql:5.6

10
ENV MYSQL_DATABASE webpersonal
ENV MYSQL_ROOT_PASSWORD=test

## todos los scripts en docker-entrypoint-initdb.d/ se


ejecutan automaticamente
COPY ./Database/ ./docker-entrypoint-initdb.d/

Sobre esta imagen de Docker con MySQL ya corriendo, debemos ejecutar los ficheros sql que
componen la base de datos.

Podemos hacer este paso tanto en la imagen como tal, creando una aplicación de consola
en .Net, o en un pequeño script de PowerShell.

En este caso, en un pequeño script de PowerShell el cual deberá ser ejecutado antes de
empezar a trabajar con las pruebas de integración. Ya que no solo ejecuta los ficheros SQL,
sino que inicializa la imagen de Docker.

##Copiar ficheros de la base de datos


$source = "src/Database"
$destino = "Tools/ServerMysql"

Copy-Item -Path $source -Filter "*.sql" -Recurse -


Destination $destino -Container -force

##Borrar la imagen vieja


docker rm $(docker stop $(docker ps -a -q --filter
ancestor='server-mysql' --format="{{.ID}}"))

##construir la imagen
docker build -t server-mysql Tools\ServerMysql\.

##iniciar el contenedor
docker run -d -p 4306:3306 server-mysql

11
observamos que estamos indicando el puerto que va a estar escuchando, en MySQL el normal
es 3306 pero es probable que tengamos un MySQL corriendo en nuestro ordenador, con lo
que en ese caso podemos utilizar uno random cualquiera, para este caso 4306.

Se debe buscar este fichero en el sitio correcto, en este caso, será en la raíz del proyecto y ahí
una carpeta llamada Tools donde incluiremos todo aquello que utilizamos para hacernos la
vida más sencilla, pero no es directamente parte del código como tal.

Por cierto, se recomienda correr los scripts directamente desde la raíz del proyecto.

Por lo tanto, ejecutaremos el siguiente comando para construir nuestro servidor MySQL con la
información necesaria en un contenedor de Docker:

PS C:\repos\WebPersonal> .\Tools\ServerMySql\
BuildServerAndRun.ps1

2.10. Creación de un test de integración con Visual Studio

Para crear una prueba de integración en Visual Studio se debe crear un proyecto de test y a
este llamarlo <<TestDeIntegracion>>.

Por supuesto debemos crearlo en su carpeta correspondiente.

La idea de las pruebas de integración es cubrir todo el sistema, tanto Front como Back End, en
este caso por ahora no se tiene Front End, lo que no quiere decir que nos libremos de hacer las
pruebas de integración, sino que cuando el Front End esté listo, habrá que hacer una
refactorización.

Primero de todo se debe tener en cuenta que, si nuestro proyecto utiliza inyección de
dependencias deberemos inyectar estas dependencias en nuestro test.

private IServiceCollection BuildDependencies()


{

12
IServiceCollection services = new ServiceCollection();
services.AddScoped<DbConnection>(x
=> new
MySqlConnection("Server=127.0.0.1;Port=4306;Database=webpers
onal;Uid=root;password=test;Allow User Variables=True" ))
.AddScoped<TransactionalWrapper>()
.AddScoped<PersonalProfile>()
.AddScoped<PutPersonalProfile>()
.AddScoped<IGetPersonalProfileDependencies,
GetPersonalProfileDependencies>()
.AddScoped<IPutPersonalProfileDependencies,
PutPersonalProfileDependencies>()
.AddScoped<PersonalProfileRepository>()
.AddScoped<SkillRepository>()
.AddScoped<InterestsRepository>()
.AddScoped<UserIdRepository>();

return services;
}

Se puede observar además que la conexión MySQL está apuntando a nuestro contenedor
Docker. Este paso también va a necesitar de refactorización cuando veamos una
implementación de los diferentes entornos.

Por lo tanto, se crea el test que comprobara que el Flow o el proceso funciona:

[Fact]
public async Task TestInsertPerfilPersonal_Then_ModifyIt()
{
IServiceCollection services = BuildDependencies();
using (ServiceProvider serviceProvider =
services.BuildServiceProvider())
{
string username = Guid.NewGuid().ToString();

PersonalProfileDto defaultPRofile =
BuildPersonalProfile(username);
var departmentAppService =
serviceProvider.GetRequiredService<PerfilPersonalController>
();
await departmentAppService.Post(defaultPRofile);

13
PersonalProfileDto userStep1 = await
departmentAppService.Get(username).ThrowAsync();
Assert.Empty(userStep1.Skills);
Assert.Equal(defaultPRofile.FirstName,
userStep1.FirstName);
Assert.Equal(defaultPRofile.Website,
userStep1.Website);
Assert.Equal(defaultPRofile.LastName,
userStep1.LastName);

SkillDto skill = new SkillDto()


{
Id = null,
Name = "nombre1",
Punctuation = 10m
};
userStep1.Skills.Add(skill);

InterestDto interest = new InterestDto()


{
Id = null,
Interest = "interes pero debe contener 15
caracteres"
};
userStep1.Interests.Add(interest);
var _ =await departmentAppService.Put(userStep1);

PersonalProfileDto userStep2 = await


departmentAppService.Get(username).ThrowAsync();

Assert.Single(userStep2.Skills);
Assert.Equal(skill.Name,
userStep2.Skills.First().Name);
Assert.Single(userStep2.Interests);
Assert.Equal(interest.Interest,
userStep2.Interests.First().Interest);
Assert.Equal(defaultPRofile.FirstName,
userStep2.FirstName);
Assert.Equal(defaultPRofile.Website,
userStep2.Website);
Assert.Equal(defaultPRofile.LastName,
userStep2.LastName);
}
}

private PersonalProfileDto BuildPersonalProfile(string


uniqueUsername)
{
return new PersonalProfileDto()

14
{
Description = "Description",
Email = "email",
FirstName = "firstName",
GitHub = "github",
Id = null,
Interests = new List<InterestDto>(),
LastName = "last name",
Phone = "telefono",
Skills = new List<SkillDto>(),
UserId = null,
UserName = uniqueUsername,
Website = "web"
};
}

Es muy común ejecutar los resultados contra la base de datos directamente, para este caso
particular “get” únicamente lee de la base de datos, por lo que el efecto y resultado son el
mismo.

(NETMENTOR, 2020)

Herramientas de prueba de integración

Algunas de las herramientas mencionadas a continuación que ayudan en una prueba de


integración:

 Rational Integration Tester


 Protractor (Protractor, s.f.)
 Steam
 TESSY (Razorcat, s.f.)

2.11. Integración y pruebas incrementales

Las pruebas de sistema implican integrar diferentes componentes y, después, probar el


sistema integrado que se creó. Siempre hay que usar un enfoque incremental para la
integración y las pruebas (es decir, se debe incluir un componente, probar el sistema, integrar
otro componente, probar de nuevo y así sucesivamente).

Esto significa que, si ocurren problemas, quizá se deban a interacciones con el componente
que se integró más recientemente.

La integración y las pruebas incrementales son fundamentales para los métodos ágiles como
XP, donde las pruebas de regresión se efectúan cada vez que se integra un nuevo incremento.

15
(Sommerville, 2011)

2.12. ¿En qué orden llevamos a cabo la integración de los componentes?

Para llevar a cabo estas pruebas en (Schaefer, Linz, & Spillner, 2014) nos muestran las
siguientes estrategias para la prueba de integración:

 Integración descendente.
 Integración ascendente.
 Integración Ad hoc.
 Integración del esqueleto.

3. TIPOS DE PRUEBAS DE INTEGRACIÓN

3.1. Integración descendente

La prueba de integración descendente es un enfoque incremental para la construcción de la


arquitectura del software. La prueba se iniciará con el componente de más alto nivel del
sistema que llama a otros componentes del sistema, pero no a sí mismo. La integración avanza
con componentes de nivel inferior. (Sánchez Peño, 2015)

Requiere que se prueben los módulos de más alto nivel e integren primero. Estas permiten que
la lógica de alto nivel y el flujo de datos se prueben temprano en el proceso y tiende a
minimizar la necesidad de drivers. Sin embargo, la necesidad de stubs complica la gestión de
pruebas y las utilidades de bajo nivel se verifican relativamente tarde en el ciclo de desarrollo.
Otra desventaja de las pruebas de integración de arriba hacia abajo o descendentes es su
pobre soporte para el lanzamiento temprano de funcionalidad limitada. (Integration Testing
cs.ccu.edu.tw)

16
Ilustración 2. Enfoque Descendente. (Integration Testing cs.ccu.edu.tw)

Pueden proceder de dos formas: integración primero en profundidad e integración primero en


amplitud.

Para una integración profunda, cada módulo se prueba con cada vez más detalle,
reemplazando más y más niveles de detalle con código real en lugar de stubs.
Alternativamente, la integración en amplitud primero procedería refinando todos los módulos
al mismo nivel de control en toda la aplicación. En la práctica se utilizaría una combinación de
las dos técnicas. (Integration Testing cs.ccu.edu.tw)

3.2. Integración ascendente

La prueba comienza con los componentes elementales del sistema que no requieren
componentes adicionales. Los subsistemas más grandes se ensamblan a partir de los
componentes probados. (Sánchez Peño, 2015)

Requiere que las unidades de nivel más bajo se prueben e integren primero. Estas unidades se
denominan con frecuencia módulos de utilidad. Mediante el uso de este enfoque, los módulos
de utilidad se prueban al principio del proceso de desarrollo y se minimiza la necesidad de
stubs. Sin embargo, la desventaja es que la necesidad de drivers complica la gestión de
pruebas y la lógica de alto nivel y el flujo de datos se pruebe tarde. Al igual que el enfoque
descendente, el enfoque ascendente también brinda un soporte deficiente para el
lanzamiento temprano de funcionalidad limitada. (Integration Testing cs.ccu.edu.tw)

17
Ilustración 3. Enfoque Ascendente. (Integration Testing cs.ccu.edu.tw)

3.3. Integración Ad-hoc

Los componentes se han integrado en el orden en que están terminados. Cuando un


componente ha pasado la prueba de componentes, se inicia la prueba de integración para ver
si encaja con otro componente ya probado y se inicia la prueba de integración.

3.4. Integración del esqueleto

Cuando un esqueleto o columna vertebral del sistema se ha terminado, los componentes se


integran gradualmente en él.

18
4. PRUEBAS DE INTERFACES

Algunas de las verificaciones que se realizan en las pruebas de integración son las pruebas de
interfaz. En la comprobación de las transferencias de datos entre dos componentes. Prueba de
interfaces como servicios web, API, entre otros; se realiza para verificar que los componentes
estén sincronizados entre sí. Ayudan a determinar que diferentes funciones, como la
transferencia de datos entre los diferentes elementos del sistema, se realizan de acuerdo con
la forma en que fueron diseñadas. (Vargas, s.f.)

En general, los componentes de software están constituidos por varios objetos en interacción.
Por ejemplo, en el sistema de la estación meteorológica, el componente de reconfiguración
incluye objetos que tratan con cada aspecto de la reconfiguración. El acceso a la funcionalidad
de dichos objetos es a través de la interfaz de componente definida. Por consiguiente, la
prueba de componentes compuestos tiene que enfocarse en mostrar que la interfaz de
componente se comporta según su especificación. Se puede suponer que dentro del
componente se completaron las pruebas de unidad sobre el objeto individual. (Sommerville,
2011)

Ilustración 4. Prueba de interfaz (Sommerville, 2011)

19
La figura 4 ilustra la idea de la prueba de interfaz de componente. Suponga que los
componentes A, B y C se integraron para crear un componente o subsistema más grande. Los
casos de prueba no se aplican a los componentes individuales, sino más bien a la interfaz del
componente compuesto, creado al combinar tales componentes. Los errores de interfaz en el
componente compuesto quizá no se detecten al poner a prueba los objetos individuales,
porque dichos errores resultan de interacciones entre los objetos en el componente.

Existen diferentes tipos de interfaz entre componentes de programa y, en consecuencia,


distintos tipos de error de interfaz que llegan a ocurrir:

 Interfaces de parámetro. Son interfaces en que los datos, o en ocasiones referencias


de función, pasan de un componente a otro. Los métodos en un objeto tienen una
interfaz de parámetro.
 Interfaces de memoria compartida. Son interfaces en que un bloque de memoria se
reparte entre componentes. Los datos se colocan en la memoria de un subsistema y
otros subsistemas los recuperan de ahí. Este tipo de interfaz se usa con frecuencia en
sistemas embebidos, donde los sensores crean datos que se recuperan y son
procesados por otros componentes del sistema.
 Interfaces de procedimiento. Son interfaces en que un componente encapsula un
conjunto de procedimientos que pueden ser llamados por otros componentes. Los
objetos y otros componentes reutilizables tienen esta forma de interfaz.
 Interfaces que pasan mensajes. Se trata de interfaces donde, al enviar un mensaje, un
componente solicita un servicio de otro componente. El mensaje de retorno incluye
los resultados para ejecutar el servicio. Algunos sistemas orientados a objetos tienen
esta forma de interfaz, así como los sistemas cliente-servidor.

Los errores de interfaz son una de las formas más comunes de falla en los sistemas complejos
(Lutz, 1993). Dichos errores caen en tres clases:

 Uso incorrecto de interfaz Un componente que llama a otro componente y comete


algún error en el uso de su interfaz. Este tipo de error es común con interfaces de
parámetro, donde los parámetros pueden ser del tipo equivocado, o bien, pasar en el
orden o el número equivocados de parámetros.
 Mala interpretación de interfaz Un componente que malinterpreta la especificación de
la interfaz del componente llamado y hace suposiciones sobre su comportamiento. El
componente llamado no se comporta como se esperaba, lo cual entonces genera un
comportamiento imprevisto en el componente que llama. Por ejemplo, un método de
búsqueda binaria puede llamarse con un parámetro que es un arreglo desordenado.
Entonces fallaría la búsqueda.
 Errores de temporización Ocurren en sistemas de tiempo real que usan una memoria
compartida o una interfaz que pasa mensajes. El productor de datos y el consumidor
de datos operan a diferentes niveles de rapidez. A menos que se tenga cuidado
particular en el diseño de interfaz, el consumidor puede acceder a información
obsoleta, porque el productor de la información no actualizó la información de la
interfaz compartida.

20
Las pruebas por defectos de interfaz son difíciles porque algunas fallas de interfaz sólo pueden
manifestarse ante condiciones inusuales. Por ejemplo, se dice que un objeto implementa una
cola como una estructura de datos de longitud fija. Un objeto que llama puede suponer que la
cola se implementó como una estructura de datos infinita y no verificaría el desbordamiento
de la cola, cuando se ingresa un ítem. Esta condición sólo se logra detectar durante las
pruebas, al diseñar casos de prueba que fuercen el desbordamiento de la cola, y causen que el
desbordamiento corrompa el comportamiento del objeto en cierta forma detectable.

Un problema posterior podría surgir derivado de interacciones entre fallas en diferentes


módulos u objetos. Las fallas en un objeto sólo se detectan cuando algún otro objeto se
comporta de una forma inesperada. Por ejemplo, un objeto llama a otro objeto para recibir
algún servicio y supone que es correcta la respuesta; si el servicio de llamada es deficiente en
algún modo, el valor devuelto puede ser válido pero equivocado. Esto no se detecta de
inmediato, sino sólo se vuelve evidente cuando algún cálculo posterior sale mal.

Algunos de los lineamientos generales para las pruebas de interfaz son:

1. Examinar el código que se va a probar y listar explícitamente cada llamado a un componente


externo. Diseñe un conjunto de pruebas donde los valores de los parámetros hacia los
componentes externos estén en los extremos finales de sus rangos. Dichos valores extremos
tienen más probabilidad de revelar inconsistencias de interfaz.

2. Donde los punteros pasen a través de una interfaz, pruebe siempre la interfaz con
parámetros de puntero nulo.

3. Donde un componente se llame a través de una interfaz de procedimiento, diseñe pruebas


que deliberadamente hagan que falle el componente. Diferir las suposiciones de falla es una
de las interpretaciones de especificación equivocadas más comunes.

4. Use pruebas de esfuerzo en los sistemas que pasan mensajes. Esto significa que debe
diseñar pruebas que generen muchos más mensajes de los que probablemente ocurran en la
práctica. Ésta es una forma efectiva de revelar problemas de temporización.

5. Donde algunos componentes interactúen a través de memoria compartida, diseñe pruebas


que varíen el orden en que se activan estos componentes. Tales pruebas pueden revelar
suposiciones implícitas hechas por el programador, sobre el orden en que se producen y
consumen los datos compartidos.

En ocasiones, las inspecciones y revisiones suelen ser más efectivas en costo que las pruebas
para descubrir errores de interfaz. Las inspecciones pueden concentrarse en interfaces de
componente e interrogantes sobre el comportamiento supuesto de la interfaz planteada
durante el proceso de inspección. Un lenguaje robusto como Java permite que muchos errores
de interfaz sean descubiertos por el compilador. Los analizadores estáticos son capaces de
detectar un amplio rango de errores de interfaz.

21
5. PRUEBAS DE ESFUERZO O RENDIMIENTO

Las pruebas de esfuerzo o rendimiento también llamadas (Performance Testing) son un tipo de
pruebas no funcionales, las cuales tienen en cuenta el comportamiento externo del software,
es decir cómo funciona el sistema, y se suelen utilizar técnicas de diseño de caja negra.
(Sánchez Peño, 2015)

Las ISO 25010 también define las características que han de tener estas pruebas que son
fiabilidad, factibilidad de uso, eficiencia, compatibilidad y seguridad. (Norma ISO 25010 - ISO,
s.f.)

Según (Myers, 2004), se han de tener en cuenta las siguientes características no funcionales en
las pruebas:

 Pruebas de carga: consisten en la medición del comportamiento del sistema para


aumentar la caga del mismo, ya sea mediante el número de peticiones que se realizan
a una WEB al mismo tiempo, el número de usuarios que trabajan simultáneamente.
 Pruebas de rendimiento: en estas pruebas se medirán la velocidad de procesamiento y
el tiempo de respuesta del sistema.
 Pruebas de volumen: se mide la capacidad del sistema para procesar gran cantidad de
datos, como procesar archivos con tamaños muy grandes.
 Pruebas de esfuerzo: se realizan pruebas donde se sobrecarga el sistema y se analiza la
capacidad de recuperación.
 Pruebas de seguridad: se realizan diferentes pruebas de accesos no autorizados,
ataque de denegación de servicio, etc.
 Pruebas de estabilidad, eficiencia, robustez: se realiza una medición de la respuesta
del sistema a los errores de funcionamiento.
 Pruebas de compatibilidad: son pruebas del funcionamiento del sistema con los
diferentes sistemas operativos, plataformas de hardware, etc., con los que interactúa
el programa.
 Pruebas de usabilidad: se mide la facilidad de uso, efectividad y satisfacción, siempre
dentro de un grupo específico de usuarios.

5.1. ¿Qué son las pruebas de esfuerzo?

Las pruebas de esfuerzo abarcan varios tipos de pruebas enfocados en el rendimiento y la


capacidad de respuesta de un sistema o componente bajo diferentes volúmenes de carga.

Dicho de otra forma, las pruebas de esfuerzo o rendimiento determinan cómo se comporta un
sistema en términos de respuesta y estabilidad sobre una carga de trabajo concreta.

22
Por ponerlas en contexto sobre otras pruebas, irían después de realizar las pruebas unitarias y
las pruebas de integración.

(Moreno O. , 2019)

5.2. Tipos de pruebas de esfuerzo o rendimiento

Existen varios tipos de pruebas de rendimiento, entre los que podríamos destacar:

5.2.1. Pruebas de carga


Las pruebas de carga son aquellas que se enfocan en la habilidad de un sistema para gestionar
niveles de carga (posibles en la realidad) de forma anticipada a que ocurran.

Se realizan a través del incremento de solicitudes generadas por un número controlado de


usuarios o procesos

5.2.2. Pruebas de estrés

En este caso, lo que se trata es de medir la capacidad que tiene un sistema o un componente,
para gestionar una carga máxima que, o bien está en su límite, o bien lo sobrepasa.

Se puede utilizar para medir la capacidad de dicho sistema o componente en caso de que no
disponga de suficientes recursos (como por ejemplo ancho de banda, procesador, memoria,
etc)

También se conocen como pruebas de esfuerzo.

5.2.3. Pruebas de capacidad

Estas pruebas son similares a las de estrés. Una carga se incrementa en un sistema
monitorizado sobre condiciones de fallo predeterminadas.

De esta forma, las pruebas de capacidad pueden medir el número, por ejemplo, de usuarios,
que se podrá tratar sin disminuir el rendimiento o, aunque lo haga, que no deje de cumplir los
objetivos mínimos establecidos.

23
5.2.4. Pruebas de escalabilidad

En las pruebas de escalabilidad, el objetivo es medir si un sistema será capaz de cumplir con los
objetivos de rendimiento posibles en un futuro.

Gracias a estas pruebas, es posible determinar si un sistema podrá crecer (aumentando el


número de usuarios y de conexiones concurrentes) sin que se produzcan errores o cumpliendo
las expectativas planificadas.

5.2.5. Spike testing

En este tipo de pruebas, el procedimiento se lleva a cabo, incrementando o reduciendo, de


forma repentina, la carga generada por un elevado número de usuarios, mientras se
monitoriza el comportamiento del sistema.

Con esta prueba, es posible ver si el rendimiento se ve afectado ante cambios drásticos e
inesperados de carga.

5.2.6. Pruebas de resistencia

En este caso, nos encontramos con un tipo de pruebas enfocadas en la estabilidad del sistema
durante un periodo de tiempo específico dentro de un contexto del sistema operativo
concreto.

Para que se entienda mejor, estas pruebas miden la capacidad del sistema para afrontar
situaciones concretas de demandas de recursos, es decir, que no haya fugas de memoria,
problemas con el número de las conexiones de bases de datos, grupos de hilos.

5.2.7. Pruebas de concurrencia

Las pruebas de concurrencia se centran en el impacto que podrían tener situaciones concretas
cuando ocurren de forma simultánea sobre un sistema.

Por ejemplo, un elevado número de software de terceros, realizando la misma llamada sobre
una API, o muchos usuarios enviando el mismo formulario de contacto.

(Moreno O. , 2019)

24
5.3. Qué objetivos tienen las pruebas de rendimiento

Las pruebas de rendimiento sirven para investigar, medir, validar o verificar otros atributos de
la calidad del sistema, como podrían ser la escalabilidad o la fiabilidad.

Sirven para mostrar si un sistema puede afrontar unos criterios de trabajo planificados para
situaciones futuras.

Además, también es útil para poder comparar dos sistemas o componentes, lo que podría
ayudarte a determinar cuál es más oportuno utilizar.

Por último, también te pueden ayudar a detectar qué partes de un sistema empiezan a fallar
primero ante un incremento de la carga recibida.

5.4. Herramientas para realizar pruebas de rendimiento

Las herramientas de pruebas de rendimiento incluyen las siguientes categorías:

 Generadores de carga: Estas herramientas, a través del IDE o editor de código, crean y
ejecutan varias instancias que simulan los comportamientos de clientes acuerdo a un
determinado perfil.
 Consola de gestión de la carga: Con este tipo de herramientas, se realizan las tareas
encargadas de iniciar o detener las determinadas cargas que aplicaremos al sistema
objeto de las pruebas.
 Herramientas de monitorización: Son imprescindibles ya que, gracias a ellas, es posible
supervisar, grabar y analizar el comportamiento del sistema ante las pruebas.

Las Herramientas de pruebas de rendimiento que se podrían destacar son:

JMeter

Es Opensource y quizá la más utilizada. Es un proyecto de Apache que puede medir el


desempeño de varios tipos de servicios, pero está orientada a aplicaciones web.

Puedes encontrar más información en su sitio web (Apache Software Foundation, s.f.)

LoadRunner

25
Esta herramienta es propietaria, está desarrollada por Micro Focus y apareció en 1993

Muy útil para las pruebas de concurrencia. Disponible en para Windows y Linux, en 11 idiomas,
y desde su versión 12.55 se pueden ejecutar scripts de Apache JMeter.

Puedes encontrar más información y solicitar una prueba gratuita en (Micro Focus, s.f.)

Neoload

Neoload también es software propietario, está desarrollado en Java, y disponible para


Windows, Linux, MacOS y Solaris.

Sus scripts se desarrollan a través de una interfaz de forma más intuitiva que con las anteriores
herramientas.

Destaca también por la velocidad de ejecución de sus pruebas.

Puedes ver más sobre esta herramienta o descargar una demo desde su página web (Tricentis,
s.f.)

26
6. CONCLUSIÓN

Las pruebas de integración son un proceso y un paso que debemos implementar a lo largo del
desarrollo para garantizar que nuestro código funcione correctamente cuando lo ponemos
todo junto. Son difíciles de implementar, porque se debe invertir mucho tiempo en
implementar todos los servicios relacionados (siempre que estén en el proyecto), como la base
de datos en Docker utilizada para este escenario. Por esta razón, necesitamos combinar las
pruebas de integración con las pruebas unitarias para probar completamente la aplicación.

Las pruebas de estrés se enfocan completamente en probar el sistema bajo condiciones de


carga extremas para encontrar su punto de ruptura y ver si se muestran los mensajes
apropiados cuando el sistema no responde. Destaca la memoria y el procesador durante el test
y verifica qué tan bien se recuperan.

La prueba de estrés es un tipo de prueba no funcional y generalmente se realiza después de la


prueba funcional. Cuando también existe un requisito de prueba de carga, esta prueba se
puede realizar como el caso extremo de prueba de carga. El 90% de las veces, la misma
herramienta de automatización se puede utilizar para pruebas de carga y estrés.

27
7. GLOSARIO DE TÉRMINOS

 Bug: Puede definirse como un error de codificación que causa una falla o defecto
inesperado. En otras palabras, si un programa no funciona según lo previsto, lo más
probable es que se trate de un bug. (Padmini)
 CI/CD: En ingeniería de software, CI/CD o CICD generalmente refiere a las prácticas
combinadas de integración continua y entrega continua (también conocida como
despliegue continuo). (Heller, s.f.)
 Stubs & Drivers: Programas ficticios en las pruebas de integración utilizados para
facilitar la actividad de prueba de software. No implementan toda la lógica de
programación del módulo de software, pero simulan la comunicación de datos con el
módulo de llamada durante la prueba. Estos programas actúan como sustitutos de los
modelos que faltan en las pruebas. (Hamilton, 2022)
o Stubs
 Es una pieza de código que simula la actividad de una unidad de nivel
inferior no disponible. Se necesitan stubs en el enfoque de arriba hacia
abajo. (Integration Testing cs.ccu.edu.tw)
 Genera entradas predeterminadas para el Sistema bajo prueba. Permite
ejercitar rutas en el código no probadas. Hay dos tipos:
o Respondedor: Inyecta valores válidos.
o Saboteador: Inyecta errores o excepciones. (Zapata, 2021)
 Es llamado por el Módulo bajo Prueba. (Hamilton, 2022)

Ilustración 5. Implementando pruebas descendentes.

 Drivers
 Un controlador es una pieza de código que pasa un caso de prueba a una
unidad de nivel inferior disponible. Se necesitan controladores en el
enfoque de abajo hacia arriba. (Integration Testing cs.ccu.edu.tw)
 Llama al Módulo a probar. (Hamilton, 2022)

28
Ilustración 6. Implementando pruebas ascendentes.

 Mocks:

29
8. BIBLIOGRAFÍA

Referencias de libros:

Myers, G. J. (2004). The art of software testing. New Jersey: John Wiley & Sons, Inc.

Sánchez Peño, J. M. (2015). Pruebas de Software. Fundamentos y Técnicas. MADRID:


UNIVERSIDAD POLITÉCNICA DE MADRID.

Schaefer, H., Linz, T., & Spillner, A. (2014). Software testing foundations. Santa Barbara, USA:
Rocky Nook Inc.

Sommerville, I. (2011). INGENIERÍA DE SOFTWARE Novena edición. México: PEARSON


EDUCACIÓN.

Referencias en internet:

Apache Software Foundation. (s.f.). Obtenido de https://jmeter.apache.org (Consultado el 24


de septiembre de 2022)

Hamilton, T. (27 de Agosto de 2022). Guru99. Obtenido de


https://www.guru99.com/integration-testing.html (Consultado el 18 de septiembre de
2022)

Heller, M. (s.f.). TechBeacon. Obtenido de https://techbeacon.com/continuous-integration-


answer-life-universe-everything (Consultado el 24 de septiembre de 2022)

Integration Testing cs.ccu.edu.tw. (s.f.). Integration Testing. Obtenido de


https://www.cs.ccu.edu.tw/~naiwei/cs5812/st8.pdf (Consultado el 19 de septiembre
de 2022)

Micro Focus. (s.f.). Obtenido de https://www.microfocus.com/es-es/portfolio/application-


development (Consultado el 24 de septiembre de 2022)

Microsoft. (s.f.). Microsof Ignite. Obtenido de


https://learn.microsoft.com/es-es/dotnet/core/testing/ (Consultado el 24 de
septiembre de 2022)

Moreno, O. (19 de Noviembre de 2019). Blog personal sobre DevOps, QA y Desarrollo de


software. Obtenido de http://oscarmoreno.com/pruebas-de-rendimiento/ (Consultado
el 24 de septiembre de 2022)

Moreno, Ó. (1 de Octubre de 2019). Blog personal sobre DevOps, QA y Desarrollo de software.


Obtenido de http://oscarmoreno.com/pruebas-de-integracion/ (Consultado el 18 de
septiembre de 2022)

30
NETMENTOR. (07 de Septiembre de 2020). Tests de integración con C# y Docker. Obtenido de
https://www.netmentor.es/Entrada/test-integracion (Consultado el 24 de septiembre
de 2022)

Norma ISO 25010 - ISO. (s.f.). ISO 25000. Obtenido de


https://iso25000.com/index.php/normas-iso-25000/iso-25010 (Consultado el 24 de
septiembre de 2022)

Orejas, F. (26 de Julio de 2012). EL PAÍS. Obtenido de


https://blogs.elpais.com/turing/2012/07/es-posible-construir-software-que-no-
falle.html (Consultado el 24 de septiembre de 2022)

Padmini, C. (s.f.). Beginners Guide to Software Testing. Obtenido de


https://www.softwaretestingclass.com/wp-content/uploads/2016/06/Beginner-Guide-
To-Software-Testing.pdf (Consultado el 20 de septiembre de 2022)

Protractor. (s.f.). Obtenido de https://www.protractortest.org/#/ (Consultado el 24 de


septiembre de 2022)

Razorcat. (s.f.). Obtenido de https://www.razorcat.com/en/testing-integration-test.html


(Consultado el 24 de septiembe de 2022)

Terra, J. (2 de Agosto de 2022). SimpiLearn. Obtenido de https://www.simplilearn.com/what-


is-integration-testing-examples-challenges-approaches-article (Consultado el 18 de
septiembre de 2022)

Tricentis. (s.f.). Obtenido de https://www.tricentis.com/products/performance-testing-


neoload?utm_source=referral&utm_medium=redirect&utm_campaign=neotys
(Consultado el 24 de septiembre de 2022)

Vargas, C. (s.f.). trycore. Obtenido de Tipos de pruebas funcionales para el aseguramiento de la


calidad: https://trycore.co/transformacion-digital/tipos-de-pruebas-funcionales/#top
(Consultado el 24 de septiembre de 2022)

Zapata, M. (23 de Mayo de 2021). YouTube. Obtenido de Pruebas de Integración | MOCKS vs


STUBS | Dobles de Prueba: https://www.youtube.com/watch?v=pxOwxsBFYYo
(Consultado el 20 de septiembre de 2022)

31

También podría gustarte