QA und Testen

resized_image_400x400 resized_image_400x400

Bei Webdelo ist das Testen Teil der Architektur und Kultur, nicht ein separater Schritt. Wir entwerfen Systeme so, dass es für Bugs schwierig ist, zu erscheinen. Qualität wird auf allen Ebenen sichergestellt: von der Modulgestaltung bis zu den Bereitstellungs- und Überwachungsprozessen.
QA ist ein Teamprozess. Er umfasst Entwickler, QA-Ingenieure und DevOps. Alles beginnt mit dem Verständnis der Anforderungen. Es wird mit dem Schreiben von testbarem Code fortgesetzt. Es endet mit der CI/CD-Pipeline, die automatisch überprüft, ob das Produkt korrekt funktioniert.
Das Testen zeigt, wie sich das System unter vorhersehbaren und unvorhersehbaren Bedingungen verhält, sogar unter Last und in Szenarien, die zu Beginn nicht berücksichtigt wurden. So gewährleisten wir den stabilen Betrieb des Systems in der Produktionsumgebung und implementieren Änderungen mit Zuversicht, ohne Risiko für die Benutzer.

resized_image_400x400 resized_image_400x400
Allgemeine Prinzipien der QA

Allgemeine Prinzipien der QA

Die Zuverlässigkeit des Produkts beginnt nicht zum Zeitpunkt der Veröffentlichung, sondern schon lange davor — in der Planungs- und Entwicklungsphase. Damit die Webdelo-Systeme stabil laufen, integrieren wir Qualitätsprinzipien in die Architektur, die Prozesse und die Kultur des Teams. In diesem Abschnitt erfahren Sie, wie wir die Testbarkeit von Anfang an umsetzen, die Automatisierung einrichten und die Zusammenarbeit zwischen Entwicklern und QA-Ingenieuren in allen Phasen gestalten.

Die Rolle der QA im Entwicklungsprozess

Wir integrieren Tests in den frühesten Phasen. Wenn der Architekt Module entwirft - legt er die Testbarkeit fest. Wenn der Entwickler Code schreibt - schreibt er sofort auch die Tests. Wenn die QA die Aufgabe erhält - kennt sie den Kontext, die Architektur und die Ziele.

Der Einstiegspunkt der QA ist nicht das Code-Review, sondern die Aufgabenstellung. Das reduziert die Anzahl der Bugs und beschleunigt die Behebung von Fehlern.

Wie wir große Projekte testen

Wir gestalten den Prozess so, dass jede Phase logisch an die vorherige anschließt und wichtige Aspekte des Systems überprüft.

Zuerst deckt der Entwickler die zentrale Geschäftslogik mit Unit-Tests ab. Diese Tests sind schnell und decken die Schlüsselberechnungen und Regeln ab. Danach werden Integrationsprüfungen durchgeführt – sie helfen zu überprüfen, ob der Dienst korrekt mit der Datenbank, den Warteschlangen und externen APIs interagiert.

Anschließend wird eine manuelle Überprüfung hinzugezogen. Der QA-Spezialist prüft die Schnittstellen, das Verhalten in Browsern und komplexe Fälle, in denen Automatisierung möglicherweise ineffektiv sein könnte. Danach folgt die Regression – das erneute Testen zuvor funktionierender Szenarien. In der Pre-Release-Phase stellen wir sicher, dass Updates die Kompatibilität nicht beeinträchtigen und das System Belastungen standhält.

Nach der Veröffentlichung werden Monitoring-Tools aktiviert: wir überwachen die Protokolle, Fehler und Metriken, um rechtzeitig zu reagieren, falls etwas schiefgeht.

Die Rolle von CI/CD bei der Qualitätssicherung

Jede Änderung im Code löst eine Kette von Prüfungen aus. Zuerst werden die Tests ausgeführt: Unit-Tests, Integrations- und e2e-Tests. Dann werden Linter und statische Analysen hinzugezogen, um sicherzustellen, dass der Code den Standards des Teams entspricht. Danach vergleichen die Frontend-Bauten und Regressionstests die Ergebnisse mit früheren Versionen.

