Erlerne Continuous Integration mit Bitbucket Pipelines
Sten Pittet
Gastautor
In diesem Tutorial lernen wir am Beispiel eines einfachen Node.js, wie ein CI-Workflow in Bitbucket Pipelines eingerichtet wird.
Uhrzeit
30 Minuten
Zielpublikum
Continuous Integration und/oder Bitbucket Pipelines sind neu für dich
Voraussetzungen
- Node v4.6 oder höher zum Ausführen der Beispielanwendung
- Terminal zum Ausführen von Bash-Befehlen
- Git zum Verwalten des Repositorys und für Push-Übermittlungen zurück an Bitbucket Cloud
- Ein Bitbucket-Konto
Softwaretests können ein kostspieliger Teil des Release-Zyklus sein. Du musst dabei nicht nur prüfen, ob neue Änderungen erwartungsgemäß funktionieren, sondern auch sicherstellen, dass bestehende Funktionen nicht beeinträchtigt wurden. Dies kann schnell zu einer erheblichen Belastung werden, weil der Testaufwand mit jedem neuen Release zunimmt. Außerdem ist es eine mühsame Aufgabe für dein Team, da grundlegende Aspekte eurer Anwendung immer wieder manuell überprüft werden müssen.
Hier schafft Testautomatisierung Abhilfe, da sie deinen Mitarbeitern den redundanten und lästigen Teil des Testens abnimmt. Du schreibst einmalig einen Test, der dann automatisch und ohne menschliche Eingriffe von einem Test-Framework ausgeführt werden kann. Dann kannst du noch einen Schritt weiter gehen und dein Repository in einen Continuous-Integration-Service wie Bitbucket Pipelines einbinden, um Tests automatisch für jede Änderung auszuführen, die in das Haupt-Repository gepusht wird.
In diesem Tutorial lernen wir anhand eines einfachen Node.js-Beispiels, wie ein CI-Workflow in Bitbucket Pipelines eingerichtet wird. Wir erstellen zunächst unsere Anwendung. Dann sehen wir uns an, wie wir einen einfachen Test implementieren können. Schließlich besprechen wir, wie wir das Ganze in Bitbucket Pipelines einbinden.
Schritt 1: Ein neues leeres Bitbucket-Repository erstellen
Erstelle ein neues Bitbucket-Repository, um dieses Tutorial zu beginnen.
Klone dieses Repository mit einem Befehl wie:
git clone git@bitbucket.org:pmmquickstartguides01/cdtutorial.git
Schritt 2: Eine einfache Hello World-Anwendung erstellen
Erstelle zu Beginn eine einfache Node.js-Anwendung, die "Hello World!" im Browser anzeigt.
Führe npm init aus, um dein neues Node-Projekt zu initialisieren. Du kannst alle Standardeinstellungen übernehmen, mit Ausnahme des Einstiegspunkts, den du von index.js zu server.js ändern musst.
npm init
Deine npm init-Einstellungen
Solltest du vergessen haben, den Einstiegspunkt zu server.js zu ändern, kannst du das jederzeit in der Datei package.jsonnachholen. Wenn du fertig bist, sollte dein helloworld-Verzeichnis eine einzige Datei namens package.json enthalten und wie folgt aussehen:
package.json
{
"name": "cdtutorial",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+ssh://git@bitbucket.org/pmmquickstartguides01/cdtutorial.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://bitbucket.org/pmmquickstartguides01/cdtutorial/issues"
},
"homepage": "https://bitbucket.org/pmmquickstartguides01/cdtutorial#readme"
}
Jetzt installieren wir Express, ein Web-Framework für Node. Wir speichern es als Abhängigkeit mit dem Parameter --save. Es ist wichtig, es als Abhängigkeit zu speichern, da spätere Bitbucket Pipelines so nachvollziehen können, welche Abhängigkeiten installiert werden müssen, um deine Anwendung zu testen.
npm install express --save
Erstelle eine Datei namens server.js und kopiere den folgenden Code, um deine Hello World-Anwendung zu erstellen.
var express = require("express");
var app = express();
// The code below will display 'Hello World!' to the browser when you go to http://localhost:3000
app.get("/", function (req, res) {
res.send("Hello World!");
});
app.listen(3000, function () {
console.log("Example app listening on port 3000!");
});
module.exports = app;
Dein Anwendungsordner sollte jetzt so aussehen:
wmarusiak@C02F207NML7L cdtutorial % ls
node_modules package-lock.json package.json server.js
Du kannst jetzt einfach deine Node-Anwendung starten und sie unter http://localhost:3000 in Aktion erleben.
npm start
Unser Beispiel in Aktion
Schritt 3: Einen Test für unsere Anwendung schreiben
Unsere Anwendung ist jetzt fertig und wir können einen zugehörigen Test schreiben. In diesem Fall möchten wir sicherstellen, dass sie immer "Hello World!" anzeigt, wenn der Benutzer die Basis-URL aufruft. Dies ist ein sehr einfaches Beispiel, aber wenn du dieser Struktur folgst, kannst du Unit-Tests für deine eigene Anwendung hinzufügen und außerdem komplexere Dinge tun, wie z. B. die Authentifizierung prüfen, Inhalte erstellen und löschen sowie Berechtigungen testen.
Dazu verwenden wir ein Test-Framework namens Mocha und eine Bibliothek namens supertest, die uns helfen werden, bei unseren Tests HTTP-Anfragen zu verwalten. Wenn du bereit bist, Testautomatisierung für deine Anwendung einzusetzen, solltest du dir die Zeit nehmen, um das richtige Test-Framework für deine Anforderungen zu finden. Je nach Sprache können die Optionen variieren. Einige Frameworks sind bereits etabliert, z. B. PHPUnit für PHP, aber in anderen Fällen musst du unter Umständen ein bisschen recherchieren, um das beste Test-Framework für dein Projekt ausfindig zu machen. Bei Wikipedia findest du zwar eine umfassende Liste mit Unit-Test-Frameworks, aber wir raten dir, in der Entwickler-Community für deine Sprache ein paar Empfehlungen einzuholen.
Führe den folgenden Befehl in deinem Terminal aus, um Mocha und supertest als Entwicklungsabhängigkeiten für deine Anwendung zu installieren.
npm install mocha --save-dev && npm install supertest --save-dev
Ersetze in deiner package.json den Testskript-Befehl, um stattdessen mocha aufzurufen.
{
"name": "cdtutorial",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "mocha --exit"
},
"repository": {
"type": "git",
"url": "git+ssh://git@bitbucket.org/pmmquickstartguides01/cdtutorial.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://bitbucket.org/pmmquickstartguides01/cdtutorial/issues"
},
"homepage": "https://bitbucket.org/pmmquickstartguides01/cdtutorial#readme",
"dependencies": {
"express": "^4.17.3"
},
"devDependencies": {
"mocha": "^9.2.2",
"supertest": "^6.2.2"
}
}
Wenn du den Befehl "npm test" auf deinem Terminal ausführst, sollte die Fehlermeldung angezeigt werden, dass keine Tests gefunden wurden. Dies ist das erwartete Verhalten. Als Nächstes sehen wir uns an, wie wir einen einfachen Test hinzufügen können.
Jetzt kannst du einen Testordner anlegen, in dem du eine Testdatei hinzufügst.
mkdir test
touch test/test.js
Unser Test wird sehr einfach sein: er wird lediglich prüfen, ob der Satz "Hello World!" vorhanden ist, wenn die Basis-URL aufgerufen wird.
test.js
var request = require("supertest");
var app = require("../server.js");
describe("GET /", function () {
it('displays "Hello World!"', function (done) {
// The line below is the core test of our app.
request(app).get("/").expect("Hello World!", done);
});
});
Wenn du npm test noch einmal in deinem Terminal ausführst, solltest du jetzt sehen, dass ein Test erfolgreich ("passing") ist.
Herzlichen Glückwunsch! Du hast jetzt einen automatisierten Test für deine Anwendung implementiert. Dies ist nur ein Schritt auf dem Weg zu Continuous Integration. Bei der Entwicklung deiner eigenen Anwendung solltest du dich mit den unterschiedlichen Arten von Tests vertraut machen, die du implementieren kannst, um die Integrität deines Systems zu prüfen. Halte dir immer vor Augen, dass kompliziertere Tests auch teurer in der Ausführung sind.
In diesem Tutorial haben wir eine Funktion implementiert und anschließend einen Test dafür geschrieben. Es kann eine interessante Erfahrung sein, umgekehrt vorzugehen und erst die Tests zu schreiben, mit denen die Funktion geprüft werden soll. Du kannst die Funktion dann in dem Wissen implementieren, dass du bereits über die nötigen Sicherheitsmaßnahmen verfügst, um die ordnungsgemäße Ausführung zu überprüfen.
Schritt 4: Continuous-Integration-Workflow mit Bitbucket Pipelines implementieren
Du kannst den Test jetzt als Skript über die Befehlszeile ausführen. Bevor du beginnst, CI zu praktizieren, solltest du aber sicherstellen, dass deine Testsuite bei jedem neuen Commit ausgeführt wird. So werden die Entwickler benachrichtigt, wenn ihre Änderungen zu Fehlern in der Anwendung führen, damit sie das zugrunde liegende Problem umgehend beheben können, bevor sie zur nächsten Aufgabe übergehen. Ein weiterer Vorteil der Ausführung deiner Tests bei jedem Commit besteht darin, dass dein Team dadurch die Qualität der Entwicklung beurteilen kann – du kannst visualisieren, wie oft neue Änderungen Anwendungsfehler verursachen und wie schnell die Integrität wiederhergestellt wird.
Das mag ernüchternd klingen, aber mit Bitbucket Pipelines kannst du deine Tests zum Glück ganz einfach automatisieren.
Als Erstes solltest du dein Repository zu Bitbucket hinzufügen.
git add --all
git commit -m "first commit"
git branch -m main
git push -u origin main
Rufe Pipelines auf, indem du in der Seitenleiste auf die entsprechende Menüoption klickst.
Nachdem du Pipelines aktiviert hast, wähle die Node.js-Vorlage im Konfigurationsbeispiel aus. In diesem Beispiel sollte der Skriptabschnitt die Befehle npm install und npm test enthalten. Bitbucket Pipelines führt sie genauso aus, wie du es in deinem eigenen Terminal machen würdest, um Abhängigkeiten zu installieren und die Tests durchzuführen.
Das Update der bitbucket-pipelines.yml sieht wie folgt aus:
image: node:16
pipelines:
default:
- parallel:
- step:
name: Build and Test
caches:
- node
script:
- npm install
- npm test
Du kannst es direkt in dein Repository committen.
Anschließend wirst du zum Pipelines-Abschnitt weitergeleitet, wo du deine erste Pipeline in Ausführung sehen kannst.
Du kannst die Pipeline anklicken, um Details zur Ausführung anzuzeigen und den Vorgang bis zum erfolgreichen Abschluss im Auge zu behalten.
Das wars auch schon! Für dein Bitbucket-Repository ist jetzt ein CI-Workflow eingerichtet und deine Tests werden bei jedem Commit ausgeführt. Das kannst du testen, indem du Änderungen am Code vornimmst und den Pipelines-Abschnitt beobachtest. Wenn alles funktioniert, ist die Anzeige grün, aber wenn Fehler auftreten oder du den Satz änderst, der auf der Startseite angezeigt wird, solltest du eine fehlgeschlagene Pipeline sehen und eine E-Mail-Benachrichtigung erhalten.
E-Mail-Benachrichtigung, nachdem eine Änderung einen Fehler verursacht hat
Was kommt als Nächstes?
Dieses Beispiel hat natürlich nicht viel mit der Anwendung zu tun, die du gerade entwickelst. Es sollte dir aber ein grundlegendes Verständnis dafür geben, wie die Testautomatisierung funktioniert und wie du einen Continuous-Integration-Workflow einrichtest:
- Ermittle das passende Test-Framework
- Implementiere deine Tests
- Aktiviere Bitbucket Pipelines
Um die Vorteile von CI wirklich zu nutzen, musst du kontinuierlich neue Tests für jede Funktion, Verbesserung oder Fehlerbehebung hinzufügen, die du auslieferst. Ist der Umfang deiner Testsuite zu klein, erhältst du am Ende ein falsches Gefühl der Sicherheit, dass deine Anwendung funktioniert. Die Einführung von Continuous Integration ist mit einem Wandel der Unternehmenskultur verbunden und kann nur erfolgreich sein, wenn dein gesamtes Team an Bord ist. Weitere Informationen findest du in unserem CI-Leitfaden.
Diesen Artikel teilen
Nächstes Thema
Lesenswert
Füge diese Ressourcen deinen Lesezeichen hinzu, um mehr über DevOps-Teams und fortlaufende Updates zu DevOps bei Atlassian zu erfahren.