TDD in Node.js
Ziel dieser Übung ist es vorderrangig die Tools die in dieser Übung eingesetzt werden kennenzulernen. Hierzu greifen wir auf eine minimale Node.js Anwendung zurück und implementieren eine einfache Funktion unter der Verwendung von TDD.
Projekt importieren
Section titled “Projekt importieren”Hierzu importieren wir zuerst einmal ein Repository mittels GitHub.
Aufruf des Import-Menüs
Section titled “Aufruf des Import-Menüs”Hierzu navigieren wir zuerst in der oben Menüleiste nach rechts und klicken auf den Pfeil nach unten neben den Plus (1) und anschließend auf “Import repository” (2). Siehe auch Screenshot

Wahl des zu importierenden Projekts
Section titled “Wahl des zu importierenden Projekts”Danach öffnet sich der folgende Dialog in dem wir die Felder
(1) - URL des Quell-Repositories, in unserem Fall
https://github.com/FHB-Student/Nodejs-Starter(2) - Der Namen des zu erstellenden Repositories in unserem Account z.B.: TDD-Nodejs-Example
befüllen.

Anschließend wählen wir noch aus das ein privates Repository angelegt werden soll und beginnen den Import mittels Klick auf den Button “Begin import”.
Nach dem erfolgreichen Import
Section titled “Nach dem erfolgreichen Import”Nach einer kurzen Wartezeit sollte das neue Repository inklusive der importieren Daten zur Verfügung stehen.
Es sollte nun folgender Screen zu sehen sein.

Öffnen des Repositories
Section titled “Öffnen des Repositories”Mittels Klick auf den Link bei der Anzeige des erfolgreichen Imports gelangen wir direkt zur Ansicht des Repos in GitHub.
Erweitern der Anwendung mit Hilfe von TDD
Section titled “Erweitern der Anwendung mit Hilfe von TDD”Erstellen eines neuen Branches
Section titled “Erstellen eines neuen Branches”Im Repository angekommen legen wir nun zu aller erst einmal eine Branch an.

- (1) Wie im Screenshot ersichtlich Klicken wir zuerst auf “main” um ins Branch-Menü zu gelangen.
- (2) Anschließend vergeben wir einen klaren verständlichen Namen für unseren neuen Branch.
- (3) Abschließend klicken wir auf “Create branch … from main”
Anschließend schickt und GitHub zurück zur Repo-Seite. Der neue Branch ist automatisch ausgewählt, dies kann wie unten im Screenshot überprüft werden.

Starten von GitHub Codespaces
Section titled “Starten von GitHub Codespaces”Hierzu klicken wir zuerst auf “Code” (1) danach wählen wir den Tab “Codespaces” (2) aus. Anschließend klicken wir auf “Create codespace on …” (3) um den Codespace zu starten.

Es öffnet sich nun ein neuer Browser-Tab mit einer VS Code Oberfläche.
Installieren von Fremdsoftware
Section titled “Installieren von Fremdsoftware”Wir installieren ein JavaScript Test-Framework names Mocha. Hierzu öffnen wir das Terminal und fügen den unten angeführten Aufruf ein.
npm install mocha --save-devErstellen der automatischen Tests
Section titled “Erstellen der automatischen Tests”Anschließend erstellen wir im Verzeichnis “src” die Datei “calculator.js”.
Für unsere automatischen Tests legen wir nun auf oberster Ebene ein Verzeichnis names “test” an.
In dem zuvor erstellten Verzeichnis legen wir nun eine Datei names “calculator.test.js” an und befüllen sie mich dem unten angeführten Inhalt.
const assert = require('assert');
describe('Simple Math Test', () => { it('should return 2', () => { assert.equal(1 + 1, 2); });});Wir haben somit einen ersten automatischen Test mit Hilfe von Mocha erstellt. Nun ist es an der Zeit diesen auszuführen und verifizieren ob dies korrekt funktioniert.
Es ist eine Konvention in NPM das Tests mit einem Script names “test” ausgeführt werden können. Hierzu geben wir in die Kommandozeile nun den Befehl
npm run testein um unseren Test zu starten.
Wir bekommen nun die Rückmeldung “No test specified” obwohl wir doch zuvor eine Test angelegt haben.
@FHB-Student ➜ /workspaces/TDD-Nodejs-Example (feature/tdd-example) $ npm run test
> nodejs-starter@1.0.0 test> echo "No test specified" && exit 0
No test specifiedUm die Ursache für diese Meldung herauszufinden navigieren wir zur Datei “package.json” im Quellverzeichnis.
"scripts": { "start": "nodemon src/index.js", "test": "echo \"No test specified\" && exit 0" },Wie im Ausschnitt der Datei “package.json” oben erkennbar ist das Script aktuell eben so definiert. Es gibt aktuell die Meldung “No test specified” aus und wird danach beendet.
Damit das von uns gewünscht Verhalten ausgeführt ist müssen wir dieses Script anpassen. Wie im unteren Beispiel angeführt ersetzen wir das bestehende Test-Script durch ein neues welches Mocha aufruft.
"scripts": { "start": "nodemon src/index.js", "test": "echo \"No test specified\" && exit 0" "test": "mocha" },Nun wurde der Test erfolgreich ausgeführt, dies erkennen wir an der Ausgabe im CLI.
Um zu sehen wie ein fehlgeschlagener Test aussieht fügen wir den unten dargestellten (grünen) Block hinzu.
const assert = require('assert');
describe('Simple Math Test', () => { it('should return 2', () => { assert.equal(1 + 1, 2); });
it('should also return 2', () => { assert.equal(1 + 3, 2); });});Anschließend führen wir den Test erneut aus. Wir sehen das nun wie gewohlt ein Test erfolgreich durchgelaufen ist und der andere mit eine fehlschlägt.
Dies zeigt uns die Ausgabe in der Kommandozeile farblich gekennzeichnet (wie im Screenshot ersichtlich) an.