Wenn alles erfolgreich ist, kann der Code gemergt werden. Wenn nicht, stoppt CI. Dies schließt das Einpflegen von nicht funktionalen Änderungen in die Produktion aus und beschleunigt das Debugging.
Reduzierung von Bugs in der Produktion um 60 % dank CI/CD
Nach der Implementierung von automatisierten Tests über GitLab CI, einschließlich komplexer Szenarien und Regressionstests, erzielte GitLab eine signifikante Reduzierung der Anzahl an Bugs in der Produktionsumgebung — etwa um 60 %. Das Team beschleunigte die Releases dank zuverlässiger Automatisierung jedes Commits.
GitLab

Testarten und ihre Zwecke

Wir verwenden verschiedene Arten von Tests, von denen jeder für seine eigene Zuverlässigkeitsstufe verantwortlich ist.

Unit-Tests überprüfen einzelne Funktionen und Module. Sie werden schnell ausgeführt und schützen die grundlegende Geschäftslogik. Integrationstests zeigen, wie Teile des Systems miteinander interagieren: zum Beispiel und Dienst und Datenbank. End-to-End-Tests reproduzieren das Verhalten des Benutzers — vom Einloggen bis zur Bestellung.

Darüber hinaus führen wir manuelle Überprüfungen durch. Dies hilft sicherzustellen, dass die Benutzeroberfläche korrekt funktioniert, alles wie vorgesehen aussieht und das System gegenüber ungewöhnlichen Szenarien stabil ist.

Checklisten, Testfälle und Szenarien

Um wichtige Szenarien nicht zu verpassen, gestalten wir die Überprüfung in verständlichen und reproduzierbaren Formaten:
  • PHPUnit, Cypress, Playwright, Vitest — für automatische Tests auf allen Ebenen: vom Backend bis zur Benutzeroberfläche.
  • Postman und Newman — für das Testen und die Automatisierung von APIs.
  • Sentry, Prometheus, Grafana — um Fehler, Metriken, Ausfälle und Leistung zu überwachen.
  • Loki, Jaeger, Graylog — für das Loggen und die Nachverfolgung von Anfragen in verteilten Systemen.
Alle Werkzeuge sind in CI/CD integriert. Wenn ein Test fehlschlägt, erfahren wir sofort davon.

Regression und Pre-Release-Prüfung

Vor der Veröffentlichung führen wir eine umfassende Kontrolle durch:
  • Wir überprüfen, dass alte Funktionen weiterhin wie erwartet funktionieren (Regression).
  • Wir führen Migrationen im Stand durch und rollen sie zurück, um die Zuverlässigkeit sicherzustellen.
  • Wir vergleichen die Leistungskennzahlen vor und nach den Änderungen.
  • Wir überprüfen, dass externe Dienste, mit denen wir integrieren, weiterhin verfügbar und versioniert sind.
Die endgültige Entscheidung liegt bei QA. Ohne seine Bestätigung geht die Aufgabe nicht in die Veröffentlichung.

Interaktion von QA mit Entwicklern

