Curso de
Día 4: Pruebas asíncronas
Vuestro anfitrión
(según mi hija de 5 años)
Ingeniero senior en MediaSmart Mobile
Co-organizador de Node.js Madrid
@pinchito
Guión
- Pruebas asíncronas
- Sesión práctica: prueba asíncrona
- Control
- Sesión práctica: prueba de sockets
Pruebas Asíncronas
Anónimo¿Quién automatiza al automatizador?
Tipos de pruebas
Pruebas unitarias
Pruebas de integración / de sistemas
Pruebas de carga
Pruebas de código asíncrono
No basta con correr el código y ver el resultado
Requieren una librería especial
Veremos cómo usar testing
Librería especializadaOtras librerías
Éxito y fracaso
testing.failure(
"Failed to do something",
callback);
Da la prueba por fallida con un mensaje
testing.success(
"Well done!",
callback);
Da la prueba por buena con un mensaje
Aserciones
Para comprobar que un valor contiene lo que se espera
testing.assert(value, "Error in value", callback);
La variable value
debe ser cierta (true
o un objeto)
testing.assertEquals(sum(2, 2), 4, "Wrong sum", callback);
La función sum(2,2)
debe devolver 4
Ejecución asíncrona
testing.check(error, "There is an error", callback);
Comprueba que no haya error; si lo hay, falla el testtesting sigue la convención habitual de node para callbacks:
doSomethingAsync(function(error, result) {
if (error) {
console.error('Could not do something: ' + error);
return;
}
});
El error contiene algo sólo si la función falló
Sesión Práctica 1: prueba asíncrona
Comprobar que la función returnFiveAsync() no da error
y devuelve el valor 5
código a probar
Función que envía 5 a la callback
inmediatamente pero asíncrono
function returnFiveAsync(callback) {
setImmediate(function() {
callback(null, 5);
});
}
setImmediate(callback, args...)
: llama a la callback
después de los eventos de I/O
y antes de setTimeout() y setInterval()
Fuente: setImmediate()
Solución
function testAsync(callback) {
returnFiveAsync(function(error, result) {
testing.check(error, 'Could not return five', callback);
testing.assertEquals(result, 5, 'Invalid result', callback);
testing.success(callback);
});
}
Casi todas las llamadas de testing terminan en una callback¡Bien!
Control
testing.run([testFirst, testSecond], timeout, callback);
Corre las pruebas testFirst()
y testSecond()
testing.show(results);
Muestra el resultado de las pruebas
Uso habitual:
// run tests if invoked directly
if (__filename == process.argv[1])
{
testing.run([testFirst, testSecond], testing.show);
}
¡Automatiza!
Diseña un API de control
Arranca y para el sistema usando el API
Tests auto-contenidos: limpia al terminar
Tres reglas básicas:
- Un único botón
- Haz los fallos visibles
- Sin intervención humana
Sesión práctica 3: pruebas
Diseñar las pruebas para el servidor de sockets
usando testing
Crear un API de control
Diseño de la prueba
Arrancar el servidor de sockets en un puerto diferente (1705)
Conectar con un socket y enviar "hello"
Verificar que devuelve "world"
Cerrar el socket
API de control
Encapsular el arranque del servidor en una función
function start(port, callback) {
var server = net.createServer(function(connection) {
console.log('Conexión abierta');
...
});
server.listen(port, callback);
return server;
}
Añadir la parada del servidor: server.close()
Llamar en secuencia:
function testServer(callback) {
var server = start(1705, function(error, result) {
server.stop(function(error, result) {
....
});
});
}
Prueba completa
function testServer(callback) {
var port = 1705;
var server = start(port, function(error) {
testing.check(error, 'Could not start server', callback);
console.log('started');
var socket = net.connect(port, 'localhost', function(error) {
testing.check(error, 'Could not connect', callback);
socket.on('data', function(data) {
console.log('Received ' + data);
var message = String(data).trim();
if (message == 'Hello?')
{
socket.write('hello');
return;
}
testing.assertEquals(message, 'world', 'Bad response', callback);
server.close(function(error) {
testing.check(error, 'Could not stop server', callback);
testing.success(callback);
});
});
});
});
}
Ejercicios
Eliminar todos los console.log()
Añadir otra prueba testError()
:
envía otra cadena, comprueba que obtiene 'ERROR'
Añadir una prueba que arranque dos servidores
en puertos distintos y los pare¡Tachán!
Thanks!
Curso de Node.js Amaris: Pruebas asíncronas
By Alex Fernández
Curso de Node.js Amaris: Pruebas asíncronas
Curso para Amaris de Node.js, 2014-11-06: pruebas asíncronas
- 2,434