Automatisierte Front-End-Tests mit BackstopJS und KSS-Styleguide

Was sind Front-End-Tests und warum sind sie hilfreich?

Front-End-Tests zielen darauf ab, die Benutzeroberfläche der Anwendung zu testen – also den Teil, mit dem Benutzer direkt interagieren. So können wir visuelle Fehler frühzeitig im Entwicklungsprozess erkennen.

Arten von Front-End-Tests

Benutzeroberflächen in modernen Webanwendungen können sehr komplex sein. Daher ist es nicht verwunderlich, dass es viele verschiedene Arten von Front-End-Tests gibt. Jeder einzelne konzentriert sich auf einen anderen Aspekt der Website.

Browserübergreifende Kompatibilitätstests

Es gibt eine Vielzahl von Browsern auf dem Markt, von denen Sie viele auf verschiedenen Betriebssystemen installieren können. Unterschiede in den Browser-Engines können visuelle Fehler in nur einem bestimmten Browser oder sogar nur einer bestimmten Version des Browsers verursachen.

Browserübergreifende Tests stellen sicher, dass alle visuellen Funktionen Ihrer Website auf allen wichtigen Browsern in Kombination mit allen gängigen Betriebssystemen funktionieren. Es gibt diverse Plattformen, die fertige Umgebungen für browserübergreifende Tests bieten, z. B. BrowserStack, LambdaTest oder Browserling.

Zugänglichkeitstests

Nach Angaben der WHO gibt es weltweit mehr als 1 Milliarde Menschen, die von einer Behinderung betroffen sind. Einige von ihnen, wie Seh- oder motorische Behinderungen, erschweren die Navigation und Nutzung von Websites erheblich oder machen dies sogar unmöglich.

Die bessere Zugänglichkeit einer Website kommt auch anderen Nutzern zugute. Das ist etwa der Fall, wenn Sie die Website bei direkter Sonneneinstrahlung oder auf einem Bildschirm mit schlechter Qualität betrachten.

Um sicherzustellen, dass Ihre Website benutzerfreundlich ist, sollten Sie die für die Zugänglichkeit entscheidenden Teile Ihrer Website testen, wie etwa den Textkontrast, Formularbeschriftungen, Alternativtexte zu Bildern oder die Tastaturnavigation. Weitere Einzelheiten zur Barrierefreiheit Ihrer Website finden Sie in unserem Blogbeitrag zu diesem Thema: How to make your website accessible for everyone.

Visuelle Regressionstests

Visuelle Regressionstests stellen sicher, dass sich die an einer Komponente vorgenommenen Änderungen nicht ungewollt auf andere Teile der Website auswirken. Es ist nicht ungewöhnlich, dass Aktualisierungen der Komponente A einen Einfluss darauf haben, wie Komponente B aussieht – etwa wenn sie aus Komponenten A besteht. Ein Entwickler, der an Komponente A arbeitet, könnte das nicht erkennen und so visuelle Fehler auf der Website verursachen.

Visuelle Regressionstests lösen dieses Problem. Sie erstellen automatisch Screenshots von bestimmten Komponenten und vergleichen diese mit der Referenzversion. In diesem Blogbeitrag werde ich einen möglichen Ansatz für diese Art von Front-End-Test beschreiben.

Organisieren Sie Ihre Komponenten in einem "lebenden Styleguide"

Wenn Sie und Ihr Team an einer Website mit vielen benutzerdefinierten Elementen arbeiten, ist es eine gute Idee, all diese an einem Ort zu sammeln. Auf der einen Seite wird es für Designer einfacher, neue Layouts aus bereits definierten Komponenten zu erstellen. Auf der anderen Seite haben Entwickler eine Liste von Elementen, die während der Implementierung einfach verwendet werden können.

Ein lebender Styleguide ist in diesem Fall die perfekte Lösung. Im Gegensatz zu statischen Styleguides, also reinen PDF-Dokumenten, müssen Sie diese nicht ständig manuell aktualisieren, wenn sich etwas an Ihren Komponenten ändert. Stattdessen handelt es sich um eine Website. Sie müssen lediglich eine Liste von Elementen definieren, die Sie im Styleguide haben möchten. Diese Elemente sind dann auf dieser Website verfügbar, wobei das Styling direkt aus dem Quellcode Ihres Projekts stammt. Auf diese Weise müssen Sie sich nicht bei jeder CSS-Änderung um die Aktualisierung des Styleguides kümmern. Das spart Zeit für Ihr Team.