Die Arbeit von QA und Entwicklern basiert auf einer klaren Aufteilung der Verantwortlichkeiten und ständiger Interaktion.
  • Wer schreibt die Tests?
    Der Entwickler schreibt Unit-Tests für seine Geschäftslogik und deckt Services, Anfragen, Controller ab. Wenn die Komponente komplex ist, fügt er auch Integrationstests oder e2e-Tests hinzu, besonders für kritische Benutzerszenarien. QA konzentriert sich auf die Benutzerszenarien und Logik, basierend auf den vom Entwickler durchgeführten Überprüfungen.
  • Wer testet manuell?
    Manuelles Testen ist die Verantwortung von QA. Es handelt sich um visuelle Überprüfungen, UX, Cross-Browser-Kompatibilität, mobile Versionen, unkonventionelle Fälle, Integrationen. QA arbeitet mit Checklisten, reproduziert Edge-Cases und vergleicht das Verhalten mit der Spezifikation.
  • Wer schreibt Bug-Reports?
    Alle Bugs werden von QA beschrieben. Er formuliert die Schritte zur Reproduktion, das erwartete und das tatsächliche Ergebnis, die Umgebung und Screenshots. Es ist wichtig, dass der Bug-Report klar und verständlich ohne unnötige Interpretation ist. Der Entwickler erhält den Bug - und bestätigt ihn entweder oder klärt ihn mit dem Autor.
  • Wie interagieren wir?
    Jeder Merge-Request durchläuft QA: er überprüft die Abdeckung, das Verhalten und die Regression. Wenn Verbesserungen nötig sind, schreibt er Kommentare. QA nimmt auch am Grooming von Aufgaben teil, um im Voraus die benötigten Szenarien festzulegen. Alle Vereinbarungen werden in Bug-Reports oder Testdokumentationen dokumentiert.


Eine solche Interaktion hilft dem Team, schneller und effizienter zu arbeiten. Jeder weiß, wofür er verantwortlich ist, und arbeitet mit dem Fokus auf stabile Ergebnisse.
Code Testing: Go

Testen im Code: Go

Go wurde als Sprache für unsere hochbelasteten Mikrodienste gewählt. Seine strenge Typisierung, Einfachheit und hohe Leistung erfordern klare Disziplin im Testen. Hier ist es besonders wichtig, die Hauptlogik der Anwendung zu trennen, sicherzustellen, dass sie korrekt mit externen Diensten interagiert, und eine stabile automatische Überprüfung jeder Änderung einzurichten.

Unit-Tests in Go

Wir verwenden das Standardpaket testing und die Bibliothek testify für bequeme Assertions. Unit-Tests in Go sind eine schnelle und zuverlässige Möglichkeit, sicherzustellen, dass die Geschäftslogik korrekt funktioniert. Wir halten uns an eine lesbare Benennungsweise (TestXxx_WhenYyy_ShouldZzz) und überprüfen sowohl normale als auch Grenzfälle des Verhaltens des Systems — zum Beispiel leere Felder, Maximalwerte oder unerwartete Daten.

Integrationstests

Wenn es notwendig ist, die Interaktion zwischen Diensten, Datenbanken oder Nachrichtenbrokern zu überprüfen, verwenden wir httptest, dockertest und Testkonfigurationen mit temporären Containern. Dies ermöglicht es, PostgreSQL, Redis, Kafka und andere Abhängigkeiten in einer isolierten Umgebung zu betreiben. Wir führen das System unter Bedingungen aus, die den realen so nahe wie möglich kommen, jedoch ohne die Verwendung von echten Benutzerdaten.

Mocking und falsche Implementierungen

Um einzelne Teile des Systems zu testen, ohne das gesamte übrige zu beeinträchtigen, setzen wir anstelle der echten Komponenten spezielle Stubs ein — sie simulieren das Verhalten, führen jedoch keine echten Aktionen aus. Dafür verwenden wir die Werkzeuge gomock und mockery. Da alle Abhängigkeiten über Schnittstellen verbunden sind, können wir beispielsweise die Datenbank oder API einfach durch einen simplen Mock ersetzen, der vorhersehbare Antworten liefert. Dies ermöglicht es, sich auf die Überprüfung der Logik des Codes zu konzentrieren, anstatt auf die Funktionsweise des gesamten Systems.

Abdeckung und Testbarkeit

Wir entwerfen Module so, dass sie bequem stückweise getestet werden können. Das bedeutet: Die Logik ist separat ausgelagert, Abhängigkeiten lassen sich leicht austauschen, und das Verhalten kann isoliert reproduziert werden.

