Parametrisierte Unit-Tests

Da das Unit-Test-Framework Mocha von Haus aus keine Unterstützung für Testfälle enthält, rüstet das Modul cases diese nach. Es unterstützt sowohl synchrone als auch asynchrone Tests und macht das Laden von Testdaten aus JSON-Dateien besonders einfach.

vorlesen Druckansicht
Lesezeit: 4 Min.
Von
  • Golo Roden
Inhaltsverzeichnis

Wie im Artikel Unit-Tests mit Node.js beschrieben, besteht die größte Stärke von Mocha in der einfachen Art, asynchronen Code zu testen. Was Mocha jedoch fehlt, ist die Unterstützung verschiedener Testfälle, um einen Test wiederholt mit verschiedenen Eingabewerten auszuführen. Abhilfe schafft das Modul cases, das sich nahtlos in Mocha integriert. Um es zu verwenden, ist es zunächst auf dem üblichen Weg mit npm in den lokalen Kontext der Anwendung zu installieren:

$ npm install cases

AnschlieĂźend kann man das Modul mit Hilfe der require-Funktion in die Testdatei integrieren:

var cases = require('cases');

Als einfaches Beispiel fĂĽr einen synchronen Test kann eine Funktion namens add dienen, deren Aufgabe darin besteht, zwei Zahlen zu addieren und deren Summe zurĂĽckzugeben:

var add = function (first, second) {
return first + second;
};

Ein Test fĂĽr diese Funktion ist schnell geschrieben:

test('add returns the sum.', function () {
assert.that(add(23, 42), is.equalTo(65));
});

Doch was, wenn der gleiche Test auch mit anderen Eingabewerten ausgeführt werden soll? Es liegt auf der Hand, dass es sich auch bei der Wahl anderer Zahlen um immer noch den gleichen Test handelt – ob 23 und 42 oder 5 und 7 addiert werden, spielt im Grunde genommen keine Rolle. Dennoch wäre es wünschenswert, diesen Test mit verschiedenen Testfällen ausführen zu können.

Das Modul cases ermöglicht die Implementierung genau dieses Szenarios: Anstelle der eigentlichen Testfunktion ruft man die Funktion cases auf, die verschiedene Testfälle und eine entsprechend parametrisierte Testfunktion entgegennimmt:

test('add returns the sum.', cases([
[ 23, 42, 65 ],
[ 5, 7, 12 ]
], function (first, second, expected) {
assert.that(add(first, second), is.equalTo(expected));
}));

Mocha führt daraufhin die Testfunktion der Reihe nach für alle Testfälle aus. Schlägt einer der Testfälle fehl, dann auch der zugehörige Test.

Asynchronen Code kann man auf die gleiche Art testen. Der einzige Unterschied besteht darin, dass man der Testfunktion wie in Mocha üblich einen zusätzlichen Parameter namens done übergeben muss. Als Beispiel für asynchronen Code dient die Funktion addAsync:

var addAsync = function (first, second, callback) {
setTimeout(function () {
callback(first + second);
}, 100);
};

Ein klassischer Test fĂĽr diese Funktion lautet in Mocha:

test('addAsync returns the sum.', function (done) {
addAsync(23, 42, function (actual) {
assert.that(actual, is.equalTo(65));
done();
});
});

Das Modul cases ermöglicht die Formulierung auch dieses Tests mit Hilfe verschiedener Testfälle, wobei das Vorgehen prinzipiell analog zu jenem für synchronen Code ist:

test('addAsync returns the sum.', cases([
[ 23, 42, 65 ],
[ 5, 7, 12 ]
], function (first, second, expected, done) {
addAsync(first, second, function (actual) {
assert.that(actual, is.equalTo(expected));
done();
});
})
);

Beiden vorgestellten Varianten ist gemein, dass man die Testdaten inline definiert. Für größere Datenmengen wäre es jedoch hilfreich, diese ausgelagert definieren zu können, beispielsweise in einer .json-Datei:

module.exports = [
[ 23, 42, 65 ],
[ 5, 7, 12 ]
];

Um diese Datei zu laden, genĂĽgt der Aufruf der require-Funktion innerhalb jener Funktion, die die Testdaten definiert:

test('add returns the sum.', cases(function () {
return require(path.join(__dirname, 'addAsyncCases.json'));
}
, function (first, second, expected) {
assert.that(add(first, second), is.equalTo(expected));
}));

Selbstverständlich kann man zum Laden der Daten auch jeden beliebigen anderen Mechanismus verwenden, um beispielsweise Daten aus einer Datenbank oder von einem Webservice laden zu können. Derzeit gilt hierbei allerdings die Einschränkung, dass das Laden der Daten synchron erfolgen muss.

tl;dr: Da das Unittest-Framework Mocha von Haus aus keine Unterstützung für Testfälle enthält, rüstet das Modul cases diese nach. Es unterstützt sowohl synchrone als auch asynchrone Tests und macht das Laden von Testdaten aus .json-Dateien besonders einfach. ()