Consumer Driven Contracts – Schnittstellentests für Microservices

Hat man als Softwareingenieur die Aufgabe, zwei Systeme miteinander über eine Schnittstelle zu integrieren, trifft man in der Regel auf folgenden Prozess:

  • Der Fachbereich erstellt eine Schnittstellenspezifikation und überreicht diese an das Team des Systems, das die Schnittstelle zur Verfügung stellt (Schnittstellen-Provider).

  • Der Schnittstellen-Provider implementiert die Schnittstelle zum Beispiel als Webservice.

  • Sobald der Schnittstellen-Provider die Implementierung abgeschlossen hat, beginnt das Team des Systems, das die Schnittstelle nutzt (Schnittstellen-Consumer), mit der Implementierung.

  • In mehreren Teststufen – oft manuell – wird die Integration beider Systeme getestet.

  • Es erfordert viel Disziplin bei allen Beteiligten, die ursprüngliche Schnittstellenspezifikation und den Code konsistent zu halten, sollten während der Tests Schnittstellenänderungen nötig sein.

Es ist offensichtlich, dass dieser Ansatz bei der Anwendung des Microservices-Architekturmusters nicht tragfähig ist. Wird das System in kleine Services aufgeteilt, entsteht eine Vielzahl von Schnittstellen, deren Integration mit dem beschriebenen Ansatz nicht mehr beherrschbar ist. Hinzu kommt, dass eine hohe Testautomatisierung ein entscheidendes Kriterium für das kontinuierliche Software Deployment ist. Diese kann nur erreicht werden, indem die Schnittstellentests automatisiert als Bestandteil der Buildpipeline (Continuous Integration CI/ Continuous Delivery CD) ausgeführt werden. Für die Integration der Schnittstellentests gibt es zwei Ansätze:

Consumer Driven Contract Tests (CDC-Tests)

Die Kernidee hinter CDC ist, dass der Service Consumer die Anforderungen an die API des Service Providers stellt. Jeder Nutzer der API schließt mit dem Service Provider einen Vertrag über seine Anforderungen an die API ab.

Service Provider mit zwei Service Consumern

In dem in der Abbildung dargestellten Fall benötigt Service Consumer A die Attribute x und y einer Ressource, der Service Consumer B die Attribute x und z. Der Service Provider stellt daher eine API mit den Attributen x, y, z bereit.

Für CDCs existieren technische Frameworks, mit denen die Contracts erstellt werden und technisch sichergestellt wird, dass Service Provider und Service Consumer die Vereinbarungen einhalten. Diese Tests sind automatisiert und können in die CI/ CD integriert werden. Dadurch lassen sich die beiden oben vorgestellten Ansätze vereinbaren. Mit geringen Infrastrukturanforderungen gibt die Pipeline schnelles Feedback (Fail Fast) und trotzdem wird die Produktion simuliert und die Kommunikation zwischen den Services getestet. Zwei prominente Vertreter für CDC Frameworks sind Spring Cloud Contract und Pact. Die folgende Groovy-Datei zeigt einen beispielhaften Contract auf Basis von Spring Cloud Contract:

Für die Implementierung wird der Spring Cloud Contract in der einfachsten Variante im Source Code Repository (z.B. git) des Providers verwaltet. Der Ablauf für die Erweiterung eines Contracts zwischen Service Consumer und Service Provider stellt sich dann folgendermaßen dar:

  1. Service Consumer
    Der Consumer cloned sich das Repository des Service Providers und kann sich mit einem build (z.B. in maven) einen lokalen Stub Server erzeugen. Er kann nun in den Offline-Modus wechseln und seine Änderungen lokal entwickeln und testen. Abschließend stellt er einen Merge Request.
  1. Producer Phase
    Akzeptiert der Service Provider die Änderungen, schreibt er die fehlende Implementierung und merged in den master. Die CI/ CD Pipeline lädt die Stubs in eine Artifact Repository (z.B. Nexus).
  1. Service Consumer
    Dieser kann nun wieder in den Online-Modus wechseln, die Stubs aus dem Artifact Repository laden und in der CI/ CD-Pipeline gegen diese testen.
Grafik

Consumer Driven Contracts in der Praxis

Werden CDC-Tests für das Testen von Microservice Schnittstellen in einem agilen Entwicklungsprojekt genutzt, kristallisieren sich Vor- und Nachteile heraus.

Positive Erfahrungen:

  • Es findet Kommunikation zwischen den Teams statt. Da der Service Consumer die Anforderungen an die API stellt, sind diese stets transparent. Für den Service Provider wiederum sind die Anforderungen pro Service Consumer transparent.

  • Business und IT nutzen denselben Vertrag. Technisch ist sichergestellt, dass die Spezifikation (der Contract) und der Code nicht auseinanderlaufen.

  • Das agile Vorgehen wird unterstützt. Werden CDCs konsequent eingesetzt, wird nur das implementiert, was auch angefordert ist.

  • Fail Fast: Sind die CDCs verletzt, kann dies zu einem frühen Zeitpunkt in der CI/ CD-Pipeline geprüft werden.

Negative Erfahrungen:

  • CDC-Tests sind noch relativ unbekannt, was zur Folge hat, dass etablierte Best Practices fehlen. Das kann im Projekt zu erhöhtem Diskussions- und Refactoring-Aufwand führen.

  • Die CDCs sind nicht für den Test von Geschäftslogik gedacht. Deshalb können sie in einem Projekt nicht die automatisierten Integrationstests und Aktezptanztests vor einem produktiven Deployment ersetzen.

  • Beim Einsatz von Spring Cloud Contract ist anzumerken, dass dieses Framework auf das Spring Framework reduziert ist. Benutzen Microservices einen anderen Technologiestack, bringen diese keinen Mehrwert. In diesem Fall ist der Einsatz von Pact zu empfehlen.

  • Fail Fast: Sind die CDCs verletzt, kann dies zu einem frühen Zeitpunkt in der CI/ CD-Pipeline geprüft werden.

Fazit

CDC Tests liefern einen Mehrwert, wenn der Einsatz darauf beschränkt ist, dass Service Consumer und Service Provider ein gemeinsames Verständnis der Anfragen und Antworten einer API gewinnen (Endpoint, Verortung der Attribute). Auf Geschäftslogik in CDC-Tests sollte verzichtet werden.

Jetzt lesen

Blog - Technologie & Innovation

Meet Q_ROOMS – Die App zur schnellen und unkomplizierten Buchung von Meetingräumen
Jetzt lesen

Weitere News

WIR SIND FÜR SIE DA!

Mit Q_PERIOR steht Ihnen ein starker Partner zur Seite.
Wir freuen uns auf Ihre Herausforderung!

7. September 2018|