Um zu verstehen, wie gut unser Code durch Tests geschützt ist, überprüfen wir seine „Abdeckung“ — das heißt, welche Teile des Codes tatsächlich durch Tests durchlaufen werden. Dafür nutzen wir:
  • go test -coverprofile=coverage.out — erstellt eine spezielle Datei, in der ersichtlich ist, welcher Prozentsatz der Codezeilen während der Tests ausgeführt wurde;
  • go tool cover -html=coverage.out — öffnet eine benutzerfreundliche farbliche Visualisierung: getestete Zeilen sind hervorgehoben, ungetestete — nicht.


So sehen wir sofort, wo Schwachstellen geblieben sind, und können die notwendigen Prüfungen hinzufügen.

Ziel dieser Abdeckung ist es, Risikozonen und Wachstumspunkte zu identifizieren. Wenn sie abnimmt, überarbeiten wir die Architektur oder verstärken die Tests.

CI für Go

Jedes Mal, wenn ein Entwickler Änderungen in das Repository sendet, wird automatisch eine Reihe von Prüfungen gestartet. Das macht das System GitHub Actions. Es führt Schritt für Schritt aus:
  • Automatisches Ausführen aller Tests mit dem Befehl go test ./.... Dies überprüft, ob die Funktionalität des bereits geschriebenen Codes beeinträchtigt ist.
  • Prüfung der Qualität und Sicherheit des Codes: Die Befehle go vet, staticcheck und golangci-lint erkennen potenzielle Fehler, falsche Datentypen und Verstöße gegen den Code-Stil.
  • Bewertung der Testabdeckung - um zu verstehen, wie gut der Code getestet ist.


Wenn eine Prüfung fehlschlägt, wird der Prozess gestoppt. Der Entwickler erhält Feedback und kann sofort Korrekturen vornehmen. Das hilft, Bugs zu vermeiden, noch bevor die Änderungen in den Hauptzweig des Projekts gelangen. Erst nach erfolgreichem Abschluss aller Phasen kann der Code mit dem Hauptteil des Systems zusammengeführt werden.
Code Testing: PHP / Laravel

Testen im Code: PHP / Laravel

In Laravel spielen Ereignisse, Warteschlangen, Formulare und Migrationen eine besondere Rolle. All dies muss durch Tests abgedeckt werden, da sonst das Risiko von Ausfällen nach Updates steigt. Jede Aufgabe durchläuft Unit-Tests, Szenarientests und eine manuelle Überprüfung, wenn nötig. CI weist sofort darauf hin, wo der Fehler liegt, und Mock-Services sowie Factory-Klassen beschleunigen die Überprüfung. Dank dieser Kombination bleibt Laravel selbst in großen Projekten vorhersehbar.

Unit-Tests in Laravel

phpunit ist das Hauptwerkzeug, das wir für die automatische Überprüfung des Codes in Laravel verwenden. Es hilft uns sicherzustellen, dass die wesentlichen Teile des Systems — wie zum Beispiel Dienste, Formulare, Validierung und Geschäftslogik — wie vorgesehen funktionieren. Wir schreiben Tests, die überprüfen, ob eine Funktion die gewünschte Aktion ausführt: zum Beispiel, dass eine Bestellung tatsächlich erstellt wird, der Benutzer eine Benachrichtigung erhält und das Formular einen Fehler bei falschen Daten zurückgibt. Wir speichern die Tests in denselben Ordnern wie den Hauptcode und halten die gleiche Struktur von Projekt zu Projekt ein. Dies ermöglicht es jedem Entwickler, sich schnell zurechtzufinden: wo sich die benötigten Tests befinden, wofür sie verantwortlich sind und wie sie zur Überprüfung ausgeführt werden können. Dies macht den Testprozess transparent und wartungsfreundlich.

Feature und Integrationstests