Es gibt viele Hilfsmittel, die Ihnen bei der Erstellung eines lebenden Styleguides helfen. In diesem Beitrag werden wir uns auf kss-node konzentrieren, das auf der KSS-Dokumentationssyntax für Stylesheets basiert.

Verwendung von kss-node zur Erstellung eines Styleguides

Installation

Hier ist die package.json-Datei. Sie enthält das kss-node-Paket und ein Skript, das unseren Styleguide generiert. Es beinhaltet auch „node-sass“, was unsere SCSS-Dateien zu CSS kompilieren wird.

{
  "scripts": {
    "styles": "node-sass scss/style.scss > style.css",
    "styleguide": "npm run styles && kss --source scss --destination styleguide --css ../style.css --homepage homepage.md",
    "backstop-reference": "npm run styleguide && backstop reference --config=backstop.js --docker",
    "backstop-test": "npm run styleguide && backstop test --config=backstop.js --docker"
  },
  "devDependencies": {
    "kss": "^3.0.1",
    "node-sass": "^6.0.1"
  },
  "dependencies": {}
}

Vor der Installation sollten Sie einen Blick auf den Befehl „kss“ werfen. Er benötigt einige Parameter:

  • --source --- in dem kss nach den KSS-Kommentaren sucht
  • --css --- .css-Datei zur Aufnahme in den Styleguide
  • --homepage --- Datei die zur Homepage Ihres Styleguides wird

Führen Sie npm install aus, um alle Komponenten zu installieren.

Dokumentation der Komponenten

Nehmen wir an, wir haben die Komponenten Schaltfläche und Karte (in diesem Blogbeitrag werde ich die SCSS-Syntax für alle Stylesheets verwenden):

.button {
  font-weight: 700;
  font-size: 18px;
  padding: 8px 20px;
  background-color: #9EBD71;
  color: white;
  text-align: center;

  &.secondary {
    background-color: #116D56;
  }

  &:hover {
    opacity: 0.7;
  }
}
.card {
  position: relative;
  display: block;
  box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.15);
  background-color: #F8FAF4;
  padding: 10px;
  width: 300px;

  @media screen and (max-width: 767px){
    width: 220px;
  }

  &__title {
    text-align: center;
    font-weight: 700;
    font-size: 30px;
  }

  &__buttons {
    text-align: center;
  }
}

Wie fügen wir nun diese Komponenten zu unserem Styleguide hinzu? Das ist sehr einfach. Wir müssen nur einen Kommentar über der Elementdefinition hinzufügen und dabei der KSS-Syntax folgen:

// Button 

Der Name des Elements: Dies wird der Titel des Abschnitts zu diesem Element im Styleguide sein.

// Standard Kiwee button 

Die Beschreibung des Elements.

// Markup:
// <a class="button" href="">Button</a> 

Das Markup des Elements; alternativ können Sie das Markup in eine separate Datei verschieben und den Dateinamen hier angeben.

// Style guide: elements.button 

Der Pfad dieses Elements in der Styleguide-Navigation

Ähnliches gilt für card:

// Card
//
// Card with two buttons
//
// Markup:
// <div class="card">
//   <span class="card__title">Card title</span>
//   <p>
//     Lorem ipsum dolor sit amet, consectetur adipiscing elit,
//     sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
//     Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
//   </p>
//   <div class="card__buttons">
//     <a class="button" href="">Button</a>
//     <a class="button secondary" href="">Read more</a>
//   </div>
// </div>
//
// Style guide: elements.card

Jetzt können Sie npm run styleguide ausführen. Dabei wird das Verzeichnis styleguide erstellt. Wir könnten jetzt einfach styleguide/index.html in unseren Browser eingeben. Allerdings werden nicht alle Funktionen des Styleguides korrekt funktionieren, wenn er als lokale .html-Datei angezeigt wird. Lassen Sie uns daher einen einfachen lokalen Server konfigurieren, um unseren Styleguide schnell bereitzustellen.

Erstellen Sie Dockerfile in docker/styleguide-nginx mit dem folgenden Inhalt:

