Anónimo¿Quién automatiza al automatizador?
Pruebas unitarias
Pruebas de integración / de sistemas
Pruebas de carga
No basta con correr el código y ver el resultado
Requieren una librería especial
Veremos cómo usar testing
Librería especializada
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
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
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ó
Comprobar que la función returnFiveAsync() no da error
y devuelve el valor 5
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()
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
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);
}
Diseña un API de control
Arranca y para el sistema usando el API
Tests auto-contenidos: limpia al terminar
Tres reglas básicas:
Diseñar las pruebas para el servidor de sockets
usando testing
Crear un API de control
Arrancar el servidor de sockets en un puerto diferente (1705)
Conectar con un socket y enviar "hello"
Verificar que devuelve "world"
Cerrar el socket
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) {
....
});
});
}
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);
});
});
});
});
}
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