Wir überprüfen die Funktionsweise der Schlüsselelemente der Anwendung — Routen, Middleware und Datenbankmigrationen. Das hilft sicherzustellen, dass Benutzeranfragen die richtigen Routen durchlaufen, alle Prüfungen durchgeführt werden und die Struktur der Datenbank den Erwartungen entspricht. Um die Tests von realen Daten und externen Prüfungen unabhängig zu machen, verwenden wir withoutMiddleware() — es schaltet alle Middleware aus, und RefreshDatabase — es setzt die Datenbank vor jedem Test zurück. Dies gibt uns einen „sauberen“ Zustand und erhöht die Zuverlässigkeit der Tests. Wir prüfen nicht nur Standard-Szenarien, sondern auch Grenzfälle: leere Felder, sehr lange Werte, fehlerhafte Daten — damit die Anwendung robust mit allen Eingabedaten umgeht.

Mocking und Fakes

Um die Geschäftslogik zu testen, ohne von externen Diensten abhängig zu sein, setzen wir stattdessen temporäre Platzhalter ein. Das hilft, die Zuverlässigkeit, die mit Netzwerken, externen APIs und Datenbanken verbunden ist, zu vermeiden.

So funktioniert es:
  • Mit Mockery erstellen wir „Stubs“ — Objekte, die sich wie echte verhalten, aber einfach vorher festgelegte Antworten zurückgeben.
  • Die Methode Http::fake() ermöglicht es, Aufrufe externer APIs zu imitieren, sodass die Anwendung denkt, sie habe eine Antwort von einem echten Server erhalten.
  • Über Factory::new() erstellen wir fiktive Modelle für Tests — z.B. Benutzer, Bestellungen oder Beiträge, ohne etwas in der Hauptdatenbank zu speichern.
Das macht die Tests zuverlässig, schnell und reproduzierbar. Und das Wichtigste — sie sind nicht von Internetzugang oder der Verfügbarkeit externer Dienste abhängig.

Testen von Ereignissen und Warteschlangen

Wir überprüfen, dass das System nach bestimmten Aktionen die erforderlichen Ereignisse auslöst und Aufgaben (Jobs) in die Warteschlange zur weiteren Verarbeitung einstellt. Dies ist wichtig für alle Geschäftsprozesse, die im Hintergrund stattfinden – zum Beispiel das Versenden von E-Mails nach der Registrierung. Um diese Aktionen während der Tests nicht tatsächlich auszuführen, verwenden wir Event::fake() – es ermöglicht uns, Ereignisse „abzufangen“ und zu überprüfen, dass sie tatsächlich ausgelöst wurden. In ähnlicher Weise stellen wir mit Queue::assertPushed() sicher, dass die Aufgaben tatsächlich in die Warteschlange gestellt wurden. Dies gibt uns die Gewissheit, dass die Anwendung sich korrekt verhält und auf die Aktionen des Benutzers so reagiert, wie es beabsichtigt ist.

CI für PHP

In Laravel-Projekten verwenden wir GitHub Actions, um den Code automatisch zu überprüfen, jedes Mal, wenn jemand Änderungen vornimmt. Das ermöglicht es, Fehler schnell zu erkennen und sicherzustellen, dass die Anwendung wie gewünscht funktioniert.

Folgendes passiert genau:
  • Zuerst werden automatische Tests über phpunit gestartet. Wir verwenden das Flag --stop-on-failure, um die Überprüfung sofort bei der ersten Fehler zu stoppen — das spart Zeit und zeigt genau, wo das Problem liegt.
  • Dann wird die statische Code-Analyse aktiviert: phpstan (auf dem maximal strengen Level 8) und psalm helfen, potenzielle Bugs und Verstöße gegen architektonische Prinzipien noch vor dem Start der Anwendung zu finden.
  • Außerdem wird die Datei der Abhängigkeiten composer.json überprüft: die Befehle composer validate und composer normalize garantieren, dass die Struktur und das Format dieser Datei korrekt und konsistent sind.
