# PRUEBAS UNITARIAS ## HERRAMIENTAS UTILIZADAS * JEST * super test ### JEST Jest es un framework abierto de pruebas de JavaScript desarrollada por Facebook. Su eslogan es ***"Pruebas de JavaScript deliciosas"***. Funciona con proyectos que usan: * Babel * TypeScript * Node * React * Angular * Vue y más! #### Características * **Rapido y Seguro:** Jest puede ejecutar pruebas en paralelo de manera confiable. * **Cobertura de código:** Jest puede recopilar información de cobertura de código de proyectos completos, incluidos archivos no probados. * **Fácil Burlarse:** Jest utiliza un solucionador personalizado para las importaciones en sus pruebas, lo que facilita la simulación de cualquier objeto fuera del alcance de su prueba * **Grandes Excepciones:** Las pruebas fallan; cuando lo hacen, Jest proporciona un contexto rico por qué. #### Instalacion y configuración ***PASO 1*** Instalacion de Jest usando `npm` ``` bash npm install jest -D ``` Explacacion: * Instalando el framework de jest `jest` * Esta nueva dependencias será instalada como dependencias de desarrollo( *devDependencies* ) `-D` ya que en el proyecto se uso TypeScript fue necesario instalar los types y otra dependencia. ``` shell npm install @types/jest ts-jest -D ``` Explacacion: * Instalando de los tipos para jest `@types/jest` * Instalando el preprocesador de TypeScript para jest `ts-jest`. * Las nuevas dependencias serán instaladas como dependencias de desarrollo ( *devDependencies* ) `-D` ***PASO 2*** Configurando jest, en el archivo de `package.json` agregar lo siguiente: * Agregar un nuevo script ```json "scripts": { ... "test": "jest --verbose --silent", }, ``` * Agregar la configuración para jest ```json { ... "scripts": { ... }, "devDependencies": { ... }, "dependencies": { ... }, "jest": { "testEnvironment": "node", "moduleFileExtensions": [ "ts", "tsx", "js" ], "transform": { "^.+\\.(ts|tsx)$": "ts-jest" }, "globals": { "ts-jest": { "tsConfigFile": "tsconfig.json" } }, "testMatch": [ "**/tests/*.+(ts|tsx|js)" ] } } ``` ### Supetest Es un módulo para poder realizar pruebas de solicitudes HTTP. #### Instalacion y configuración ***PASO 1*** Instalacion de supertest usando `npm` ``` shell npm install supertest -D ``` Explacacion: * Instalando del módulo de supertest `supertest` * Esta nueva dependencias será instalada como dependencias de desarrollo( *devDependencies* ) `-D` ya que en el proyecto se uso TypeScript fue necesario instalar los types para supertest ``` shell npm install @types/supertestt -D ``` Explacacion: * Instalando de los tipos para supertest `@types/supertest` * Esta nueva dependencia será instalada como dependencias de desarrollo ( *devDependencies* ) `-D` ***PASO 2*** Una vez instalado, ahora se puede hacer importado simplemente llamando ```typescript import supertest from 'supertest' ``` ## CREACIÓN Para la creacion de las 4 pruebas se creo un archivo para las pruebas dentro de un directorio llamado *tests*, quedando de la siguiente manera `src/tests/tests.spec.ts` ### Importaciones ```typescript import { app, server } from '../index' import supertest from 'supertest' ``` ### Primera Prueba ```typescript test( "Login success", async () => { const data = { "email": "fer@gmail.com", "password": "123456" } const result = await api.post("/LoginCitizen") .send( data ) .expect(200) .expect('Content-Type', /application\/json/) expect(result.body.auth).toEqual( true ) } ); ``` ### Segunda Prueba ```typescript test( "Invalid credentiales", async () => { const data = { "email": "alex@gmail.com", "password": "12345" } const result = await api.post("/LoginCitizen") .send( data ) .expect(200) .expect('Content-Type', /application\/json/); expect(result.body.auth).toEqual( true ) } ); ``` ### Tercera Prueba ```typescript test('The admin should be able to see all the reports', async () => { const data = { "email": "admin@ayd1.com", "password": "123456" } const auth = await api.post("/LoginEmployee") .send( data ) .expect(200) .expect('Content-Type', /application\/json/); expect(auth.body.auth).toEqual( true ) const token = auth.body.data.token; const result = await api.get("/ReportsAdmin") .set('Authorization', token ) .expect( 200 ) .expect('Content-Type', /application\/json/); expect(result.body.correct).toEqual( true ) }); ``` ### Cuarta Prueba ```typescript test('An employe should not be able to see all open reports, if he is not logged in', async () => { const result = await api.get("/ReportsEmployee") .expect( 200 ) .expect('Content-Type', /application\/json/); expect(result.body.correct).toEqual( true ) }) ``` ## EJECUCIÓN Para ejecutar las pruebas, solo es necesario ejecutar lo siguiente ```shell npm run test ``` ## RESULTADOS ### Primera Prueba ![](https://i.imgur.com/bK7ho0D.png) ### Segunda Prueba ![](https://i.imgur.com/Dr735zR.png) ### Tercera Prueba ![](https://i.imgur.com/9cXpzQb.png) ### Cuarta Prueba ![](https://i.imgur.com/azPNUtU.png) # PUEBAS DE CARGA Para la ejecución de las pruebas de carga se utilizó locust. En el siguiente apartado se dará una introducción al uso de esta herramienta. ## HERRAMIENTAS UTILIZADAS * LOCUST * PYTHON Las pruebas fueron escritas en lenguaje de programación Python y se ejecutarón con el sistema de simulación de carga Locust. ### LOCUST Locust es una herramienta de prueba de rendimiento escalable, con secuencias de comandos y fácil de usar. Usted define el comportamiento de sus usuarios en código Python normal, en lugar de usar una interfaz de usuario torpe o un lenguaje específico de dominio. Esto hace que Locust sea infinitamente expandible y muy amigable para los desarrolladores. Para más información, consultar [documentación de locust](https://) #### ¿Como funciona? En Locust, define su comportamiento de usuario en código Python. Luego, usa el comando locust y (opcionalmente) su interfaz web para generar y simular varios de esos usuarios mientras recopila estadísticas de solicitudes. Emplo de un archivo python para ejecutar locust (locustfile.py): ```python= import time from locust import HttpUser, task, between class QuickstartUser(HttpUser): wait_time = between(1, 2.5) @task def hello_world(self): self.client.get("/hello") self.client.get("/world") @task(3) def view_items(self): for item_id in range(10): self.client.get(f"/item?id={item_id}", name="/item") time.sleep(1) def on_start(self): self.client.post("/login", json={"username":"foo", "password":"bar"}) ``` ## CREACIÓN Para crear las pruebas de carga se utilizo el siguiente archivo de python (locustfile.py): ```python= import time from locust import HttpUser, task, between class LoadTest(HttpUser): wait_time = between(2, 3) @task def employe_reports(self): token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MiwiaWF0IjoxNjI0MTc0NzUwLCJleHAiOjE2MjY3NjY3NTB9.RsMMo5ZjTtmSlpE1BhDz-cWIR5DF9JxO07xzywskHdM" self.client.get("/ReportsEmployee",headers={"Authorization":token}) ``` **Importar time** Se importarón los módulo, HttpUser, task, between necesarios para ejecutar las pruebas aplicadas. ``` python import time from locust import HttpUser, task, between ``` **Clase LoadTest** Se crea la clase LoadTest que estiende de HttpUser, que simulará la demanda de usuarios. ``` python class LoadTest(HttpUser): ``` **Propiedad wait_time** Define el tiempo que los usuarios esperarán entre cada acción programada. En esta simulación se estiman peticiones entre 2 y 3 segundos. ``` python wait_time = between(2, 3) ``` **task employe_reports** Se define una task, que servirá para que locust abra un hilo para la ejecución de la rutina definida en employe_reports. Este método incluye selft.cliente que servive para realizar peticiones http y validarlas. La peticón get implementada envía una solicitud a /ReportsEmployee, incluyendo una llave de autorización en el header, que en este caso ser{ia el token de sesión. ``` python @task def employe_reports(self): token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwidHlwZSI6MiwiaWF0IjoxNjI0MTc0NzUwLCJleHAiOjE2MjY3NjY3NTB9.RsMMo5ZjTtmSlpE1BhDz-cWIR5DF9JxO07xzywskHdM" self.client.get("/ReportsEmployee",headers={"Authorization":token}) ``` ## EJECUCIÓN Nos dirigimos al directorío que contiene el archivo locustfile.py ``` CMD | locustDirectory | >locustfile.py ``` Una vez allí se ejecuta el siguiente comando: ``` CMD locust ``` Inmediatamente comenzarán a ejecutarse las configuraciones establecidas en la construcción del archivo locustfil.py. El servicio de locust se levanta en http://localhost:8089/. ## RESULTADOS ### Prueba de 10 usuarios ![](https://i.imgur.com/BDutvh4.png) ![](https://i.imgur.com/FYVpEts.png) ![](https://i.imgur.com/0xqkaEV.png) ![](https://i.imgur.com/6pDhs8f.png) ![](https://i.imgur.com/KZ7gT4Y.png) ### Prueba de 100 usuarios ![](https://i.imgur.com/Jbl149j.png) ![](https://i.imgur.com/EVm0EAm.png) ![](https://i.imgur.com/hOf9MJW.png) ![](https://i.imgur.com/pq8otOa.png) ![](https://i.imgur.com/inSTnqO.png) ### Prueba de 1000 usuarios ![](https://i.imgur.com/ye7dJtB.png) ![](https://i.imgur.com/hExTPVe.png) ![](https://i.imgur.com/BP7krpu.png) ![](https://i.imgur.com/AVMNwKL.png) ![](https://i.imgur.com/AiekpTK.png)