FROM nginx:alpine
COPY style.css /usr/share/nginx/html

Erstellen Sie die Datei docker-compose.yml:

version: '3.7'

services:
 styleguide:
   build:
     context: .
     dockerfile: docker/styleguide-nginx/Dockerfile
   ports:
     - "8081:80"
   volumes:
     - ./styleguide:/usr/share/nginx/html
     - ./style.css:/usr/share/nginx/html/style.css

Hinweis: Wenn Sie mit Linux arbeiten, fügen Sie

extra_hosts:
  host.docker.internal: host-gateway

Unterhalb der Ports-Erklärung hinzu. Dies funktioniert nur in Docker v20.10+.

Führen Sie nun einfach docker-compose up -d aus. Der Styleguide sollte unter localhost:8081 erreichbar sein.

Und schon sind unsere Elemente im Styleguide dokumentiert. Sie können alle Informationen aus unserem Kommentar sowie einen Pfad zur Datei button.scss sehen, in der dieses Element dokumentiert ist.

Es gibt aber noch eine Sache, die wir verbessern können. Wenn Sie sich die Datei button.scss ansehen, erkennen Sie, dass wir das Aussehen der Schaltfläche beim Hovern verändern. Wir haben auch die Klasse .secondary hinzugefügt, welche die Hintergrundfarbe der Schaltfläche ändert. Im Styleguide ist dies jedoch nicht ersichtlich.

Glücklicherweise gibt es eine einfache Möglichkeit, alle Zustände des Elements zu dokumentieren, ohne dass Sie dasselbe Markup mit verschiedenen Klassen wiederholen müssen. Man nennt das Modifikatorenklasse.

Der erste Schritt besteht darin, alle Zustände zu definieren, die Sie dokumentieren wollen. In unserem Fall sind das die Klasse .secondary und die Schaltfläche bei :hover. Dann fügen Sie {{modifier_class}}-Platzhalter in den Elementen class hinzu. Der resultierende Kommentar sieht wie folgt aus:

// Button
//
// Standard Kiwee button
//
// .secondary - Use this class to indicate that the button is the primary
//              feature of this form.
// :hover     - Highlight the button when hovered.
//
// Markup:
// <a class="button {{modifier_class}}" href="">Button</a>
//
// Style guide: elements.button

Nun führen wir npm run styleguide noch einmal aus. So sehen wir, wie sich der Styleguide verändert hat:

Jetzt ist jeder Zustand und jeder Modifikator unseres Elements gut dokumentiert und für jeden sichtbar, der an dem Design oder der Implementierung arbeitet.

Verwenden Sie BackstopJS, um alle visuellen Fehler auf Ihrer Website zu erkennen

BackstopJS ist ein Open-Source-Tool zur Durchführung visueller Regressionstests. Es verwendet einen kopflosen Browser, um Screenshots von Ihrer Website zu erstellen. Dann vergleicht es sie mit zuvor gespeicherten Referenzdateien. Wenn sich diese Bilder unterscheiden, zeigt BackstopJS die Unterschiede zwischen ihnen an. Dies ist ein guter Indikator für eine visuelle Regression – eine unerwünschte Veränderung im Aussehen eines Elements.

Installation und Konfiguration

Beginnen wir mit der Installation von BackstopJS für unser Projekt:
npm install -g backstopjs

Erstellen Sie eine Konfigurationsdatei backstop.js im Stammverzeichnis des Projekts.

const styleguideUrl = 'http://host.docker.internal:8081'

module.exports = {
  "id": "backstop_default",
  "viewports": [
    {
      "label": "phone",
      "width": 375,
      "height": 677
    },
    {
      "label": "desktop",
      "width": 1920,
      "height": 1080
    },
  ],
  "scenarios": [
    {
      "label": "Button",
      "url": `${styleguideUrl}/section-elements.html`,
      "referenceUrl": `${styleguideUrl}/section-elements.html`,
      "selectors": ["#kssref-elements-button .kss-modifier__wrapper"],
      "removeSelectors": [".kss-modifier__heading"]
    },
    {
      "label": "Card",
      "url": `${styleguideUrl}/section-elements.html`,
      "referenceUrl": `${styleguideUrl}/section-elements.html`,
      "selectors": ["#kssref-elements-card .kss-modifier__wrapper"],
      "removeSelectors": [".kss-modifier__heading"]
    },
  ],
  "paths": {
    "bitmaps_reference": `backstop_data/bitmaps_reference`,
    "bitmaps_test": `backstop_data/bitmaps_test`,
    "html_report": `backstop_data/html_report`,
  },
  "engine": "puppeteer",
  "engineOptions": {
    "args": ["--no-sandbox"]
  },
}