Wenn auch nur einer dieser Schritte fehlschlägt, wird der gesamte Prozess blockiert. Das bedeutet, dass der Code nicht in den Hauptzweig gelangen kann, bis die Fehler behoben sind. Dieser Ansatz hilft dem Team, sicher zu sein: alles, was ins Projekt gelangt, wurde bereits überprüft und ist bereit für den Einsatz.
Frontend-Testing: Vue.js und SPA)

Frontend-Testing (Vue.js und SPA)

Das Frontend bei Webdelo ist ein wichtiger Teil der Systemarbeit. Hier werden Formulare verarbeitet, Daten mit dem Server ausgetauscht, die Zustände der Benutzeroberfläche verfolgt und auf Benutzeraktionen reagiert. Wir überprüfen jedes Detail sorgfältig: wie einzelne Komponenten funktionieren – zum Beispiel Schaltflächen oder Eingabefelder – und wie sich das System in komplexen Situationen verhält – zum Beispiel, wenn der Benutzer den gesamten Bestellprozess durchläuft. Das ermöglicht es uns, sicherzustellen, dass die Benutzeroberfläche stabil funktioniert und das System in jedem Szenario vorhersehbar reagiert.

Komponenten-Unit-Tests

Wir verwenden die Werkzeuge Vitest oder Jest, um die Funktionalität jedes Benutzeroberflächenkomponenten separat zu überprüfen. Das bedeutet, dass wir prüfen, ob der Text korrekt angezeigt wird, wie das Element auf Klicks reagiert, ob die benötigten Klassen aktiviert werden und ob die Anzeigebedingungen greifen. Solche Tests sind nicht mit dem Server oder der Datenbank verbunden — sie überprüfen rein das visuelle und logische Verhalten der Komponente unabhängig von der restlichen Anwendung. Dies ermöglicht es, schnell Fehler in der Anzeige oder Interaktion zu erkennen, ohne Zeit mit einer komplexen Umgebungsanpassung zu verschwenden.

Integrations- und e2e-Tests

Um sicherzustellen, dass der Benutzer den gesamten Weg in der App komfortabel durchlaufen kann, verwenden wir die Tools Cypress und Playwright. Mit ihrer Hilfe werden Szenarien getestet, die im echten Leben stattfinden: Anmelden, Formular absenden, Profil bearbeiten, Links folgen. Solche Tests starten die Benutzeroberfläche im Browser und durchlaufen Schritt für Schritt die Aktionen des Benutzers, als ob ein lebender Mensch vor dem Computer sitzt. Das hilft zu überprüfen, dass alles wie gewünscht funktioniert: Tasten werden gedrückt, Seiten laden, Daten werden gespeichert, Fehler treten nicht auf.

API-Mocks und Zustände

Während des Testens greifen wir nicht auf echte Server oder externe APIs zu. Stattdessen erstellen wir gefälschte Antworten, die wie reale aussehen und vorab festgelegte Daten zurückgeben. Dies wird als Mocking bezeichnet – wir setzen fiktive Antworten für REST- oder gRPC-Anfragen ein. Dieser Ansatz hilft, unabhängig von der Internetverbindung oder anderen Diensten zu sein und ermöglicht es, Tests schnell und stabil durchzuführen. Bei jedem Testlauf erhalten die Tests dieselben Antworten und arbeiten unter vorhersehbaren Bedingungen.

Linter und visuelle Tests

Wir nutzen die Tools eslint und stylelint, um automatisch zu prüfen, ob im Code Syntaxfehler oder Verstöße gegen die Stilvorschriften vorhanden sind. Dies hilft, den Code sauber und einheitlich zu halten. Wenn die Benutzeroberfläche besonders komplex ist oder visuelle Genauigkeit wichtig ist, fügen wir screenshot-Tests hinzu — sie machen Screenshots und vergleichen sie pixelgenau mit der Referenzversion. Wenn sich irgendwo etwas verschoben oder verschwunden ist, zeigt der Test dies sofort an. Dieser Ansatz hilft uns, visuelle Bugs nicht zu übersehen und das Design stabil zu halten.

