Close

Erlerne Continuous Integration mit Bitbucket Pipelines

Porträt von Sten Pittet
Sten Pittet

Gastautor

In diesem Tutorial lernen wir am Beispiel eines einfachen Node.js, wie ein CI-Workflow in Bitbucket Pipelines eingerichtet wird.

Zeit

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.

Screenshot: Erstellung eines neuen Repositorys in Bitbucket

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
Terminal response from "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
Screenshot: localhost "hello world"

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.

Screenshot: npm test-Terminal

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.

NPM test, Erfolg

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.

NPM test, Erfolg

Du kannst die Pipeline anklicken, um Details zur Ausführung anzuzeigen und den Vorgang bis zum erfolgreichen Abschluss im Auge zu behalten.

NPM test, Erfolg

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.

Sten Pittet
Sten Pittet

Ich bin seit 10 Jahren in der Softwarebranche tätig und hatte schon verschiedene Positionen inne, unter anderem in der Entwicklung und im Produktmanagement. Nachdem ich in den letzten 5 Jahren bei Atlassian an Entwickler-Tools gearbeitet habe, schreibe ich jetzt über das Erstellen von Software. In meiner Freizeit feile ich zusammen mit meinem Kleinkind an meinen Kompetenzen als Vater.


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.

Abbildung: DevOps

DevOps-Community

Abbildung: DevOps

DevOps-Lernpfad

Abbildung: Karte

Kostenlos loslegen

Melde dich für unseren DevOps-Newsletter an

Thank you for signing up