Wir bestimmen zuerst styleguideUrl, um den zuvor erstellten Styleguide zu finden. Wir verwenden host.docker.internal anstelle von localhost, da sonst BackstopJS – das im Docker-Container läuft – nicht auf den Server zugreifen kann. Ich werde dies später in diesem Beitrag näher erläutern.

Das Objekt „Viewports“ enthält alle Bildschirmgrößen, die für die Tests verwendet werden. Die Screenshots werden für jedes Szenario in jedem definierten Viewport erstellt.
Jedes Szenario bietet mehrere Felder, von denen wir uns einige ansehen:

  • url, referenceUrl --- URLs zum Testen und Erstellen entsprechender Referenz-Screenshots. In unserem Fall sind beide Variablen auf ${styleguideUrl}/section-elements.html gesetzt. Wir werden die Verweise aus dem grundlegenden Styleguide speichern und den Test mit der aktualisierten Version durchführen.
  • selectors --- ein Array von Selektoren, die erfasst werden sollen. In unserem Fall wollen wir die KSS-Styleguide-Elemente Schaltflächen und Karten erfassen.
  • removeSelectors --- Liste der Selektoren, die vor der Aufnahme des Screenshots entfernt werden sollen. Hier beseitigen wir die KSS-Überschrift, da sie nicht Teil unserer Komponente ist.

Generierung von Referenz-Screenshots

Da wir nun alle notwendigen BackstopJS-Konfigurationen haben, fügen wir zwei Skripte in package.json hinzu:

"backstop-reference": "npm run styleguide && backstop reference --config=backstop.js --docker",
"backstop-test": "npm run styleguide && backstop test --config=backstop.js --docker"

Beachten Sie, dass wir hier die Option --docker verwenden. Dabei wird BackstopJS, wie in der Dokumentation beschrieben, in einem Docker-Container ausgeführt:

Übergeben Sie die Option --docker, um Ihren Test in einem Docker-Container zu rendern. Dies hilft bei der Konsistenz, wenn Sie versuchen, Referenzen über mehrere Umgebungen hinweg zu vergleichen.”

Beginnen wir mit der Erstellung von Referenzen aus dem aktuellen Styleguide.
npm run backstop-reference

Wenn alles gutgegangen ist, sollten Sie die Screenshots unserer Komponenten aus dem Styleguide in backstop_data/bitmaps_reference sehen. Diese Referenzen werden mit allen zukünftigen BackstopJS-Tests verglichen.

Durchführung visueller Regressionstests

Jetzt haben wir unsere grundlegenden Screenshots. Nun können wir BackstopJS endlich zum Testen verwenden.

Stellen Sie sich vor, wir implementieren ein neues Design für die Schaltflächen. Wir wollen ihr Padding vergrößern. Wir ändern padding: 4px 12px; in padding: 8px 20px;.

Die Implementierung ist abgeschlossen. Jetzt ist es an der Zeit, die Tests durchzuführen:

npm run backstop-test

Der Testbericht wird automatisch in Ihrem Browser geöffnet.

So weit, so gut. Die Tests sind hier offensichtlich gescheitert. Aber das war zu erwarten, da wir das Padding vergrößert haben. BackstopJS hebt alle Unterschiede zwischen Referenz- und Test-Screenshots in rosa hervor. Werfen wir einen Blick auf andere fehlgeschlagene Tests.

Ups! Das Kartenelement auf mobilen Geräten ist jetzt komplett zerstört. Zwei Schaltflächen passen nicht in eine Reihe mit dem größeren Padding. Es gibt ein paar Möglichkeiten, das Problem zu beheben: die Karte etwas breiter machen, das Padding der Schaltflächen nur innerhalb der Karte verringern usw. Sie können das Problem beheben, wie Sie möchten. Wichtig ist, dass wir diesen visuellen Fehler dank BackstopJS entdeckt haben.

