---
title: "Visual Regression mit Lost Pixel und Gitlab"
description: "🕵️‍♀️ Visuelle Bugs in der Gitlab CI Pipeline finden - wir zeigen wie's mit Lost Pixel funktioniert."
canonical_url: "https://www.blueshoe.de/blog/visuelle-regression-in-gitlab-mit-lost-pixel/"
---

Bei Überarbeitung von CSS Regeln gibt es oftmals Seiteneffekte die zu spät bemerkt werden. Um diese zu finden eigenen sich Visual Regression Tests. Lost Pixel ist ein beliebtes, einfaches und sehr gutes Tool um diese Art von Tests auszuführen. Lost Pixel kommt von Haus aus mit Github Actions Support - die Integration in Gitlab ist also nicht ganz offensichtlich. Wir zeigen wie man Lost Pixel und Gitlab CI/CD zusammen verwendet.

![Visual Regression mit Lost Pixel und Gitlab](/img/blog/lost_pixel.svg)

<global-title :size="lg" className="mb-5">

Was ist Visual Regression Testing?

</global-title>

<global-paragraph>

Visual Regression Testing ermöglicht die Identifizierung von optischen Veränderungen basierend auf einer vorher festgelegten Basis. Diese Veränderungen beinhalten unter Umständen Regressionen, welche somit schnell und kostengünstig erkannt werden. Moderne Anwendungen beinhalten oftmals eine Menge JavaScript und CSS. Änderungen an dem Quellcode, oder auch einfache Updates können zu Seiteneffekten führen. Um diese aufzudecken, eignet sich Visual Regression Testing sehr gut.

</global-paragraph>

<global-title :size="lg" className="mb-5">

Wie funktioniert Visual Regression Testing?

</global-title>

<global-paragraph>

Das Vorgehen für VRT-Tools ist immer ähnlich:

</global-paragraph>

<global-block className="ol-decimal,mb-4">

1. Es wird eine Menge von Komponenten oder Seiten definiert, welche zu prüfen sind.
2. Basierend darauf wird eine Baseline generiert.
3. Bei Code Änderungen und Updates werden Screenshots gemacht und diese mit der Baseline verglichen.

</global-block>

<global-paragraph>

Oftmals arbeiten Tools im Bereich des Testing für visuelle Regressionen mit einem Threshold. Das bedeutet, die Abweichung von der Baseline hat eine Toleranz - absolut oder relativ. Beispielsweise könnte man festlegen, dass 10 Pixel oder 1% Abweichung von der Baseline akzeptiert werden.

</global-paragraph>

<global-paragraph>

Warum ist das so? - Das Rendering von Websites unterscheidet sich teilweise von Browser zu Browser sowie Betriebssystem zu Betriebssystem. Hier ist eine gewisse Toleranz ausgesprochen hilfreich.

</global-paragraph>

<global-title :size="lg" className="mb-5">

Lost Pixel in der Praxis

</global-title>

<global-paragraph>

