Tu primer test
Clase 6 de 27 • Curso de Introducción al Testing con JavaScript
Contenido del curso
SANDRO SIMON
Jehú Frayle
Andrés Esteban Rodríguez Jiménez
Edgar Mauricio Pérez Rojas
Dany R
Alvaro Eduardo Garzón Pira
JUAN JOSE HERNANDEZ MUÑOZ
Irving Juárez
Carlos Andrés Moreno Jimenez
Miguel Angel Reyes Moreno
Gilbert Ardila
Juan José Mamani Tarqui
Ariel Ezequiel Biazzo Genua
Amanda Sierra
Fredy Arias
Nicolas Molina
Kevin Franco
Kevin Franco
William Zapata
Sergio Alejandro Valencia López
Javier Rosario Rovero
Carlos S. Aldazosa
Sebastian Pedroza
Respecto de la salida de pantalla:
Test Suites: 2 passed, 2 total Tests: 4 passed, 4 total
Cada archivo sería un test suite. En este caso 02-math.test y 01-sum.test.
Probando un conversor de segundos
☕ Actualmente, en la universidad estoy llevando Java básico, y uno de los primeros ejercicios consistía en hacer un conversor de segundos a horas, minutos y segundos.
Me hubiera venido muy bien saber de test en ese momento, porque era muy tedioso tener que revisarlo manualmente para saber si estaba correcto.
En fin, lo que hice fue replicar el ejercicio, ahora en JavaScript e implementar un test sencillito.
function secondsConverter(seconds) { const hours = Math.floor(seconds/3600); const minutes = Math.floor((seconds%3600)/60); const residue = (seconds%3600)%60 return (`${hours}:${minutes}:${residue}`); }
Y en el test simplemente le paso los ejemplos que ya sé que respuesta deben devolver.
test('Converts seconds to hours, minutes and seconds', ()=>{ const rta = secondsConverter(3600); expect(rta).toBe('1:0:0'); const rta2 = secondsConverter(3700); expect(rta2).toBe('1:1:40'); const rta3 = secondsConverter(0); expect(rta3).toBe('0:0:0'); })
Es curioso porque incluso en este desarrollo de 5 minutos me ayudó, pues yo erróneamente asumí que el la respuesta tendría un formato 'HH:MM:SS' que yo nunca le indique, y el test me hizo darme cuenta de mi error cuando lo corrí por primera vez 😅.
Tu primer test
Vamos a experimentar un poco con Jest, vamos a crear varias funciones matemáticas y vamos a hacer sus respectivos test.
Creemos entonces un archivo math.js
// Función para sumar function sum(a, b) { return a + b; } // Función para multiplicar function multiply(a, b) { return a * b; } // Función para dividir function divide(a, b) { return a / b; } // Exportamos nuestras funciones como paquetes module.exports = { sum, multiply, divide }
Ya que tenemos nuestro archivo preparado, vamos entonces a crear nuestro archivo de test para empezar a familiarizarnos con la herramienta.
Vamos a crear nuestro archivo math.test.js:
// Exportar funciiones creadas const {sum, multiply, divide} = require('./math'); /* Para empezar a testear nuestras funciones debemos usar la palabra reservada test como función */ /* Dentro de esta función vamos a escribir como string que es lo que esperamos que haga esta función, ósea es una pequeña descripción de lo que se supone debe hacer la función */ /* Luego de esto vamos a tener una fución que será el manejador del test, en esta estableceremos la lógica de nuestro test */ test("añadir 1 + 3 debe dar 4", ()=> { // Ejecutamos nuestra función y le pasamos sus respectivos valores const rta = sum(1,3); /* Expect tendrá la ejecución de la función y toBe tendrá el resultado que esperamos de la función */ expect(rta).toBe(4); });
Ahora si ejecutamos nuestro comando de test veremos que tenemos un resultado correcto:
npm run test # Output = test passed
Vamos a crear los test de las siguientes funciones:
const {sum, multiply, divide} = require('./math'); test("añadir 1 + 3 debe dar 4", ()=> { const rta = sum(1,3); expect(rta).toBe(4); }); test("añadir 9 x 2 debe dar 18", ()=> { const rta = multiply(9,2); expect(rta).toBe(18); }); test("añadir 12 / 3 debe dar 4", ()=> { const rta = divide(12,3); expect(rta).toBe(4); // Podemos tener varios escenarios de prueba en nuestros test const rta2 = divide(5,2); expect(rta2).toBe(2.5); });
Podemos también aumetar la complejidad de nuestros test:
... test( 'dividir entre 0 nos debe retornar un string que diga "no se puede dividir entre 0"', ()=> { const rta = divide(0,0); expect(rta).toBe("no se puede dividir entre 0"); } );
Vamos a crear una validación para solucionar este problema:
... function divide(a, b) { if(a === 0 || b === 0) { return "no se puede dividir entre 0" } return a / b; }
Así es como podemos crear nuestras pruebas para nuestros proyectos.
Hola , me salté para ser el primer comentario, ya que es el primer test :
< console.log( Hola Mundo del Testing); >
no paremos de aprender. :D
¿cuando usar "import" y cuando "require"?
Hola Dany, originalmente node.js solo aceptaba importación común con require, pero desde unos años atrás se admite también el uso de import debido a que JS realiza importaciones así, es decir, import proviene del lenguaje y request del entorno de ejecución por lado del servidor conocimido como node.js, no puedes usar los dos dentro del mismo proyecto debido a que se debe de configurar en el archivo package.json, muchas personas recomiendan usar solo import para dejarlo como estandar con JS por lado del backend y frontend pero puede variar en cada proyecto.
Cualquier test consiste de tres simples pasos: Arrange, Act y Assert. (Configuracion, Accion y Verificacion).
Que es mas recomendado, hacer un toBe(null) o un toBeNull(), y hay alguna diferencia entre ellos?
No es mucho, pero es trabajo honesto:
function sum(a, b) { return a + b; } function multiply(a, b) { return a * b; } function divide(a, b) { if (b === 0) { return null; } return a / b; } function substract(a, b) { return a - b; } function power(a, b) { return Math.pow(a, b); } module.exports = { sum, multiply, divide, substract, power };
const { sum, divide, multiply, substract, power } = require('./02-math') test('sum of 1 + 3 should be 4', () => { const rta = sum(1, 3); expect(rta).toBe(4); }); test('substract 0 - 0 should be 0', () => { const rta = substract(0, 0); expect(rta).toBe(0); }) test('mutiply 3 * 5 should be 15', () => { const rta = multiply(3, 5); expect(rta).toBe(15); }); test('should divide', () => { const rta = divide(6, 3); expect(rta).toBe(2); const rta2 = divide(5, 2); expect(rta2).toBe(2.5); }) test('should divide by 0', () => { const rta = divide(6, 0); expect(rta).toBe(null); const rta2 = divide(5, 0); expect(rta2).toBe(null); }) test('should return the power of the base number', () => { const rta = power(2, 3); expect(rta).toBe(8); });
//imput.js
<function input(content){ if(typeof(content)!==String ||content.includes('@') || content.includes('#') || content.includes('/') || content.includes('-')){ return 'Error' } return 'Exito' } module.exports =input>
//input.test.js
<const input=require('./input'); test('this input must be wrong, it is not a string',()=>{ expect(input(1)).toBe('Error'); }); test('this input must be wrong, it contains special caracters',()=>{ expect(input('j@iro')).toBe('Error'); });>
por qué usar testing si al programar la consola editor te manda error si es que anda algo mal sin tener que implementar jest ...
Porque el testing nos permite modularizar y encontrar los errores. Si haces un programa con mas de 4 archivos y miles de linea de codigo sin test, no es tan facil encontrar los errores o bugs. Ademas, testing nos permite lanzar un error si no nos da la salida que esperamos, en cambio la termninal nos lanza un error solo si hay typos o algo siimilar.
esto es correcto? porque no me marca error en las pruebas pero yo no le di return null cuando definí la función
const rta3 = divide(5, 0); expect(rta3).toBeNull;
Es buena práctica tener más de un expect en un test?
Hola, no es no mala ni buena práctica, depende de que quieras probar, puede que en una sola prueba quieras validar varios expects que hagan sentido tenerlos todo dentro.
quise calcular el teomera de pitagoras:
function calculatePitagorasTheorem(value1 = 0, value2 = 0) { const squaredSum = Math.pow(value1, 2) + Math.pow(value2, 2); const squareRoot = Math.sqrt(squaredSum); return squareRoot; } module.exports = calculatePitagorasTheorem;
test:
const calculatePitagorasTheorem = require('./03-self'); test('calculatePitagoras', () => { const angles = calculatePitagorasTheorem(3, 4); expect(angles).toBe(5); }); ```y funciono perfecto, que emoción
El uso de expect y toBe es fundamental en las pruebas unitarias de JavaScript, especialmente con bibliotecas como Jest. expect es una función que se utiliza para crear una expectativa sobre un valor, y toBe es un matcher que verifica si el valor esperado es exactamente igual al valor actual mediante comparación estricta (===).
Por ejemplo:
expect(valor).toBe(valorEsperado);
Esto asegura que los resultados de tu código sean los esperados, ayudando así a detectar fallos en tu lógica.
RETO
Elevar un número a una potencia
function raiseExponent(base, exponent) { return base ** exponent;}
Test
test("raiseExponent", () => { const rta = raiseExponent(2, 3); expect(rta).toBe(8); const rta2 = raiseExponent(1, 0); expect(rta2).toBe(1);});
En visual code podemos instalar un plugin para correr la prueba de forma rapida sobre el mismo codigo, se llama “Jest Runner”
> demos@1.0.0 test2 > jest PASS src/01-sum.test.js PASS src/02-math.test.js Test Suites: 2 passed, 2 total Tests: 8 passed, 8 total Snapshots: 0 total Time: 1.98 s, estimated 2 s Ran all test suites.
Mi ejemplo de test con una función que retorna el promedio de un array:
Función
function average(numbers) { if (numbers.length === 0) { return 'Array can not be empty'; } const sum = numbers.reduce((previous, current) => { return previous + current }) return sum/numbers.length; }
Test
test('Average', async () => { const res = average([1,2,3,4,5]); expect(res).toBe(3); }); test('Average error', async () => { const res = average([]); expect(res).toBe('Array can not be empty'); });
🤓Tu primer test
function sum(a, b) { return a + b; } function multiply(a, b) { return a * b; } function divide(a, b) { if (b === 0) { return null; } return a / b; } module.exports = { sum, multiply, divide, };
2)Crear el archivo de pruebas para el código a evaluar
const { sum, multiply, divide } = require('./02-math'); // Importar el archivo JS a evaluar //test = Define la pueba a hacer test ("Descripción de la prueba", ()=>{ //Ejecución de la prueba en el código /*expect= Define y compara que el resultado esperado a partir de la pueba realizada sea igual al obtenido espues de la ejecución*/ expect(/*Resultado de la ejecución*/).toBe(/*Resultado de la prueba*/); }); test("add 1 + 3 should be 4", () => { const rta = sum(1, 3); expect(rta).toBe(4); }); test("add 1 * 4 should be 4", () => { const rta = multiply(1, 4); expect(rta).toBe(4); }); test("add 1 / 4 should be 4", () => { const rta = divide(6, 3); expect(rta).toBe(2); const rta2 = divide(5, 2); expect(rta2).toBe(2.5); }); test("should divide for zero", () => { const rta = divide(6, 0); expect(rta).toBeNull(); const rta2 = divide(5, 0); expect(rta2).toBeNull(); });
npm run test