Aktualisierung der Backstop-Referenzen

Aber was ist, wenn Tests aufgrund von absichtlichen Änderungen im Design fehlschlagen? In diesem Fall sollten Sie die BackstopJS-Referenzen im Repository aktualisieren. Führen Sie dazu npm run backstop-reference erneut aus und übertragen Sie die aktualisierten Referenzen.

Tracking von BackstopJS-Dateien in Git

Wenn Sie zum Projekt zurückkehren, werden Sie feststellen, dass BackstopJS zwei neue Ordner in backstop_data erstellt hat: bitmaps_test und html_report. Wie der Name schon sagt, enthalten diese Verzeichnisse Testergebnisse. Im Gegensatz zu den Referenzen handelt es sich dabei jedoch um unsere lokalen Testergebnisse, die nicht im Repository gespeichert werden sollten. Fügen Sie diese beiden Zeilen zu .gitignore hinzu:

backstop_data/html_report/
backstop_data/bitmaps_test/

Sie sollten backstop_data/bitmaps_reference zum Repository hinzufügen. Dies ist die Baseline, die Sie mit dem gesamten Entwicklungsteam teilen sollten. Alle Tests sollten gegen sie laufen.

Andere mögliche Anwendungen für BackstopJS

Automatischer Test bei jedem Branch Push

Kürzlich haben wir BackstopJS-Tests zur CI-Pipeline hinzugefügt, die bei jedem Branch Push ausgelöst wird. Unser Workflow sieht folgendermaßen aus:

  1. Wir speichern alle grundlegenden Referenzen im Repository.
  2. Bei jedem Branch Push wird der Styleguide aus dem Quellcode dieser Branch generiert.
  3. Die BackstopJS-Tests werden ausgeführt, wobei die Baselines mit dem im vorherigen Schritt erstellten Styleguide verglichen werden.
  4. Testergebnisse und Berichte sind nach jeder Ausführung der Pipeline verfügbar.

Regelmäßige Prüfung ganzer Seiten

Wir haben auch eine Pipeline, die jede Nacht läuft und verschiedene Aspekte der Website testet. Ein Teil davon sind visuelle Regressionstests auf der Live-Website. In diesem Fall werden ganze Seiten und nicht nur einzelne Komponenten getestet. Sie gibt uns keine genauen Informationen über die fehlgeschlagene Komponente. Sie hilft uns aber, Teile abzudecken, die nicht im Styleguide enthalten sind. Das funktioniert folgendermaßen:

  1. Referenzen werden auf dem Server gespeichert.
  2. Wenn ein Test fehlschlägt, hält die Pipeline an und wartet auf Benutzereingaben. Wenn die fehlgeschlagenen Tests das Ergebnis beabsichtigter Änderungen sind, löst die manuelle Zustimmung eine automatische Aktualisierung der Referenzen aus. Andernfalls gibt uns der Testbericht Aufschluss darüber, was sich genau geändert hat. So können wir schnell Korrekturen vornehmen.

Zusammenfassung

Die Einführung eines lebenden Styleguides in Ihr Projekt lohnt sich in jedem Fall. Er hilft Ihnen, doppelten CSS-Code zu vermeiden, und gibt Designern und Entwicklern einen guten Überblick über die Komponenten, die bereits zur Verfügung stehen. In Kombination mit BackstopJS-Regressionstests erhalten Sie ein effektives Tool, um visuelle Bugs schon in der Entwicklungsphase zu verhindern.

Das in diesem Blogbeitrag vorgestellte Beispiel ist natürlich sehr einfach. Wenn das Projekt allerdings Dutzende von Komponenten hat, von denen einige von anderen abhängen, kann es sehr schwierig sein, alle zu überprüfen und unerwünschte Änderungen oder Fehler zu erkennen. Anstatt die Elemente jedes Mal manuell durchzugehen, können Sie visuelle Regressionstests zu Ihrem Projekt hinzufügen. Der Aufwand für die Grundkonfiguration von BackstopJS ist nicht allzu groß, kann aber viele Fehler vermeiden. So erleichtern Sie die Arbeit von Webentwicklern ein wenig.

Den vollständigen Code des vorgestellten Beispiels finden Sie hier: BackstopJS regression tests demo.

FacebookTwitterPinterest