[Lost Pixel](https://www.lost-pixel.com/) ist ein Tool der Firma nineLemon. Es ist cloud-basiert. Die einfachste Integration in eine CI Pipeline lässt sich mit Github Actions realisieren. Dabei übernimmt die Lost Pixel Cloud Applikation die Verwaltung der Baseline. Die Screenshots der Baseline müssen nicht in das Repository eingecheckt werden.

</global-paragraph>

![Lost Pixel front page](/img/blog/lost-pixel-1.png)

<global-paragraph className="italic,mb-4,text-center">

(Quelle: [https://lost-pixel.com](https://lost-pixel.com))

</global-paragraph>

<global-paragraph>

Mit der Einbindung der bereitgestellten Github Action werden automatisch Screenshots der festgelegten Seiten/Komponenten erstellt und mit der Baseline verglichen. Die Lost Pixel Cloud Applikation bietet hier hervorragende Ansichten für den Vorher-Nachher Vergleich.

</global-paragraph>

![Lost Pixel front page 2](/img/blog/lost-pixel-2.png)

<global-paragraph className="italic,mb-4,text-center">

(Quelle: [https://lost-pixel.com](https://lost-pixel.com) links nachher, rechts vorher)

</global-paragraph>

<global-paragraph>

Über die simple Benutzeroberfläche lassen sich Änderungen an der Baseline akzeptieren oder ablehnen. Bei Ablehnung wird der entsprechende Pull Request auf Github als “fehlgeschlagen” markiert.

</global-paragraph>

<global-title :size="lg" className="mb-5">

Lost Pixel mit Gitlab

</global-title>

<global-paragraph>

Github Actions ist de facto die “first class citizen” Implementierung von Lost Pixel in CI Pipelines. In diesem Abschnitt möchten wir zeigen, wie wir Lost Pixel mit der Software Gitlab verwenden.

</global-paragraph>

<global-title :size="md" className="mb-5" :color="text-bs-blue" :font="font-oswald" :tag="h3">

Erstellung der Baseline für Visual Regression Testing

</global-title>

<global-paragraph>

Zuerst wird die Basis erzeugt. Hierfür muss die `lostpixel.config.js` angelegt werden:

</global-paragraph>

<blog-code className="mb-4">

```js
module.exports = {
  pageShots: {
    pages: [
      { path: '/pattern-library/render-pattern/cms/blocks/patterns/text/text.html', name: 'text', threshold: 0.01 },
    ],
    breakpoints: [320, 640, 1024, 1200, 1920],
    baseUrl: 'http://localhost:8000',
  },
  waitBeforeScreenshot: 2000,
  waitForLastRequest: 5000,
  failOnDifference: true,
  shotConcurrency: 1,
  generateOnly: true,
}
```

</blog-code>

<global-paragraph>

Diese Konfiguration nutzt "Page Shots". Damit werden lediglich ganzseitige Screenshots von den entsprechenden URLs gemacht. Eine detaillierte Aufstellung der Einstellungen [ist hier zu finden](https://docs.lost-pixel.com/user-docs/setup/project-configuration). Der Parameter `breakpoints` ermöglicht es, unterschiedliche Bildschirmauflösungen gleichzeitig zu prüfen.

</global-paragraph>

<global-paragraph>

Zur Erzeugung und zum Vergleich der Baseline nutzen wir Docker Images, um Unterschiede durch Betriebssystem oder Browser zu minimieren. Hierfür wird die Baseline folgendermaßen erzeugt:

</global-paragraph>

<blog-code className="mb-4">

```bash
docker run --rm -v $PWD:$PWD -e WORKSPACE=$PWD -e DOCKER=1 -e LOST_PIXEL_DISABLE_TELEMETRY=0 -e LOST_PIXEL_MODE=update --network="host" lostpixel/lost-pixel:v3.22.0
```

</blog-code>

<global-paragraph>

Damit wird die Baseline neu erzeugt und lokal abgelegt. Da die Lost Pixel Cloud Plattform nicht mit Gitlab nutzbar ist, müssen diese Dateien ins Git Repository eingecheckt werden.

</global-paragraph>

<global-title :size="md" className="mb-5" :color="text-bs-blue" :font="font-oswald" :tag="h3">

Installation von Lost Pixel auf dem Gitlab Runner

</global-title>

<global-paragraph>

Zuallererst muss sichergestellt werden, dass Lost Pixel CLI in der Pipeline verfügbar ist:

</global-paragraph>

<blog-code className="mb-4">

```bash
apt-get update
apt-get install -y nodejs npm curl
npm i -g lost-pixel
npx playwright@1.47.2 install --with-deps chromium
```

</blog-code>

<global-paragraph>

Playwright wird in genau der Version installiert, welche für Lost Pixel benötigt wird.

</global-paragraph>

<global-paragraph>

Playwright ist ein modernes, von Microsoft entwickeltes End-to-End-Testframework, das für das Testen von Webanwendungen genutzt wird. Es ermöglicht automatisierte UI-Tests in mehreren Browsern.

</global-paragraph>

<global-title :size="md" className="mb-5" :color="text-bs-blue" :font="font-oswald" :tag="h3">

Visual Regression Testing in der CI Pipeline

</global-title>

<global-paragraph>

Die Ausführung des Vergleichs ist nun denkbar einfach. Wir starten unsere Applikation (in unserem Fall eine Django App) und führen das Kommando zum Vergleich aus:

</global-paragraph>

<blog-code className="mb-4">

```bash
python /app/die/manage.py serve --static &
npx lost-pixel local
```

</blog-code>

<global-paragraph>

Wir stellen sicher, dass die Screenshots temporär verfügbar sind um Unterschiede einfach untersuchen zu können. So können fehlgeschlagene Jobs einfach untersucht werden:

</global-paragraph>

<blog-code className="mb-4">

```yaml
# gitlab-ci.yaml
artifacts:
  paths:
    - .lostpixel/difference/*
    - .lostpixel/current/*
  expire_in: 1 week
  when: always
```

</blog-code>

<global-paragraph>

Anbei ein Auszug aus eine möglichen `gitlab-ci.yaml`. In diesem Fall führen wir eine Django Applikationen mit einer temporär verfügbaren, lokalen Postgres Datenbank aus:

</global-paragraph>

<blog-code className="mb-4">

```yaml
# gitlab-ci.yaml

stages:
  - lint
  - build
  - test
  - release
  - deploy

# [...]

visual_regression:
  stage: test
  image:
    name: ${TEST_IMAGE_NAME}
    docker:
      user: root
  services:
    - postgres:17-alpine
  before_script:
    - apt-get update
    - apt-get install -y nodejs npm curl
    - python die/manage.py migrate && npm i -g lost-pixel
    - npx playwright@1.47.2 install --with-deps chromium
  script:
    - python /app/die/manage.py serve --static &
    - npx lost-pixel local
  variables:
  # [...]
  artifacts:
    paths:
      - .lostpixel/difference/*
      - .lostpixel/current/*
    expire_in: 1 week
    when: always
```

</blog-code>

<global-title :size="md" className="mb-5" :color="text-bs-blue" :font="font-oswald" :tag="h3">

Auswertung des Visual Regression Tests

</global-title>

<global-paragraph>

Sollte der Job fehlschlagen lassen sich nun die Ergebnisse in der Seitenleiste von Gitlab einfach aufrufen:

</global-paragraph>

![Lost Pixel results](/img/blog/lost-pixel-3.png)

<global-paragraph>

Mit einem Klick auf *Durchsuchen* kann die Ordnerstruktur der Artefakte durchsucht werden:

</global-paragraph>

![Lost Pixel folders](/img/blog/lost-pixel-4.png)

<global-call-an-expert :bg="bg-bs-blue">
<template v-slot:buttonBlockTitle="">

Wir können visuelle Regression Tests auch für deine App einrichten.

</template>
</global-call-an-expert>

<global-title :size="lg" className="mb-5">

Welche alternativen Tools gibt es für Visual Regression Testing?

</global-title>

<global-paragraph>

Neben Lost Pixel, dem Tools welches wir bei [Blueshoe vornehmlich für Visual Regression Testing](/loesungen/automatisches-frontend-testing/) verwenden, gibt es auch einige Alternativen:

</global-paragraph>

<global-paragraph>

**Cloud-basierte Tools**

</global-paragraph>

<global-block className="ul-disk,mb-4">

- [Applitools Eyes](https://applitools.com/platform/eyes/) – KI-gestützte visuelle Tests mit Integration in viele Testframeworks
- [Percy (by BrowserStack)](https://www.browserstack.com/percy) – Automatisierte UI-Screenshots mit GitHub-Integration
- [Visual AI by LambdaTest](https://www.lambdatest.com/visual-regression-testing) – Cloud-basierte visuelle Regressionstests
- [Chromatic](https://www.chromatic.com/) – Speziell für Storybook-basierte UI-Tests

</global-block>

<global-paragraph>

**Open-Source & Selbst-gehostete Tools**

</global-paragraph>

<global-block className="ul-disk,mb-8">

- [BackstopJS](https://github.com/garris/BackstopJS) – Headless Browser-basierte visuelle Regressionstests
- [Wraith](https://github.com/bbc/wraith) – Von BBC entwickeltes Open-Source-Tool für Screenshot-Vergleiche
- [Resemble.js](https://rsmbl.github.io/Resemble.js/) – JavaScript-Bibliothek für pixelgenaue Bildvergleiche
- [Pixelmatch](https://github.com/mapbox/pixelmatch) – Leichtgewichtige Bildvergleichsbibliothek für visuelle Regressio

</global-block>

<global-title :size="lg" className="mb-5">

Fazit

</global-title>

<global-paragraph className="mb-4">

In der heutigen agilen Entwicklungswelt ist Visual Regression Testing ein entscheidender Bestandteil der Qualitätssicherung. Es hilft, unbeabsichtigte UI-Änderungen frühzeitig zu erkennen und stellt sicher, dass neue Features oder Bugfixes keine bestehenden Designelemente zerstören.

</global-paragraph>

<global-paragraph className="mb-4">

Durch den Einsatz moderner Tools wie Lost Pixel können Teams visuelle Tests effizient in ihre CI/CD-Pipelines integrieren und so die Konsistenz und Benutzerfreundlichkeit ihrer Anwendungen bewahren. Besonders im Zeitalter von komplexen Webanwendungen und responsivem Design ist ein zuverlässiges visuelles Testing ein echter Gamechanger.

</global-paragraph>

<global-paragraph>

Letztendlich spart Visual Regression Testing nicht nur Zeit und Kosten für manuelle UI-Überprüfungen, sondern trägt auch dazu bei, ein perfektes Nutzererlebnis zu gewährleisten – und das auf allen Geräten und Browsern. 🚀

</global-paragraph>

<global-title :size="lg" className="mb-5,mt-8">

Häufige Fragen

</global-title>

<global-title :size="md" className="mb-5" :color="text-bs-blue" :font="font-oswald" :tag="h3">

1. Was ist Lost Pixel und warum sollte ich es in GitLab nutzen?

</global-title>

<global-paragraph>

Lost Pixel ist ein Open-Source-Tool für visuelle Regressionstests. In GitLab-Pipelines hilft es, visuelle Unterschiede in der UI frühzeitig zu erkennen und Builds zu stoppen, wenn unerwartete Änderungen auftreten.

</global-paragraph>

<global-title :size="md" className="mb-5" :color="text-bs-blue" :font="font-oswald" :tag="h3">

2. Wie kann ich verhindern, dass nicht-relevante Änderungen Tests fehlschlagen lassen?

</global-title>

<global-block className="ul-disk,mb-4">

- Nutze `--diff-threshold`, um geringfügige Abweichungen zu ignorieren
- Verwende `excludeSelectors`, um dynamische Elemente (z. B. Datumsangaben) auszuschließen
- Stelle sicher, dass Screenshots unter identischen Bedingungen (Viewport, Theme) erstellt werden

</global-block>

<global-title :size="md" className="mb-5" :color="text-bs-blue" :font="font-oswald" :tag="h3">

3. Wie kann ich Lost Pixel mit GitLab Merge Requests kombinieren?

</global-title>

<global-paragraph>

Lost Pixel kann so konfiguriert werden, dass es bei Merge Requests ein visuelles Diff generiert und als Kommentar im MR anzeigt. Nutze dazu eine GitLab CI/CD-Integration oder externe Bots.

</global-paragraph>

<global-title :size="md" className="mb-5" :color="text-bs-blue" :font="font-oswald" :tag="h3">

4. Wie kann ich Lost Pixel so einrichten, dass nur manuell genehmigte Änderungen als neue Referenz gelten?

</global-title>

<global-block className="ul-disk,mb-4">

- Erstelle eine dedizierte `baseline`-Branch für Referenz-Screenshots
- Nutze einen CI/CD-Job, der nur nach Review geänderte Screenshots in die `baseline`-Branch merged

</global-block>

<global-title :size="md" className="mb-5" :color="text-bs-blue" :font="font-oswald" :tag="h3">

5. Warum schlägt Lost Pixel in GitLab zufällig fehl?

</global-title>

<global-block className="ul-disk,mb-4">

- Unstabile Screenshots entstehen oft durch zufällige UI-Elemente oder Animationen.
- Nutze den `--wait`-Parameter, um sicherzustellen, dass alle UI-Elemente gerendert wurden.

</global-block>

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