Jetzt testen wir aber aktuell nicht unsere Funktion sondern nur ob JavaScript den + Operator korrekt implementiert.
Hierzu müssen wir zuerst eine Funktion in der Datei “calculator.js” im Verzeichnis “src” erstellen.
const calculator = {};
calculator.calculate = (num1, num2, operation) => { return num1 + num2;}
module.exports = calculator;Ebenso müssen wir noch die Tests in der Datei “calculator.test.js anpassen.
const assert = require('assert');const calculator = require('../src/calculator');
describe('calculator.calculate() Test', () => { it('1 + 1 should equal 2', () => { const result = calculator.calculate(1, 1, '+'); assert.equal(result, 2); });});Wir führen erneut den Test mittels
npm run testaus und sehen das dieser ohne Fehler durchläuft.
Wir haben somit eine Funktion inklusive funktionierenden Unit-Test.
Nun wollen wir gemeinsam die Funktion erweitern und nutzen hierzu Test Driven Development (TDD).
Zur Erinnerung das Vorgehen bei TDD sieht wiefolgt aus:
- Einen neuen Test hinzufügen
- Alle (betroffenen) Tests ausführen => der neue Test sollte fehlschlagen
- Die betroffene Funktion wird so erweitert/angepasst das alle Tests erfolgreich durchlaufen
- Die Tests laufen fehlerfrei durch
- Refaktorisierung der Funktion => Test laufen auch danach fehlerfrei durch.
So nun spielen wir ein paar dieser Zyklen gemeinsam durch.
Änderungen in den Source übernehmen
Section titled “Änderungen in den Source übernehmen”Nachdem wir nun diese Funktion gemäß TDD gemeinsam implementiert haben müssen wir diese noch mittels git festschreiben und mittels Pull-Request in die Haupt-Branch (main) integrieren.
Hierzu wählen wir im Menü auf der linken Seite das vierte Symbol von oben aus. Anschließend geben wir in dem Testfeld einen klaren nachvollziehbaren Namen der erklärt was wir geändert haben für unseren Commit.
Abschließend klicken wir auf den Pfeil rechts neben “Commit” und wählen die Option “Commit und Push” aus.

Anschließend fragt die Web-UI nach einer Bestätigung ob wir alle Änderungen zuerst stagen und danach commiten wollen.

Dies bestätigen wir mittels eines Klicks auf “Ja”.
GitHub Codespace stoppen
Section titled “GitHub Codespace stoppen”Anschließend stoppen wir noch unseren GitHub Codespace da wir ihn nicht weiter benötigen.
Hierzu betätigen wir zuerst die “F1”-Taste und geben dann in der Befehlsleiste “Codespaces: Stop Current Codespace” und wählen diese Option anschließend aus.

Das dies erfolgreich durchgeführt wurde zeigt uns dieser Screenshot an.

Pull Request mergen
Section titled “Pull Request mergen”Nun können wir uns in der GitHub Web-UI unsere Pull-Request ansehen und nach ausreichender Prüfung in den Hauptzweig übernehmen.
Zusammenfassung
Section titled “Zusammenfassung”In diesem Lab haben wir erfolgreich
- Einen Projekt in GitHub importiert
- Einen Branch erstellt
- GitHub Codespaces aufgerufen
- Eine Abhängigkeit mittels NPM zum Projekt hinzugefügt
- Unit-Tests geschrieben und ausgeführt
- Den Ablauf bei TDD anhand eines einfachen Beispiels durchgespielt