CI im Frontend

Sobald der Entwickler Änderungen am Projekt überträgt (Code pusht), wird automatisch eine ganze Reihe von Prüfungen gestartet:
  • Zuerst erfolgt der Build des Projekts — um sicherzustellen, dass der gesamte Code ohne Fehler kompiliert wird und alles als eine Einheit funktioniert.
  • Dann wird der Linter ausgeführt — er überprüft, ob im Code syntaktische und stilistische Fehler vorhanden sind.
  • Anschließend werden die Unit-Tests gestartet — sie überprüfen, ob jeder einzelne Teil der Benutzeroberfläche korrekt funktioniert.
  • Falls visuelle Tests im Projekt integriert sind, vergleicht das System auch das Erscheinungsbild der Seiten mit Referenzaufnahmen.
Wenn irgendwo ein Fehler auftritt, wird der Build sofort abgebrochen, und der Code gelangt nicht in den Hauptzweig. Dies ermöglicht es dem Team, Probleme schnell zu finden und zu beheben, bevor sie in die Produktion gelangen.

Schlussfolgerung

Testing bei Webdelo ist ein Teil der Architektur jedes Projekts. Wir legen sofort die Möglichkeit von Überprüfungen fest, automatisieren wiederkehrende Aufgaben und wenden Werkzeuge an, die es ermöglichen, die Qualität in Echtzeit zu sehen.

Ein einheitlicher Ansatz auf allen Ebenen — von Backend über Frontend bis DevOps — hilft uns, stabile Releases zu veröffentlichen, Fehler schneller zu finden und zu beheben sowie das Produkt ohne Risiko für die Produktionsumgebung weiterzuentwickeln. Dies funktioniert dank Disziplin, transparenter Verantwortung und einer gemeinsamen Qualitätssicherungskultur im Team.

Wir betrachten das Ergebnis durch die Linse von Stabilität, Reaktionsgeschwindigkeit und Vorhersehbarkeit der Systemleistung im Betrieb.

Möchten Sie Ihr Projekt besprechen?

Lassen Sie eine Anfrage da - und wir helfen Ihnen, Ihr Unternehmen auf ein neues Level zu bringen!

Projekt starten
Blog

Blog

cookies Wir verwenden Cookies

Wir verwenden Cookies auf unserer Website, um die Nutzung zu analysieren, Inhalte zu personalisieren und die Website zu verbessern. Einige Cookies sind technisch notwendig und können nicht deaktiviert werden. Für alle anderen Cookies benötigen wir Ihre Zustimmung. Sie können Ihre Auswahl jederzeit ändern oder Ihre Einwilligung widerrufen. Weitere Informationen finden Sie in unserer Datenschutzerklärung.

Notwendige Cookies

Manche Cookies sind erforderlich, damit bestimmte Webseiten funktionieren. Aus diesem Grund werden sie ohne Ihre Einwilligung gesetzt.

Analyse-Cookies

Wir nutzen diese Cookies für interne Analysen, um unseren Service für alle Nutzer zu verbessern. Diese Cookies bewerten, wie Sie mit unserer Webseite interagieren. Sie werden nur mit Ihrer Einwilligung gesetzt.

Werbe-Cookies

Diese Cookies können von unseren Werbepartnern über unsere Webseite gesetzt werden. Sie ermöglichen es diesen Unternehmen, ein Profil Ihrer Interessen zu erstellen und Ihnen relevante Anzeigen auf anderen Webseiten anzuzeigen. Sie speichern keine direkt personenbezogenen Daten, basieren jedoch auf der eindeutigen Identifizierung Ihres Browsers und Internetgeräts. Diese Cookies werden nur mit Ihrer Einwilligung gesetzt. Wenn Sie sie nicht zulassen, erhalten Sie weniger zielgerichtete Werbung.