Kriterienkatalog für die bestmögliche Wahl von Testautomatisierungswerkzeugen

Im ersten Teil der Blogserie haben wir die Herausforderungen bei der Wahl des geeigneten Werkzeugs für die Testautomatisierung skizziert. Im zweiten Teil ging es um die Relevanz und eine mögliche Klassifizierung von Auswahlkriterien der Werkzeuge, die sich zum Teil standardisieren lassen, aber fallweise auch variabel sein müssen. In diesem dritten Artikel stellen wir die Liste der Kriterien, den Kriterienkatalog, dessen Verprobung und die Ergebnisse daraus vor.  

Symbolbild: aufgeschlagenes Buch
Designed by Freepik

Liste der Kriterien

Die folgende Abbildung stellt die finale Liste der Auswahlkriterien dar.  Dabei wurden die variablen Kriterien als „SuT-Kriterien“ gekennzeichnet. Die ermittelten Kriterien können angepasst, erweitert und aktualisiert werden.

Tabellarische Darstellung der Kriterien
Abbildung 1: Liste der Kriterien

Die Standardkriterien sind in vierzehn (14) Oberkriterien unterteilt, wie z.B. in Kompatibilität, Bedienbarkeit, Performance oder Dokumentation. Den Oberkriterien sind Unterkriterien zugeordnet. So hat das Oberkriterium Dokumentation beispielweise drei (3) Unterkriterien.

Kriterienkatalog

Nachdem die Kriterien feststanden, erstellten wir im nächsten Schritt den eigentlichen Kriterienkatalog. Da verschiedene, mehrdimensionale Ziele in die Entscheidungen einfließen, eignete sich dafür ein systematischer Ansatz. Er lässt eine multi-kriteriale Entscheidungsanalyse (auch Multi Criteria Decision Analysis oder MCDA genannt) zu. Eine dieser Anwendungsformen der multi-kriterialen Entscheidungsanalyse ist die sogenannte Nutzwertanalyse (Gansen 2020, S. 5). Die Nutzwertanalyse findet überall dort Anwendung, wo eine Bewertung vorgenommen oder eine Beurteilung getroffen wird, z. B. im Projektmanagement, im Controlling.

Tabellarische Darstellung der Nutzwertanalyse
Abbildung 2: Beispieltabelle Nutzwertanalyse

Anforderungen an den Kriterienkatalog

Für die eigentliche Anfertigung des Kriterienkatalogs definierten wir zunächst die Anforderungen. Sie sind im Folgenden tabellarisch in Form von User Stories zusammengefasst und stellen alle notwendigen Arbeitsschritte dar.

Nr.User Stories
1Als Benutzer möchte ich die Projektstammdaten eingeben, damit ich besser nachvollziehen kann, von wem, wann und für welches Projekt der Katalog erstellt wurde.
2Als Benutzer möchte ich einen neuen Katalog erstellen, um eine neue Nutzwertanalyse durchführen zu können.
3Als Benutzer möchte ich eine Nutzwertanalyse durchführen, um eine objektive Entscheidung treffen zu können
4Als Benutzer möchte ich die Kriterien gerecht und leicht gewichten, um die Relevanz für das Projekt besser steuern zu können.
5Als Benutzer möchte ich einen Überblick über die Bewertungsgrundlage haben, um die Lösungsalternativen besser bewerten zu können.
6Als Benutzer möchte ich einen klaren Überblick über die durchgeführte Nutzwertanalyse haben, damit ich schnell das Werkzeug mit dem höchsten Nutzen finden kann.
7Als Benutzer möchte ich die zuletzt bearbeitete Nutzwertanalyse aufrufen, um sie weiter bearbeiten zu können.
8Als Benutzer möchte ich den Katalog exportieren, damit ich diesen weiterleiten kann.
Tabelle 1: Anforderungen an den Kriterienkatalog

Aufbau des Kriterienkatalogs

Der Kriterienkatalog wurde mit Excel, sowie Visual Basic for Applications (VBA) entwickelt. Das entwickelte Tool wurde in verschiedene Arbeitsmappen unterteilt, die jeweils eine spezifische Aufgabe widerspiegeln.

Die Einstiegsmaske

Beim Öffnen der Datei erscheint ein Dialogfenster (siehe Abbildung 3). Zunächst ist auszuwählen, ob der zuletzt bearbeitete Katalog aufgerufen oder ein neuer Katalog erstellt werden soll. Im Falle eines neuen Katalogs wird dann ein Formular angezeigt, das vom Benutzer ausgefüllt werden muss. Die Eingaben des Benutzers zu den SuT-Kriterien werden dem Katalog als variable Kriterien hinzugefügt (siehe Abbildung 4).

Abbildung einer Maske mit verschiedenen Drop-Down-Feldern
Abbildung 3: Einstiegsmaske des Kriterienkatalogs

Abbildung 4: Angaben der SuT-Kriterien im Katalog

Die Nutzwertanalyse

Die Nutzwertanalyse wird in vier Schritten durchgeführt. Nach der Identifizierung der Kriterien folgt deren Gewichtung. Danach wird die Kriterienerfüllung gemessen und schließlich der Nutzwert jeder Alternative berechnet (Gansen 2020, S. 6). Sind die Bewertungskriterien sachgerecht beurteilt, kann mit Hilfe der Nutzwertanalyse eine objektive, rationale Entscheidung getroffen werden (Kühnapfel 2014, S. 4).

Gewichtung der Kriterien

Nachdem die Kriterien, insbesondere die variablen Kriterien, ausgearbeitet worden sind, ist eine Gewichtung dieser Kriterien vorzunehmen. Entscheidend ist es, die Kriterien entsprechend ihrer Bedeutung für das spezielle Testautomatisierungsprojekt so zu gewichten, damit sie optimal zur Erreichung der Ziele des Projekts beitragen. Die Summe der Gewichtungen von Standardkriterien und variablen Kriterien soll jeweils 100% ergeben. Bei den Standardkriterien werden zuerst die Oberkriterien mit Hilfe der Paarvergleichsmethode gewichtet, in Form einer Matrix zusammengestellt und paarweise miteinander verglichen (Wartzack 2021, S. 315).

Abbildung 5: Paarweiser Vergleich der Oberkriterien für ein Beispielprojekts

Oberkriterien: Sicherheit, Installationsaufwand, Sprachunterstützung

Anschließend wird die Wichtigkeit jedes Unterkriteriums anhand einer Ordinalskala von null bis zwei bestimmt:

0 = „unwichtig“; 1 = „teilweise wichtig“; 2 = „wichtig“

Die vergebenen Punkte werden addiert und mit der entsprechenden Gewichtung des Oberkriteriums multipliziert. Daraus ergibt sich eine proportionale Gewichtung aller Standardkriterien. Entsprechend wird mit den anderen Ober- bzw. Unterkriterien verfahren. Am Ende beträgt die Summe aller Gewichtungen der Standardkriterien am Ende 100%.

Messung der Kriterienerfüllung

Ausgangspunkt ist die Beantwortung der Frage: „In welchem Maße ist das Kriterium bei der zu bewertenden Testautomatisierungswerkzeugen erfüllt?“. Für den Kriterienerfüllungsgrad wird ein 5-stufiges Modell verwendet, dargestellt in Tabelle 2 (Gansen 2020, S. 17).

0Nicht erfüllt.
1Ist unzureichend / kaum erfüllt.
2Ist teilweise erfüllt.
3Ist in gutem Umfang erfüllt.
4Ist in sehr gutem Umfang erfüllt / vollständig erfüllt.
Tabelle 2: Bewertungsschema der Kriterienerfüllung

Wird die Note 4 vergeben, erfüllt das Tool ein Kriterium vollständig. Im Falle der Nichterfüllung wird die Note 0 vergeben. Auf diese Weise werden die entsprechenden Eigenschaften eines Testautomatisierungswerkzeugs zu einer messbaren Größe.

Aggregation der Bewertungen

Liegt der Erfüllungsgrad jedes Kriteriums vor, kann der Nutzwert berechnet werden. Für den Nutzwert gilt folgende Formel:

N i = Nutzwerte der Alternative i

Gj = Gewichtung des Kriterium j

nij = Teilnutzen der Alternative i in Bezug auf das Kriteriums j

Die Teilnutzen werden aufsummiert. Das Ergebnis stellt den tatsächlichen Wert eines Werkzeugs dar. Anhand der ermittelten Nutzwerte lässt sich schließlich eine Rangfolge der betrachteten Alternativen aufstellen und für die Entscheidungsfindung nutzen (Gansen 2020, S. 6). Es lässt sich die Werkzeuglösung wählen, die alle Anforderungen am besten erfüllt und die den größten Nutzwert aufweist.

Es gibt Kriterien, die sich als notwendig herausstellen. Diese werden als Ausschlusskriterien (K.O.-Kriterien) bezeichnet. Wenn ein Ausschlusskriterium (K.O.-Kriterium) nicht erfüllt ist (0), liegt ein Verstoß vor, der zum sofortigen Ausschluss einer Alternativlösung führt.

Abbildung 6: Bewertung und Auswahl

Navigationsleiste und Export

Die Navigationsleiste gibt dem Benutzer einen Überblick über die Struktur des Katalogs und ermöglicht es, sich mühelose darin zu bewegen.

Screenshot der Navigation
Abbildung 7: Navigationsleiste des Kriterienkatalogs

Der Katalog kann als PDF- oder Excel-Datei exportiert und der Speicherort dafür frei gewählt werden.

Abbildung 8: Ausschnitt der leeren Vorlage des Kriterienkatalogs

Ergebnisse der Verprobung des Kriterienkatalogs

Aus der Verprobung konnten folgende relevante Erkenntnisse gewonnen werden:

  • Das Zielmodell zur Identifizierung der variablen Kriterien war hilfreich, um gemeinsam Ideen für die SuT-Kriterien zu sammeln.
  • Die Anwendung des paarweisen Vergleichs schaffte Klarheit über die wichtigen Faktoren bzw. Oberkriterien. Dank der Darstellung wurde die Vergleichbarkeit hergestellt. So konnten „Bauchentscheidungen“ deutlich reduziert werden.
  • Der Kriterienkatalog zeigte einen systematischen, verständlichen und nachvollziehbaren Weg auf, um sich ein geeignetes Werkzeug empfehlen zu lassen. Außerdem konnte festgestellt werden, wo die Stärken des empfohlenen Testautomatisierungsframeworks liegen. So wurde die Abdeckung der Auswahlkriterien mit höherer Relevanz durch das Framework überprüft. Das verringert den Bedarf an Diskussionen innerhalb des Teams, die die endgültige Entscheidung herauszögern würden.
  • Aufgrund des für die Bewertung verwendeten 5-Stufen-Modells war ein sehr detailliertes Know-how über Testautomatisierungswerkzeuge erforderlich, das in den meisten Fällen nicht vorhanden ist. Daher würden die Mitarbeiterinnen und Mitarbeiter einige Kriterien nach ihrem Empfinden bzw. Gefühl bewerten. Folglich wären die Bewertungen teilweise subjektiv und die gewählte Alternative letztlich nicht die optimale. Um in diesem Fall ein zuverlässigeres Ergebnis zu erhalten, sollte mindestens eine weitere Person mit Testexpertise zu der Bewertung hinzugezogen werden.

Fazit & Ausblick

In der vorliegenden Arbeit wurde ein strukturierter und systematischer Ansatz für den Auswahlprozess untersucht. Anhand dessen kann ein geeignetes GUI-Testautomatisierungswerkzeug ausgewählt werden, das sowohl den Projekt- als auch den Unternehmensanforderungen genügt. Dabei wurde ein entsprechender Kriterienkatalog entwickelt, der vor allem als Basis für die Transparenz und Nachvollziehbarkeit der Entscheidungsfindung dient.

Es ist geplant, den Kriterienkatalog in weiteren Projekten einzusetzen. Die dabei gesammelten Erfahrungen sollen in die nächste Version 2.0 des Kriterienkatalogs einfließen.

Dieser Beitrag wurde fachlich unterstützt von:

Kay Grebenstein

Kay Grebenstein arbeitet als Tester und agiler QA-Coach für die ZEISS Digital Innovation, Dresden. Er hat in den letzten Jahren in Projekten unterschiedlicher fachlicher Domänen (Telekommunikation, Industrie, Versandhandel, Energie, …) Qualität gesichert und Software getestet. Seine Erfahrungen teilt er auf Konferenzen, Meetups und in Veröffentlichungen unterschiedlicher Art.

Alle Beiträge des Autors anzeigen

Tester-Tea-Time (Teil 3): Die ewige Ungeliebte – Dokumentation im Software-Projekt

Das Beitragsformat „Tester-Tea-Time“ greift Themen und Problemstellungen auf, die Testerinnen und Tester tagtäglich und vor allem wiederkehrend beschäftigen. Hier wollen wir solche Phänomene erläutern und Lösungen dafür finden, sowie Diskussionen und neue Denkweisen anregen. Im Testing können wir viel voneinander lernen, indem wir unseren Alltag beobachten!

Moderator: Willkommen zur Tester-Tea-Time! Im Interview mit Testerinnen und Testern der ZEISS Digital Innovation (ZDI) sprechen wir regelmäßig interessante Themen an. Heute geht es um das Thema Dokumentation im Projektalltag. Dazu unterhalten wir uns mit Sandra Wolf (SW), Testerin bei ZDI.

Sandra, warum bezeichnest du die Dokumentation als „ewig Ungeliebte“?

SW: Der Alltag einer Testerin oder eines Testers ist oft stressig und von hohem Zeitdruck geprägt. Wir machen die Erfahrung, dass deshalb für einige Aufgaben keine oder zu wenig Zeit bleibt. Dazu gehört unter anderem die Dokumentation. Sie wird gern vergessen oder aufgeschoben – deshalb der Titel „die ewige Ungeliebte“. Das liegt unter anderem daran, dass es Zeit frisst, etwas adäquat zu dokumentieren. Zeit ist kostbar. In unserer modernen Gesellschaft wird sie daher meist für die kritischsten Aufgaben im Arbeitsalltag verwendet. Wir wollen uns heute damit beschäftigen, was für eine Auswirkung eine gute Dokumentation auf den Alltag der Testerinnen und Tester haben kann und warum wir in Bezug auf deren Wichtigkeit umdenken sollten. Denn eines ist sicher: Sie hat einen festen Platz in unserem Leben als Tester verdient.

Zwei Personen im Interview
Abbildung: Max Wielsch und Sandra Wolf in der virtuellen Tester-Tea-Time im Gespräch.

Moderator: Wo im Projektalltag begegnen die Testerinnen und Tester dem Thema Dokumentation?

SW: Im normalen Alltag wird jede Testerin und jeder Tester damit konfrontiert, Testergebnisse oder Abweichungen dokumentieren zu müssen. Hier ist es vor allem wichtig, alle Informationen zu hinterlegen, die andere Teammitglieder benötigen. Doch was ist mit der Dokumentation zum Zweck der Wissensvermittlung? Gerade bei komplexer Software kann es enorm wichtig sein, gewisse Kniffe oder fachliches Know-how niederzuschreiben. Der Umfang und die Aufmachung richten sich hier natürlich nach dem Projekt selbst. Liegt bereits eine Dokumentation durch die Konzeption durch den Kunden vor? Dann lässt sich darauf aufbauen. Wenn nicht, sollten alle Teammitglieder das Ziel haben, eine solche Dokumentation schrittweise aufzubauen. Viele werden nun denken, dass das viel zu aufwendig ist. Dafür ist im Projektalltag keine Zeit. Wir Testerinnen und Tester sollten jetzt innehalten und überprüfen, wie positiv sich eine gute Dokumentation auf unseren Arbeitsalltag und den Alltag der Kolleginnen und Kollegen auswirken kann.

Moderator: Und was genau sind die positiven Auswirkungen einer adäquaten Dokumentation?

SW: Die Dokumentation ist eine Grundvoraussetzung für das Wissensmanagement, d.h. für die Entwicklung, den Austausch und den Erhalt von Wissen. Durch ein gutes Wissensmanagement kann erreicht werden, dass aufkommende Fragen zuerst in der Dokumentation nachgeschlagen werden. Das spart Meetings, Anrufe und Zeit. An zentraler Stelle finden sich viele wichtige Informationen – die Basis, um selbstständig arbeiten zu können. So entfallen beispielsweise wiederkehrende Fragen durch Teammitglieder und die Einarbeitung neuer Kolleginnen und Kollegen wird vereinfacht. Auch beim Testing bestimmter komplexer Anwendungsbereiche kann eine solche Wissenssammlung unterstützen, um spezielle Tests zu dokumentieren oder fachliches Hintergrundwissen zu vermitteln. Auch der Test selbst kann durch das Nachschlagen dieser Anforderungen und Tipps beschleunigt werden.

Alle beschriebenen Beispiele sparen Zeit, die wir vermeintlich nicht haben, um etwas zu dokumentieren. Natürlich ist der Aufwand zunächst hoch, um ein solche Wissensbasis aufzubauen, aber dadurch entsteht ein wertvolles Instrument, um auf lange Sicht Zeit zu sparen und den Arbeitsalltag und den Testing-Prozess effizienter zu gestalten.

Moderator: Das bedeutet, das es sich auf jeden Fall auszahlt, wenn das Projekt in den Aufbau der Dokumentation Zeit investiert?

SW: Ja, zusammenfassend kann ich sagen, dass sich die Investition von Zeit und Ressourcen in den Aufbau einer Wissensbasis lohnt. Der Gewinn aus dieser Investition ist wiederum Zeit, die im Arbeitsalltag stets knapp bemessen ist. Sie kann für andere Aufgaben genutzt werden. Zur Steigerung der Effizienz ist ein gutes Wissensmanagement für jedes Projekt unerlässlich.

Moderator: Wie kann nun eine Einführung bzw. Umsetzung dieses Wissensmanagements im Projekt aussehen? Dazu fragen wir Max Wielsch (MW), Entwickler bei der ZDI. Max, was kannst du uns zu diesem Thema sagen?

MW: In meinem Projekt gibt es eine sehr umfassende Wiki-Dokumentation in Confluence. Sie wird ergänzt durch eine codebasierte Dokumentation, die in das Wiki eingebunden wird. Diese Wissenssammlung habe ich in Zusammenarbeit mit meinem Team geschaffen. In der Vergangenheit gab es zwar bereits eine Dokumentation, allerdings war sie reduziert auf zwei Word-Dateien und es gab zu diesem Zeitpunkt keine Wissensträger mehr. Da wir eine sehr komplexe Plattform, bestehend aus mehreren Microservices betreuen – vor allem auf technischer Seite – war für uns aber klar, dass eine umfassende Dokumentation einen entscheidenden Mehrwert bringen wird.

Moderator: Wie genau hast du denn diese  Mammutaufgabe gelöst? Kannst du anderen Kolleginnen und Kollegen ein paar Tipps mit auf den Weg geben?

MW: Mein Ziel war es, Struktur in das vorhandene Chaos zu bringen. Natürlich ist das Schaffen einer guten Dokumentation nie ganz abgeschlossen. Es braucht auch im späteren Verlauf eine dauerhafte und adäquate Pflege der Doku, um eine korrekte Wissensvermittlung zu gewährleisten. Am Anfang habe ich mich jedoch erst einmal informiert und dafür entschieden, arc42 als Struktur-Vorlage für das Wiki zu nutzen. Sie wurde für unser Projekt angepasst. Da wir ein komplexes System von Systemen haben, ist die Doku auch entsprechend gegliedert. Einzelne Module bzw. Bausteine können wiederum eine neue Unterstruktur haben. Außerdem haben wir verschiedene Arten von Dokumentationsbereichen: Die Architekturdokumentation, die sowohl eine technische als auch eine fachliche Doku beinhaltet und die Betriebsdokumentation. Diese Bereiche befinden sich alle im Wiki. Zusammenhängende Themen werden untereinander verlinkt, damit ein einfacher Wissensaustausch und -aufbau möglich ist. Auf all diesen Seiten werden beispielsweise Prozesse erklärt, auf fachliche Erläuterungen in Glossareinträgen verwiesen oder Konfigurationen eines Moduls beschrieben. Auch spezielle Filter des Issue-Trackers (Jira) binden wir ein, um relevante Bugs oder kommende Stories auf einen Blick sichtbar zu machen. Kontext ist einfach alles!

Moderator: Das klingt sehr aufwendig, aber interessant. Hat sich die Einführung einer solchen Dokumentation für dich gelohnt?

MW: Auf jeden Fall! Wir gewinnen allein schon dadurch Zeit, wenn wir bei Fragen der Fachbereiche, des Betriebes oder anderen Stakeholdern auf entsprechende Seiten verweisen können. Außerdem ist diese Dokumentationsstruktur das perfekte Werkzeug, um neue Software-Versionen an den Betrieb zu übergeben. Wir haben beispielsweise besondere Felder in unseren Storys und Bugs, die wir dann auf speziellen Release-Wiki-Seiten in Tabellen auflisten können. Wir können verschiedene Aspekte der Änderung darstellen. Einerseits haben wir die Release-Notes für die Kommunikation an Stakeholder, andererseits gibt es bei uns die sogenannten „Ops-Notes“. Mit ihnen können wir gezielte Hinweise zum Betrieb einer neuen Funktion geben. Natürlich sind dort entsprechende Links auf Seiten der Betriebsdokumentation enthalten. Man sieht, Dokumentation zieht sich von der Planung bis zum Betrieb durch. Schlussendlich haben wir immer die Sicherheit, nachweisen zu können, dass Änderungen am Softwarestand vollständig übergeben und der Betrieb alles zur Verfügung gestellt bekommen hat, was er wissen muss.

Moderator: Wow, dieses Beispiel zeigt wirklich sehr gut, welche Vorteile die Dokumentation im Projekt haben kann. Gibt es aus deiner Sicht auch Nachteile, die es zu berücksichtigen gilt?

MW: Ja, die gibt es immer. Eine komplexe Dokumentation ist pflegebedürftig. Sie will aktuell gehalten werden. Alte, obsolete Informationen müssen entfernt werden. Es ist auch nicht immer leicht, die Dokumentationsstrukturen zu bewahren. Für die inhaltliche Pflege muss genau der richtige Detailgrad gefunden werden, damit die wirklich nötigen Informationen da sind und alles, was verzichtbar ist, nicht gepflegt werden muss. Es ist immer eine Kosten-Nutzen-Abwägung zu treffen und diese ist stark vom Projektkontext abhängig. Was die Bewahrung der Struktur angeht: Eigentlich ist das ganze Team verantwortlich für die Dokumentation. Doch wie so oft braucht es manchmal einen Verantwortlichen, der beobachtet, kontrolliert und korrigierend eingreift. Das kann insbesondere bei großen Projekten, beziehungsweise vielen Entwicklerinnen und Entwicklern hilfreich sein, damit eine klare Linie in der Dokumentation zu erkennen ist. Wenn alle Entwicklerinnen und Entwickler die Prinzipien der Doku verinnerlicht haben und diese korrekt anwenden, braucht es das vermutlich weniger. Aber auch das ist eben sehr stark vom Projekt, d. h. der Teamzusammensetzung, den Fähigkeiten und den Spezialgebieten abhängig.

Moderator: Das ist ein gutes Schlusswort. Vielen Dank, Sandra und Max, für diese Einblicke. Zusammenfassend sehen wir, dass sich eine gute Dokumentation für das Projekt auszahlen kann, die Entscheidung für deren Aufbau allerdings von den Rahmenbedingungen im Projekt abhängig ist. Dieses ungeliebte Thema hat mehr Aufmerksamkeit verdient, da es das Potenzial hat, auf Dauer Zeit zu sparen und das Arbeiten im Team effizienter zu gestalten. Denn wie in der ISO-Norm 24765 beschrieben wird, ist die Dokumentation ein Aspekt der Produktqualität und somit auch der Qualität der erstellten Software, was ihre Wichtigkeit unterstreicht.

In den folgenden Beiträgen werden wir weitere Problemstellungen aus dem Alltag von Testerinnen und Testern aufgreifen und besprechen, welche möglichen Lösungsansätze es dafür gibt.

Kommunikation zwischen C# und C++ – Eine Anleitung

Angenommen Sie haben die Anforderung, Ihre in C# geschriebene Anwendung mit einer C++-Anwendung kommunizieren zu lassen, um beispielsweise Sensordaten von einer Hardwarekomponente auszulesen. Dann können Sie für diese Kommunikation aus verschiedenen Möglichkeiten wählen. In diesem Artikel wollen wir uns die Integration eines COM-Servers ansehen. Dazu wird im Folgenden ein C++-basierter COM-Server aus einem C#-Client heraus angesprochen.

Symbolic image: zwei Hände an einem Tablet

Voraussetzungen

Um diesem Tutorial folgen zu können, benötigen Sie folgende Dinge:

  • Visual Studio 2019 oder eine neuere Version
  • Visual Studio Profil .NET Desktopentwicklung
  • Visual Studio Profil Desktopentwicklung mit C++

Die Profile können über den Visual Studio Installer ausgewählt und installiert werden.

Schritt-für-Schritt-Anleitung: Integration von einem C++-COM-Server mit einem C#-Client

Wichtig: Nähere Informationen finden Sie auch in diesem Github Repository.

Zusätzlich erstellen wir einen C++-Server:

Schritt 1: Erstellen Sie ein C++-ATL-Projekt mit Executable Datei (.exe) als Anwendungstyp.

Schritt 2: Bitte löschen Sie das Projekt ComServerPS.

Schritt 3: Mit der rechten Maustaste auf den Server klicken und eine neue Klasse (ComServerMgr) hinzufügen. Das Ergebnis sollte wie im Bild unten aussehen:

Screenshot COM-Server
Abbildung 1: Hinzufügen einer neuen neue Klasse (ComServerMgr)

Schritt 4: Im ComServerMgr.h die AddOne() Methodheader hinzufügen, damit wir diese in die Klasse einfügen können:

public:
	CComServerMgr()
	{
	}

DECLARE_REGISTRY_RESOURCEID(106)


BEGIN_COM_MAP(CComServerMgr)
	COM_INTERFACE_ENTRY(IComServerMgr)
	COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

public:
	STDMETHOD(AddOne)(int value, int* result);


};

OBJECT_ENTRY_AUTO(__uuidof(ComServerMgr), CComServerMgr)

Schritt 5: Im ComServerMgr.cpp die AddMethod() hinzufügen. Über jene wollen wir später den gegebenen Wert um eins hochzählen:

STDMETHODIMP CComServerMgr::AddOne(int value, int* result)
{
	int res = value + 1;
	if (result != nullptr)
	{
		*result = res;
		return S_OK;
	}

	return S_OK;
}

Schritt 6: In ComServer.idl die AddMethod() ebenfalls hinzufügen und sie somit bekannt machen:

Screenshot COM-Server
Abbildung 2: AddMethod() im ComServer.idl

Schritt 7: Das Projekt bauen. Anschließend auf der Festplatte in das Verzeichnis gehen, in dem der Quellcode liegt und dort das Unterverzeichnis Build auswählen. Dort sollte nun die ComServer.exe liegen. Nun die Eingabeaufforderung als Administrator öffnen und folgenden Befehl eingeben:

ComServer.exe /Regserver

Bitte beachten Sie, dass ComServer der Name des Projekts ist. Wenn z.B. das Projekt „HelloWorld“ heißt, dann müsstet der Befehl lauten: „HelloWorld.exe /Regserver“.

Jetzt fahren wir mit dem Erstellen des C#-Clients fort.

Der Ablauf ist einfacher, als für den COM-Server:

Schritt 1: Erstellen einer Konsolenanwendung.

Schritt 2: Den COM Verweis hinzufügen.

Screenshot COM-Server
Abbildung 3: COM Verweis hinzufügen

Schritt 3: Nach unten scrollen, bis der ComServerLib Verweis zu sehen ist:

Screenshot COM-Server
Abbildung 4: ComServerLib Verweis

Bitte beachten Sie, dass der Verweis ComServerLib heißt, weil wir das Server-Projekt ComServer genannt haben. Wenn z.B. das Projekt „HelloWorld“ heißt, würde der Verweis HelloWorldLib heißen.

Schritt 4: Folgenden Code hinzufügen, durch den der COM-Server beim Start der Konsolenapplikation instanziiert und anschließend die Zahl 3 übergeben wird.

    class Program
    {
        static void Main(string[] args)
        {
            IComServerMgr mgr = new ComServerMgr();
            var x = mgr.AddOne(3);

            Console.WriteLine("Hello World!");
        }
    }

Schritt 5: Um das besser nachvollziehen zu können, ist es auch möglich, den Code im Debug-Modus und mit einem Breakpoint zu starten. Die Ausführung wird dann an der entsprechenden Stelle stehen bleiben.

Code snippet
Abbildung 5: Code im Debug-Modus und mit einem Breakpoint starten

Zusammenfassung

Zugegeben, das Beispiel war sehr einfach, zeigt aber bereits, wie man eine Verbindung zwischen COM-Servern und C#-Anwendungen herstellen kann. Das ist gerade im Vorfeld von Legacy Anwendungen sehr nützlich, zu denen es leider selten Dokumentation mit einer Erläuterung des Vorgehens gibt.

Für Fragen kontaktieren Sie mich gerne unter liviu.sosu@zeiss.com.
Danke an Florian Seeleitner für seine hilfreiche Unterstützung.

Auswahl von Testautomatisierungswerkzeugen – Kriterien und Methoden

Im ersten Artikel wurden die grundsätzlichen Herausforderungen und Einflussfaktoren bei der Auswahl von Testautomatisierungswerkzeugen, als Ergebnis aus verschiedenen Interviews, vorgestellt. Es wurde aufgezeigt, dass es bereits erste Ansätze von Checklisten, aber noch keine einheitliche Methode zur Auswahl von Testautomatisierungswerkzeugen gibt. Die Aufgabe der Abschlussarbeit war es daher, einen einfachen, zielführenden Ansatz zu finden, der die Suche nach geeigneten Testautomatisierungs-werkzeugen je nach Projekteinsatz anhand eines Kriterienkatalogs unterstützt.

Grundvoraussetzung für die Entwicklung eines Kriterienkataloges ist die Beantwortung der Frage, welche Kriterien bei der Auswahl eines Werkzeugs überhaupt relevant sind. Darauf gehe ich im zweiten Teil der Blogserie ein.

Symbolbild: Junger Mann vor dem Bildschirm, zeigt mit dem Finger auf den Desktop und telefoniert

Relevanz der Auswahlkriterien

Die Frage nach geeigneten Kriterien zur Bestimmung der Qualität von Softwareprodukten und, daraus abgeleitet, von Testautomatisierungswerkzeugen wird in der Literatur ausführlich diskutiert. Die für den Kriterienkatalog ermittelten Kriterien wurden größtenteils auf der Basis von Literaturrecherchen entwickelt. Die verwendeten Literaturquellen stelle ich nachfolgend kurz vor:

Die Auflistung der Softwarequalitätsmerkmale ISO 25010 bietet eine hilfreiche Checkliste, um eine Entscheidung für oder gegen den Test jedes Kriteriums zu treffen. Vergleichbare Auflistungen von Qualitätsmerkmalen finden sich auch an anderer Stelle (Spillner/Linz 2019, S. 27). Die Autoren geben jeweils Hinweise, anhand derer für ein Projekt die Erfüllung der einzelnen Qualitätseigenschaften bestimmt werden kann. Im Bereich der Testautomatisierung finden sich Listen von Kriterien zum Beispiel in Baumgartner et al. 2021, Lemke/Röttger 2021, Knott, 2016. Diese Kriterien beziehen sich unter anderem auf die unterstützten Technologien, die Möglichkeiten der Testfallbeschreibung und Modularisierung, die Zielgruppe, die Integration in die Werkzeuglandschaft und die Kosten. Das Ziel ist hier jedoch lediglich das Identifizieren von relevanten Kriterien, nicht aber deren Bewertung. Zum anderen ergaben sich zusätzliche Kriterien aus den Experteninterviews und der Analyse der Projekte der ZDI.

Die in dieser Arbeit identifizierten Auswahlkriterien kombinieren daher Erkenntnisse und Erfahrungen aus bestehenden Schriften zu den Themen Qualität, Testautomatisierung sowie Erstellung und Prüfung von Anforderungen an Testautomatisierungswerkzeuge zu einem praktisch anwendbaren Ansatz.

Abbildung 1: Quellen des Kriterienkatalogs

Klassifizierung der Kriterien

Bei der Auswahl von Testautomatisierungswerkzeugen wurden Einflussfaktoren wie Erfahrung, Kosten oder Interessengruppen genannt. Die Kosten waren für viele der Schlüsselfaktor. Im Rahmen dieser Arbeit wurde erkannt, dass Kriterien wie Integration oder Compliance zwar je nach Rolle unterschiedlich ausgeprägt sind, aber in der Liste der Kriterien mehr oder weniger Standard sind. Und sie sind unveränderbar, unabhängig davon, welche Anwendung getestet wird. Es gibt jedoch einen kleinen Anteil von Kriterien, der je nach der zu testenden Anwendung variiert. Ein Szenario, um die Problemstellung zu veranschaulichen: In der Medizintechnikbranche wird eine neue, webbasierte Anwendung entwickelt – das Frontend mit Angular 8 und NodeJS und das Backend mit Java Microservices. Das auszuwählende Testautomatisierungswerkzeug muss primär zu den Rahmenbedingungen passen, die durch die zu testende Webanwendung vorgegeben sind. Bevor ein Automatisierungswerkzeug zum Einsatz kommen kann, müssen die Schnittstellentechnologien der Anwendung überprüft werden. In der Praxis verfügen Testautomatisierungswerkzeuge über spezifische Eigenschaften und werden daher für unterschiedliche Technologien verwendet. Einige sind eher auf Web-Tests spezialisiert, während andere mehr im Bereich der Desktop-Tests angesiedelt sind. Ob Webanwendung oder mobile Anwendung – es bestehen immer also auch bestimmte Erwartungen an das Testautomatisierungswerkzeug. Daher ist der kritischste Faktor das Testobjekt bzw. das System under Test (SuT). Es bildet die Basis, auf der die Werkzeugauswahl getroffen wird (Baumgartner et al. 2021, S. 45). Zusammenfassend lassen sich die Kriterien in zwei Arten unterteilen: in den Standard- und in den variablen Anteil.

Abbildung 2: Die zwei Arten von Kriterien

Die Standardkriterien hängen nicht von dem Testobjekt ab. In Anlehnung an die Qualitätskriterien wurden diese Kriterien in vier Kategorien gruppiert: Features, System, Benutzbarkeit und anbieterbezogene Kriterien. Im Unterschied dazu hängen die variablen Kriterien von dem zu testenden System ab. Zu den variablen Kriterien gehören beispielsweise die unterstützten Applikationstypen, Betriebssysteme, Schnittstellentechnologien, Browser und Geräte.

Strategie der Variablenauswahl

Variablenauswahl bedeutet, aus einer Anzahl von Variablen diejenigen auszuwählen, die in die Liste der Kriterien aufgenommen werden sollen. Zur Unterstützung der Auswahl variabler Kriterien wurde im Rahmen meiner Arbeit ein Zielmodell mit eine AND/OR-Zerlegung auf der Grundlage von GORE (Goal Oriented Requirements Engineering) und den Arbeiten von Lapouchnian (2005) und Liaskos et al. (2010) eingeführt. Es hatte sich als wirksam erwiesen, Alternativen oder Variabilitäten genau zu erfassen (Mylopoulos/Yu 1994, S. 159-168), um alternative Designs während des Analyseprozesses zu evaluieren (Mylopoulos et al. 2001, S. 92-96). Die Ziele und Anforderungen werden über AND/OR-Zerlegungen verknüpft. Durch die AND-Zerlegung wird ausgedrückt, dass die Erfüllung der jeweiligen notwendig ist. Bei einer OR-Verknüpfung bedeutet dies, dass ist die Erfüllung eines dieser Ziele oder Anforderungen ausreichend. Dadurch werden die ersten Erwartungen an das Werkzeug explizit formuliert und irrelevante Anforderungen vermieden.

Abbildung 3: Vereinfachtes Zielmodell für ein Beispielprojekt XY 

Vorgehensweise bei der Werkzeugauswahl

Ausgehend von den identifizierten Kriterienarten und Spillner et al. (2011) wird in dieser Arbeit eine strukturierte Vorgehensweise für die Auswahl des passenden Testautomatisierungswerkzeugs entworfen. Die neue Vorgehensweise gliedert sich in fünf Schritte:

  1. Erarbeitung der Projektanforderungen
  2. Identifikation der variablen Kriterien mit Hilfe des AND/OR-Zielmodells
  3. Gewichtung der Kategorien und Kriterien
  4. Evaluierung der verschiedenen Werkzeuglösungen
  5. Bewertung und Auswahl

Der nächste Blogartikel geht darauf ein, wie der Kriterienkatalog nach der beschriebenen Vorgehensweise aufgebaut wurde. Außerdem werden wir zeigen, wie die variablen Kriterien in den Katalog aufgenommen wurden, und die Ergebnisse der Verprobung des Kriterienkatalogs vorstellen.

Dieser Beitrag wurde fachlich unterstützt von:

Kay Grebenstein

Kay Grebenstein arbeitet als Tester und agiler QA-Coach für die ZEISS Digital Innovation, Dresden. Er hat in den letzten Jahren in Projekten unterschiedlicher fachlicher Domänen (Telekommunikation, Industrie, Versandhandel, Energie, …) Qualität gesichert und Software getestet. Seine Erfahrungen teilt er auf Konferenzen, Meetups und in Veröffentlichungen unterschiedlicher Art.

Alle Beiträge des Autors anzeigen

Testautomatisierung in Angular-Webprojekten – Was kommt nach Protractor?

Der König ist tot, es lebe der König! Aber welcher? Nachdem das Team von Angular im April angekündigt hat, die Entwicklung seines e2e-Testing-Frameworks Protractor Ende 2022 einzustellen, stellt sich für viele Entwicklerinnen und Entwickler nun die Frage, wie es weiter geht. Welches Tool zur Testautomatisierung sollte man verwenden? Der Markt hält hierfür zahlreiche Alternativen bereit, von denen einige in diesem Beitrag beleuchtet werden sollen.

Symbolic picture: A woman is sitting at a desk with a laptop, tablet and smartphone. The user interfaces show the same dashboards.

Die Testkandidaten

Cypress

Bei Cypress handelt es sich wohl um den bekanntesten Kandidaten im Testfeld. Laut einer Umfrage in der Angular Community vom Januar 2021 handelt es sich mit über 60% der Stimmen um das am weitesten verbreitete Tool für automatisierte UI-Tests. Das erste Stable-Release erschien bereits 2017, gegenwärtig befindet sich die Anwendung in Version 10. Cypress beschreibt sich selbst als schnell, einfach und verlässlich und setzt dabei auf ein eigenes Ökosystem an Tools, das im Gegensatz zu Protractor unabhängig von Selenium und WebDriver ist. Unterstützt werden derzeit Chrome, Firefox und Edge, jedoch (noch) nicht Safari. Die Möglichkeit, die Tests gegen verschiedene Browser-Versionen auszuführen, kann durch die Anbindung von BrowserStack oder durch das Austauschen der Binaries für die lokale Ausführung erreicht werden.

ProContra
+ schnell
+ stabil
+ große Community
+ umfangreiche, verständliche Dokumentation
–        Noch kein Support für Safari
Tabelle 1: Vor- und Nachteile des Tools Cypress

Playwright

Das seit 2020 von Microsoft entwickelte Playwright stellt den jüngsten Kandidaten im Feld der Automatisierungstools dar. Laut eigener Beschreibung soll die Bibliothek aktuell, schnell, zuverlässig und leistungsfähig sein, um gängige Probleme des UI-Testens wie Flakiness und langsame Ausführungsgeschwindigkeiten zu beseitigen. Mit dieser Zielsetzung im Hintergrund verwundert es nicht, dass Playwright im Gegensatz zu den anderen Testing-Tools nicht auf Selenium Webdriver aufsetzt, sondern über eine eigene Implementierung zur Browser-Steuerung verfügt. Unterstützt werden dabei die aktuellen Browser Engines von Chromium, Firefox und WebKit, jeweils auf Windows, Linux und MacOS. Ältere Versionen können unter Verwendung älterer Playwright-Versionen eingebunden werden, seit Kurzem können auch generische Chromium-Builds (Edge und Chrome) verwendet werden. Support für Mobilgeräte ist aktuell nur per Emulation bestimmter Gerätekonfigurationen wie Auflösung und User-Agent möglich, ein Testen auf echten Geräten ist derzeit nicht möglich.

Das Feature Set umfasst neben Standardoperationen auch Funktionen, die in anderen Frameworks fehlen oder nur per Workaround realisiert werden können. So stehen neben Clicks, Scrolling, Selections usw. auch Drag-and-Drop, Interaktionen im Shadow-Dom und Synchronisierung mit Animationen zur Verfügung.

Im Hinblick auf Performance und Ausführungsgeschwindigkeit verhält sich Playwright wesentlich schneller als Protractor und andere seleniumbasierte Testframeworks. In unseren Tests konnten wir auch bei mehreren Testinstanzen im Parallelbetrieb keine Probleme in Hinblick auf Flakiness oder unerwartete Abbrüche feststellen. Abschließend lässt sich sagen, dass Microsoft mit Playwright ein modernes und auf die Anforderungen modernen UI-Testings ausgerichtetes Framework vorgelegt hat, das trotz seiner kurzen Zeit am Markt bereits viele Fürsprecher gewonnen hat und wohl auch in Zukunft noch an Bedeutung gewinnen wird.

ProContra
+ schnell
+ stabil
+ großes Featureset
–        Aktuell nur eingeschränkter Support für BrowserStack
–        Kein Support für echte Mobilgeräte
Tabelle 2: Vor- und Nachteile des Tools Playwright

Webdriver.io

Webdriver.io ist mit über sieben Jahren am Markt eines der langlebigsten Automatisierungstools im Testfeld. Die Macher beschreiben das Design ihres Testframeworks als erweiterbar, kompatibel und reich an Features, was sich bei genauer Begutachtung auch bewahrheitet:

Bei Webdriver.io handelt es sich um ein Selenium-basiertes Testframework, welches die darauf beruhende WebDriver API des W3C implementiert. Dadurch wird die Kompatibilität mit allen modernen Browsern (und IE) gewährleistet, die eine eigene Treiberimplementierung bereitstellen. Darüber hinaus wird auch das Testen von Webanwendungen auf mobilen Geräten sowie nativen Apps ermöglicht.

Im tagtäglichen Einsatz zeigen sich weitere Stärken des Frameworks: Ein großer Fundus an Hilfsmethoden und syntactic sugar macht das Formulieren von Testschritten und Erwartungen deutlich einfacher und lesbarer, als man es von Protractor gewöhnt war. Hervorzuheben sind dabei u. a. der Zugriff auf ShadowRoot-Komponenten via shadow$, die vielseitigen Einstellungsmöglichkeiten der Konfiguration (u. a. automatische Testwiederholungen im Fehlerfall) und das Warten auf erscheinende bzw. verschwindende DOM-Elemente. Sollte dennoch mal eine Funktion nicht verfügbar sein, lässt sich diese als custom command implementieren und anschließend genauso wie die mitgelieferten Funktionen verwenden.

Bei aller Lobpreisung gibt es dennoch einen Wermutstropfen: Im Vergleich zu anderen Frameworks ist die Testausführung aufgrund der Selenium-basierten Implementierung recht langsam, jedoch kann die Ausführung auch parallelisiert werden.

ProContra
+ Vielseitige Kompatibilität
+ Ausgezeichnete Dokumentation
+ Zahlreiche Hilfsmethoden und syntactic sugar
–        Testausführung langsamer als in andere Frameworks
Tabelle 3: Vor- und Nachteile des Tools Webdriver.io

TestCafé

Bei TestCafé handelt es sich um einen weniger verbreiteten Kandidaten im Testfeld. Die bereits erwähnte Umfrage in der Angular Community ergab einen Nutzungsanteil von unter 1%. Das erste Stable-Release erschien 2018, gegenwärtig befindet sich die Anwendung in Version 1.19. Das Versprechen eines einfachen Setups und die Unabhängigkeit von WebDriver war für uns ein Grund, etwas genauer unter die Haube zu schauen. Stattdessen verwendet TestCafé einen umgeschriebenen URL-Proxy namens Hammerhead, der Befehle mithilfe der DOM-API emuliert und JavaScript in den Browser injiziert.

Unterstützt werden derzeit alle gängigen Browser und die mobilen Versionen von Chrome und Safari. Hervorzuheben ist dabei die Möglichkeit, Tests auf echten Mobilgeräten im gleichen Netzwerk auszuführen zu können. Die Testausführung mit BrowserStack ist ebenfalls möglich. Zu erwähnen ist an dieser Stelle auch, dass zusätzlich eine dezidierte Entwicklungsumgebung (TestCafé Studio) existiert, in der es auch möglich ist, mit wenig Programmierkenntnis Testfälle zu erstellen und aufzunehmen.

ProContra
+ schnell
+ Vielseitige Kompatibilität (auch für mobile Browser und Endgeräte)
+ großes Featureset
–        Geringe Verbreitung
–        Testrecorder-Tool nur kostenpflichtig
Tabelle 4: Vor- und Nachteile des Tools TestCafe

Gegenüberstellung

Bei der Wahl eines Testframeworks ist es zunächst wichtig, die eigenen Projektanforderungen zu kennen. Hierbei können folgende Fragestellungen nützlich sein:

  • Welche Browser sollen unterstützt werden?
  • Sollen verschiedene Browserversionen getestet werden?
  • Ist Unterstützung für mobile Geräte erforderlich?
  • Können die Kernfunktionen der Anwendung mittels des Frameworks getestet werden?

Die folgende Tabelle kann bei der Orientierung der Wahl eines Testframeworks helfen.

KriteriumCypressPlaywrightWebdriver.ioTestCafé
Browser-Support (und Versionen)o++ ++ +
Mobile Support+ ++ + ++ +
Funktionsumfang+ + ++ ++
Testgeschwindigkeit+ + o+
Migration von Protractoroo+ +
Zukunftssicherheit+ ++ + o
Tabelle 5: Vergleich der Test-Tools nach verschiedenen Kriterien

Fazit

Die Landschaft an Testframeworks ist sehr vielseitig und es ist oft nicht einfach, die richtige Entscheidung zu treffen. Für Projekte mit beispielsweise geringen Testanforderungen, das Testen gegen wenige und ausschließlich aktuelle Browser, bei denen eine schnelle Testausführung von Vorteil ist, empfehlen wir die Verwendung von Playwright.

Handelt es sich allerdings um ein Projekt, in dem eine Migration von Protractor durchgeführt werden muss und es wichtig ist, gegen viele Browser, in unterschiedlichen Versionen und auf mobilen Endgeräten zu testen, empfehlen wir Webdriver.io.

Quellen

Dieser Beitrag wurde verfasst von:

Stefan Heinze

Stefan Heinze arbeitet seit 2011 als Software-Entwickler bei der ZEISS Digital Innovation in Dresden. Derzeit beschäftigt er sich mit Angular-Anwendungen und Azure-Backend-Entwicklung im Medizinbereich. Dabei gilt ein erhöhtes Augenmerk auf die Automatisierung von Oberflächentests zur Sicherstellung der Softwarequalität.

Alle Beiträge des Autors anzeigen

Snapshot Testing mit Angular und Storybook

Storybook ist ein komponentengetriebenes Werkzeug für die Erstellung von visuellen Styleguides und zur Demonstration von UI-Komponenten aus React, Angular, Vue sowie Web Components.

Speziell das Snapshot Testing bietet die Möglichkeit, ungewollte Anpassungen des Stylings frühzeitig zu erkennen und zu korrigieren.

Symbolbild: Weibliche Hände, die eine Geste eines Fokusrahmens zeigen, auf blauem Untergrund

Snapshot Testing in Storybook

Snapshot-Tests sind ein sehr nützliches Werkzeug, wenn Sie sicherstellen möchten, dass sich Ihre Benutzeroberfläche nicht unerwartet ändert.

Ein typischer Snapshot-Testfall rendert eine UI-Komponente, erstellt einen Snapshot und vergleicht ihn dann mit einer Referenz-Snapshot-Datei, die neben dem Test gespeichert ist. Der Test schlägt fehl, wenn die beiden Snapshots nicht übereinstimmen: Entweder ist die Änderung unerwartet oder der Referenz-Snapshot muss auf die neue Version der UI-Komponente aktualisiert werden.

Storybook bietet mehrere Möglichkeiten, eine Anwendung zu testen. Angefangen mit Chromatic. Diese sogenannte Werkzeugkette setzt allerdings voraus, dass der Quellcode in GitHub versioniert ist und kostet für den professionellen Gebrauch eine monatliche Gebühr.

Eine weitere Möglichkeit ist das schlanke Add-on Storyshots, welches auf dem Testframework “Jest” basiert. Es wird in der Kommandozeile gestartet und listet dort Abweichungen der Komponente zum vorherigen Stand auf. Der Programmierer muss prüfen, ob diese Änderung erwünscht oder ein Fehler ist.

Einrichtung für Angular

Diese Anleitung setzt voraus, dass Storybook bereits für die Angular-Anwendung installiert ist. Eine Setup-Anleitung finden Sie unter diesem Link. Angular bringt von Haus aus die Testumgebung Karma mit. Um die Anwendung auf Jest umzustellen, sind folgende Schritte nötig:

Installation der Jest Dependencies

Zum Installieren von Jest einfach die Zeile „npm install jest jest-preset-angular –save-dev“ in der Kommandozeile ausführen.

Jest Setup-Datei erstellen

Im root-Verzeichnis ihres Angular Projektes die neue Typescript-Datei setupJest.ts mit dem Inhalt import ‚jest-preset-angular‘; erzeugen.

package.json anpassen

Die package.json ihres Angular-Projektes muss um einen Absatz für das Testframework Jest ergänzt werden:

{
 "jest": {
 "preset": "jest-preset-angular",
 "setupFilesAfterEnv": [
 "<rootDir>/setupJest.ts"
 },
}

Außerdem muss die Script-Ausführung für Test angepasst werden. Anstatt “test“: “ngtest“, muss “test“: “jest” verwendet werden.

Karma entfernen (optional)

Zum Entfernen von Karma muss folgende Kommandozeile ausgeführt werden:

npm uninstall karma karma-chrome-launcher karma-coverage-istanbul-reporter karma-jasmine 
karma-jasmine-html-reporter

Im Anschluss sollten auch die Dateien Karma.config.js und test.ts im <root>/src Verzeichnis gelöscht werden und der Abschnitt für Test in der angular.json entfernt werden.

Migration von Jasmine (optional)

Für die Migration nach Jest müssen Anpassungen vorgenommen werden:

• Kommandozeile: npm uninstall @types/jasmine

• jasmine.createSpyObj(’name‘, [‚key‘]) wird zu jest.fn({key: jest.fn()})

• jasmine.createSpy(’name‘) wird zu jest.fn()

• spyOn mit returnValue() muss in jest.spyOn(…).mockReturnValue(…) umgewandelt werden

• spyOn mit callFacke() muss in jest.spyOn(…).mockImplementation(…) umgewandelt werden

• Asymmetric matchers: jasmine.any, jasmine.objectContaining, etc. wird zu expect.any,

expect.objectContaining

Storyshots Dependencies installieren

Nun wird Storyshots installiert. Um Storyshots zu installieren, sollen diese zwei Kommandozeilen ausgeführt werden:

npm i -D @storybook/addon-storyshots
npm i -D @storybook/addon-storyshots-puppeteer puppeteer

Nach der Installation sollten folgende Dependencies in der package.json vorhanden sein (Stand 12.11.2021; wichtig für den Installations-Workaround unter Angular):

"jest": "^27.3.1",
"jest-preset-angular": "^10.0.1",
"@storybook/addon-storyshots": "^6.3.12"
"@storybook/addon-storyshots-puppeteer": "^6.3.12"

Storyshots Installationsdatei erstellen

Nach der Installation von Storyshots muss die Erweiterung noch eingestellt werden. Dafür muss im Verzeichnis <root>/src die Datei Storyshorts.test.js mit folgendem Inhalt erstellt werden:

import initStoryshots from '@storybook/addon-storyshots';
import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer';
import path from 'path';

// Function to customize the snapshot location
const getMatchOptions = ({ context: { fileName } }) => {
 // Generates a custom path based on the file name and the custom directory.
 const snapshotPath = path.join(path.dirname(fileName), 'snapshot-images');
 return { customSnapshotsDir: snapshotPath };
};

initStoryshots({
 // your own configuration
 test: imageSnapshot({
 // invoke the function above here
 getMatchOptions,
 }),
});

tsconfig.json für Storyshots erweitern

Des Weiteren muss noch die tsconfig.json angepasst werden. Dafür muss der compilerOptions Abschnitt in tsconfig.json wie folgt erweitert werden:

"compilerOptions": { 
 "esModuleInterop": true,

Package.json für Storyshots erweitern

Zuletzt muss der in der Package.json enthaltene Abschnitt für Jest umkonfiguriert werden:

"jest": {
 "preset": "jest-preset-angular",
 "setupFilesAfterEnv": [
 "<rootDir>/setupJest.ts"
 ],
 "transformIgnorePatterns": [
 "<rootDir>/node_modules/(?!(@storybook/addon-docs))"
 ],
 "moduleNameMapper": {
 "jest-preset-angular/build/setup-jest": "jest-preset-angular/setup-jest",
 "jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer": "jest-presetangular/build/serializers/no-ng-attributes",
 "jest-preset-angular/build/AngularSnapshotSerializer": "jest-presetangular/build/serializers/ng-snapshot",
 "jest-preset-angular/build/HTMLCommentSerializer": "jest-presetangular/build/serializers/html-comment"
 }
},

Diese Anpassungen sind speziell für die gewählte Version, da die Ordnerstruktur in Jest umgemappt werden muss. Das kann sich in späteren Versionen von Storyshorts wieder ändern.

Test der Komponenten

Für den Test gibt es eine Beispielanwendung, welche aus vier Einzelkomponenten besteht. Die erste Komponente zeigt die Uhrzeit inklusive Datum und Wochentag an. Die zweite Komponente gibt das aktuelle Wetter in Schaubild mit Gradzahl, Tageshöchst- und Tagestiefsttemperatur an. Über eine weitere Komponente werden die Straßenbahnabfahrten am Beispiel Dresden Striesen abgebildet. Zuletzt gibt es noch eine Komponente, welche 3 Aktienkurse anzeigt mitsamt Graph und Indikatoren.

Abbildung 1: Storybook für eine Anwendung bestehend aus vier Komponenten

Bespielhaft sieht der Quellcode der Uhrzeitkomponente wie folgt aus:

export default {
 title: 'WidgetMonitor/Clock',
 component: ClockComponent,
 timeIsRunning: false,
} as Meta;

export const Morning = () => {
 return({
 props: {
 timeIsRunning: false,
 time: new Date(2021, 10, 9, 9, 9, 9, 9)
 },
 parameter: {
 time: new Date(2021, 10, 9, 9, 9, 9, 9)
 }
 })
}

export const Afternoon = () => {
 return({
 props: {
 timeIsRunning: false,
 time: new Date(2021, 10, 9, 15, 15, 15, 15)
 }
 })
}

const Template: Story<ClockComponent> = (args: ClockComponent) => ({
 props: args
});

export const Running = Template.bind({});

Running.args = {
 timeIsRunning: true,
};

Running.parameters = {
 storyshots: { disable: true }
};

Diese beinhaltet drei Zustände, von denen die ersten beiden jeweils statische Zeitpunkte sind. Der dritte Zustand “Running” zeigt die aktuelle Uhrzeit an, d. h. er ist nicht statisch.

Voraussetzung für Snapshot Tests unter Storybook

Es ist wichtig, dass wir unter Storybook einen statischen Zustand haben, damit die Anwendung getestet werden kann. Im Uhrzeitbespiel ist der Zustand „Running“ nicht statisch. Diesen kann man überspringen, indem man den parameter storyshots: { disable: true } hinzufügt (siehe Quellcode weiter oben).

Test starten

Mit der Kommandozeile npm test, wird der Test in der Kommandozeile im Angular-Projektverzeichnis gestartet. Der initiale Snapshot Test erstellt nun ein Snapshot Image von jedem Komponentenzustand.

Abbildung 2: Test starten in Storybook

Zum Aufzeigen von Fehlern wird nun beispielhaft die Schrift der Uhrzeit in der Clock-Komponente sowohl kleiner als auch in Rot im SCSS umgestellt und der Test erneut gestartet.

Abbildung 3: Aufzeigen von Fehlern in Storybook

Das Ergebnis des Snapshot Tests zeigt, dass die beiden aktiven Zustände der Clock-Komponente umgefallen sind und auf ein Diff Image verwiesen wird. Dieses sieht wie folgt aus:

Abbildung 4: Ergebnis des Snapshot Tests

Links ist der ursprüngliche Zustand zu sehen, rechts der Zustand nach der Änderung. In der Mitte sieht man den Zustand, wie sich beide überschneiden. Nun gibt es die Möglichkeit, diesen Zustand entweder zu übernehmen oder den Test – nach Anpassung der Anwendung – erneut auszuführen.

Das Übernehmen des Zustands wird mittels der Kommandozeile npm test — -u erzwungen. Damit werden die Differenzbilder gelöscht und ein neuer Snapshot des Zustands der Komponente erstellt. Das erneute Aufrufen der Kommandozeile npm test sollte nun ohne Fehler durchlaufen.

Fazit

Einen Zustand für Storybook zu pflegen, bedeutet auch immer einen Mehraufwand im Projekt. Wer sich vor diesem Aufwand nicht scheut, hat mittels Jest und der Erweiterung StoryShots die Möglichkeit, einen bestimmten Zustand gekapselt prüfen zu können. Dies ist besonders hilfreich zur Früherkennung von Styling Bugs, welche schwierig in Unit- und Ende-Zu-Ende-Tests gefunden werden können und meist erst beim manuellen Testen auffallen.

Video-Tutorial: So nutzen Teams das QA Navigation Board

Das QA Navigation Board versetzt Teams in die Lage, für jedes Softwareprojekt zielführend und effizient über die Aspekte der Qualitätssicherung, deren Priorität und Ausprägung in der Durchführung zu entscheiden. Zur Erläuterung seiner Funktionsweise haben wir ein kurzes Video-Tutorial erstellt.

Abbildung 1: QA Navigation Board bei der praktischen Anwendung

Funktionsweise des QA Navigation Board

Jedes Softwareprojekt zeichnet sich durch individuelle Schwerpunkte aus. Daraus ergeben sich in der Folge ebenso spezielle Qualitätsanforderungen. Für die Prüfung dieser Qualitätsanforderungen müssen daher – je nach Themenstellung – die passenden Maßnahmen festgelegt werden. Um hier nicht zu vergessen, die Methoden richtig zu gewichten und die Abfolgen sinnvoll zu planen, haben wir das QA Navigation Board entwickelt: Ein Hilfsmittel, das es Teams ermöglicht, das Testen von Softwareprojekten optimal zu organisieren. Es berücksichtigt die Fragen: Was ist zu testen, wie, in welchem Umfang, wo und wann.

Video-Tutorial

Damit die Nutzung des Boards auf Anhieb gelingt, ist eine Einführung in das Tool hilfreich. In einem ergänzenden Video-Tutorial erklären wir deshalb dessen Funktionsweise. Wie ist es aufgebaut? Welche Schritte der Testplanung erfolgen idealerweise nacheinander und warum? So gelingt der Start Schritt für Schritt bestmöglich.

Erfahrungen mit dem QA Navigation Board

Das QA Navigation Board wird bereits in zahlreichen Projekten konsequent und mit großem Erfolg eingesetzt. Teams, die mit dem Board arbeiten, bestätigen: Es nimmt alle Teammitglieder und ihre jeweiligen Kompetenzen mit. Es sorgt dafür, dass kein Aspekt der Software vergessen und richtig, dem Zweck entsprechend, gezielt qualitätsgesichert wird. Das Arbeiten mit dem QA Navigation Board sorgt so für Übersichtlichkeit, gibt eine klare Orientierung und wird gemeinsam vom gesamten Team in einem Workshop erstellt.  

Einführungsworkshop

Für Teams, die das Board in ihre Prozesse einbinden wollen, gibt es selbstverständlich nach wie vor unseren detaillierten Ablaufplan für einen Workshop zur Einführung des QA Navigation Boards. Wie es im Detail ausgefüllt wird und was sich hinter den einzelnen Punkten verbirgt, lässt sich darüber hinaus jederzeit hier nachlesen und immer wieder zur Hand nehmen.

Geht es um das Erkennen typischer QA-Problemfälle, deren Auswirkungen und Beseitigung, dient das Board als Werkzeug für die „Anamnese der QA-Strategie für agile Teams“ – Ein Vorgehensbeschreibung ist hier zu finden.

Data Science Buzzwords und was sie bedeuten

Das Journal “Harvard Business Review” kürte vor ein paar Jahren “Data Scientist“ zum “Sexiest Job” des 21. Jahrhunderts [1], nicht zuletzt, weil datengetriebene Unternehmen wie Google, Amazon und Facebook enorme Gewinne verzeichnen können. Seitdem basteln moderne Unternehmen an ihrer Daten-Infrastruktur, wodurch Begriffe wie Machine Learning, Data Science und Data Mining in aller Munde sind. Aber was genau steckt hinter diesen ganzen Begriffen? Was haben sie gemeinsam, was unterscheidet sie? Und was macht eigentlich ein Data Scientist? Diese Fragen sollen nachfolgend beantwortet werden.

Data Scientist vor drei Bildschirmen mit verschiedenen Graphen

Buzzwords

Zunächst wollen wir versuchen, die Bedeutung einiger Schlagworte zu klären. Doch vorher sei zu beachten: Da das Themengebiet noch im Entstehen ist und sich schnell weiterentwickelt, sind viele Begriffe noch im Fluss und werden manchmal unterschiedlich verwendet. Die Begriffe werden wir am Beispiel eines fiktiven, global agierenden Logistikunternehmens „OrderNow“ veranschaulichen.

Data Science versucht, Wissen aus Daten zu generieren. Das Vorgehen von Data Scientists ist vergleichbar mit dem von Naturwissenschaftlern, die aus vielen Messdaten allgemeine Erkenntnisse ableiten. Dazu benutzen sie verschiedene Algorithmen, die im akademischen Kontext entwickelt und im industriellen Umfeld angewendet werden.
Ein wichtiges Beispiel hierzu ist die Vorhersage von Bestellungen. Aus der Buchhaltung von OrderNow weiß man, zu welchem Zeitpunkt welche Kunden was und in welcher Stückzahl bestellt haben. Ein Algorithmus eines Data Scientists analysiert diese Bestelldaten statistisch und kann dann vorhersagen, wann in der Zukunft welche Produkte in welchen Stückzahlen nachgefragt werden. Darauf vorbereitet kann OrderNow schon frühzeitig bei seinen Lieferanten bestellen und dann die eigenen Kunden schneller beliefern.

Big Data sind Datenmengen, welche zu groß, zu komplex, zu schnelllebig oder zu schwach strukturiert sind, um sie mit manuellen, herkömmlichen Methoden der Datenverarbeitung auszuwerten.
In unserem Beispiel könnten das die ständig wachsenden Bestelldaten der Vergangenheit sein.

Data Lake ist ein System von Daten, die unstrukturiert im Rohdatenformat gespeichert sind. Es werden dabei mehr Daten gespeichert als akut benötigt. In anderen Worten: ein Data Lake ist ein „Big Data“-Repository.
OrderNow besteht aus vielen Subunternehmen mit gewachsenen Strukturen. Die Bestelldaten sind manchmal Excel-Dateien und manchmal Einträge in SQL-Datenbanken.

Machine-Learning-Algorithmen lernen, ähnlich wie der Mensch, anhand von Beispielen Muster in Daten zu erkennen. Nach Abschluss der Lernphase können diese Muster in neuen Daten erkannt werden. Man spricht dabei auch von der künstlichen Generierung von Wissen aus Erfahrung. Bei der Anwendung dieser Algorithmen werden oft neuronale Netze verwendet.
Bei OrderNow wird diese Technik in der Kunden-App eingesetzt. Der Nutzer kann Objekte fotografieren, die App erkennt, um welches Produkt es sich handelt und es kann direkt bestellt werden. Ein Machine-Learning-Algorithmus hat dazu aus unzähligen kategorisierten Bilddateien gelernt, wie ein bestimmtes Produkt aussieht und kann dieses in neuen Bildern wiedererkennen.  

Deep Learning ist eine spezielleMethode des Machine Learning, welche neuronale Netze mit vielen Zwischenschichten (Hidden Layers) benutzt.

Data Mining ist der Versuch, neue Querverbindungen und Trends in großen Datenbeständen zu finden. Dabei werden statistische Methoden benutzt. Aufgrund der verschiedenen Herangehensweise ist Data Mining komplementär zu Machine Learning.
Bei OrderNow nutzt man Data Mining, um seinen Kunden Produkte zu empfehlen.

Was macht ein Data Scientist?

Unter diesen Schlagworten kann Data Science als der umfassendste Begriff gesehen werden. Ein Data Scientist nutzt unter anderem Methoden wie Machine Learning oder Data Mining, um aus Daten Wissen zu generieren.

Abbildung 1: Einen Data Scientist zeichnen Wissen und Fertigkeiten aus den Bereichen Informatik, Mathematik und Projektmanagement aus.

Dazu bedarf es verschiedener Fähigkeiten, die in Abbildung 1 zusammengefasst sind. Data Scientists programmieren häufig in den Sprachen Python oder R, kennen sich mit Datenbanken aus und wissen, wie man effizient Daten verarbeitet. Sie haben ein gutes Verständnis von Mathematik und Statistik. Der wissenschaftliche Teil ihrer Arbeit besteht nicht nur im Vorgehen beim Generieren von Wissen, sondern auch darin, dass sie die Fragestellungen, die mit der Datenbasis beantwortet werden sollen, selbst formulieren. Data Scientists müssen sich außerdem mit Projektmanagement auskennen. Sie arbeiten im Team mit Experten aus der Daten-Domäne, müssen die Ergebnisse gut im Unternehmen kommunizieren und schließlich mithelfen, ihre Erkenntnisse in die Praxis zu überführen, um Mehrwerte zu schaffen.

Mit Daten Mehrwerte schaffen

Was können solche Mehrwerte sein? Erkenntnisse für Entscheidungen des Managements einerseits, Optimierungen von bestehenden Produkten anderseits – das eigentliche Ziel ist jedoch häufig die Entwicklung neuer Produkte. Damit das gelingt, müssen Softwareentwickler und Data Scientists eng zusammenarbeiten. Die Zukunft wird zeigen, wie gut es uns gelingt, dies in die Tat umzusetzen.

References

[1] Davenport and Patil, Havard Business Review, October 2012

YARP – Ein schneller und zuverlässiger Reverse Proxy

Möglichkeiten der .NET-basierten Open-Source-Lösung von Microsoft

Routing, Load Balancing, Authentifizierung, Autorisierung und Ausfallsicherheit sind wichtige Themen in vielen Webprojekten. Microsoft hat eine große Anzahl von Teams, welche einen Reverse Proxy für ihre Dienste selbst schreiben oder nach Lösungen suchen, um die genannten Aufgaben abzubilden. Dies war ein guter Anlass, die unterschiedlichen Anforderungen zusammenzubringen, um an einer gemeinsamen Lösung zu arbeiten. YARP wurde ins Leben gerufen – das Microsoft Open-Source-Projekt für einen Reverse Proxy in .NET.

Vor mehr als einem Jahr hat Microsoft die erste Preview veröffentlicht. Seitdem gab es viele Verbesserungen und YARP ist zusammen mit dem neuen .NET 6 am 9. November 2021 in der Version 1.0 erschienen.

In diesem Artikel wollen wir uns YARP etwas genauer anschauen und einen Überblick über die Konfigurationsmöglichkeiten geben, die uns Microsoft an die Hand gibt. Dafür schauen wir uns als Erstes an, was ein Reverse Proxy eigentlich ist und wie sich YARP positioniert. Danach betrachten wir die vielfältigen Konfigurationsmöglichkeiten, um am Ende einen Ausblick zu geben.

YARP ist in C# geschrieben und auf .NET aufgebaut. Es nutzt die Infrastruktur von ASP.NET und .NET. Somit werden .NET Core 3.1 und .NET 5 sowie das schon erwähnte .NET 6 unterstützt. Bei der Verwendung von .NET Core 3.1 stehen allerdings einige Funktionen nicht zur Verfügung, da YARP bei den neueren .NET Versionen auf einige neue Features und Optimierungen zurückgreift.

Tastatur mit Open-Source-Taste

Was ist ein Reverse Proxy

Ein Reverse Proxy ist eine Art Proxy-Server, der typischerweise hinter der Firewall in einem privaten Netzwerk sitzt und Client-Anfragen an Backend Services weiterleitet. Dabei liefert der Reverse Proxy eine zusätzliche Abstraktions- und Steuerungsschicht, um den reibungslosen Fluss des Netzwerkverkehrs zwischen den Clients und Servern zu gewährleisten.

Was ist YARP

Ein klassischer Reverse Proxy arbeitet meist auf der Transportschicht (4. Ebene – TCP/IP) des ISO/OSI Modells und routet die Anfragen immer weiter. Im Vergleich dazu befindet sich YARP auf der 7. Ebene – hier http-Level – und es werden die eingehenden Verbindungen gekappt und neue zum Ziel-Server erstellt. Die eingehenden und ausgehenden Verbindungen sind somit unabhängig. Dadurch ist ein Remapping des URL Space möglich, d. h. es gibt einen Unterschied zwischen den URLs, die von außen sichtbar sind und denen im Backend.

Eine Entlastung der Backend Server ist durch Aufgabenverschiebung in den Reverse Proxy möglich.

Warum YARP?

Die Nutzungsmöglichkeiten von YARP und den vielen anderen (klassischen) Reverse Proxys sind unterschiedlicher Natur. Ein Entwickler im ASP.NET-Umfeld kann leicht die Funktionalität des Reverse Proxys in seiner gewohnten Programmiersprache einrichten, konfigurieren und erweitern. Ebenso kann der Reverse Proxy mit allen Konfigurationen, wie jedes andere Projekt auch, mit der Versionskontrolle versioniert werden. Außerdem ist es Cross-Plattform-fähig, d. h. es läuft sowohl unter Windows als auch Linux und eignet sich somit gut zur Containerisierung.

Funktionen von YARP

Eine der wichtigsten Anforderungen ist die Erweiterbarkeit sowie Anpassbarkeit von YARP. Zur Konfiguration kann jede Quelle, die das IConfiguration Interface abbildet, angebunden werden. Klassischerweise sind das JSON-Konfigurationsdateien. Die Konfiguration wird bei Änderungen ohne Neustart automatisch aktualisiert. Es ist aber auch möglich, die Konfiguration dynamisch über eine API zu steuern oder sogar on demand pro Anfrage.

Anatomie einer Anfrage

Um die Funktionen besser zu verstehen, ist es sinnvoll, sich zuerst einen Überblick über die Pipeline-Architektur von YARP zu verschaffen. Als Erstes landet eine eingehende Anfrage in der Standard ASP .NET Middleware (z. B. TLS Termination, Statische Files, Routing, Authentifizierung und Autorisierung). Anschließend folgen verschiedene Phasen in YARP.

  1. Durchlauf über alle Ziel-Server inkl. Health Check
  2. Session Affinity
  3. Load Balancing
  4. Passive Health Checks
  5. Transformation der Anfrage
  6. Weiterleitung der Anfrage durch eine neue Verbindung an den Ziel-Server

Routen und Cluster

Der Reverse Proxy kann sowohl für Routen als auch für Cluster konfiguriert werden. Die Routenkonfiguration ist eine geordnete Liste von Routentreffern mit den dazugehörigen Konfigurationen. Eine Route wird typischerweise durch drei Bestandteile definiert. Das sind die Routen-ID, Cluster-ID und ein Match-Kriterium. Wenn also eine eingehende Verbindung ankommt, wird diese mit dem Match-Kriterium verglichen. Dabei wird die Liste der Routeneinträge nacheinander abgearbeitet. Wird das Match-Kriterium erfüllt, so wird das Cluster mit der angegebenen ID zur Weiterleitung verwendet. Für eine Route können aber auch CORS, Transformer, Authentifizierung und Autorisierung konfiguriert werden.

In Abbildung 1 ist eine Beispiel-Konfiguration für Routen und Cluster zu sehen.

Im Gegensatz zum „Routes Abschnitt, enthält der Cluster Abschnitt eine ungeordnete Sammlung von benannten Clustern. Ein Cluster enthält in erster Linie eine Sammlung von benannten Zielen und deren Adressen, von denen jedes als fähig angesehen wird, Anfragen für eine bestimmte Route zu bearbeiten. Der Proxy verarbeitet die Anfrage entsprechend der Routen- und Cluster-Konfiguration, um ein Ziel auszuwählen.

{
    "ReverseProxy": {
        "Routes": {
            "minimumroute": {
                "ClusterId": "minimumcluster",
                "Match": {
                    "Path": "{**catch-all}"
                }
            },
            "route2": {
                "ClusterId": "cluster2",
                "Match": {
                    "Path": "/something/{*any}"
                }
            }
        },
        "Clusters": {
            "minimumcluster": {
                "Destinations": {
                    "example.com": {
                        "Address": "http://www.example.com/"
                    }
                }
            },
            "cluster2": {
                "Destinations": {
                    "first_destination": {
                        "Address": "https://contoso.com"
                    },
                    "another_destination": {
                        "Address": "https://bing.com"
                    }
                },
                "LoadBalancingPolicy": "PowerOfTwoChoices"
            }
        }
    }
}

Abbildung 1: Beispiel-Konfiguration mit den grundlegenden Funktionen (Routen, Cluster und Load Balancing)

TLS Termination

Wie schon erwähnt werden die eingehenden Verbindungen gekappt und neue zum Ziel-Server hergestellt. Da TLS Verbindungen teuer sind, kann das für kleine Aufrufe die Geschwindigkeit verbessern. Dies kann vor allem dann sinnvoll sein, wenn der Proxy auf Server weiterleitet, die sich alle im internen Netz befinden und keine gesicherte Verbindung mehr notwendig ist. Folgende Möglichkeiten sind hier vorstellbar:

  • Routing einer eingehenden HTTPS auf HTTP Verbindung
  • Routing einer eingehenden HTTPS/1 auf HTTP/2 Verbindung
  • Routing einer eingehenden HTTP auf HTTPS Verbindung

Session Affinity

Die Session Affinity ist ein Mechanismus zur Bindung (Affinität) einer zusammenhängenden Anforderungssequenz an das Ziel, das die erste Anforderung bearbeitet hat, wenn die Last auf mehrere Ziele verteilt ist.

Es ist in Szenarien nützlich, in denen die meisten Anfragen in einer Sequenz mit denselben Daten arbeiten und die Kosten des Datenzugriffs für verschiedene Ziele, die Anfragen bearbeiten, unterschiedlich sind.

Das häufigste Beispiel ist ein transientes Caching (z. B. In-Memory). Dabei werden während der ersten Anfrage Daten aus einem langsameren persistenten Speicher in einen schnellen lokalen Cache geholt. Bei weiteren Anfragen können diese mit den Daten aus dem Cache bearbeitet werden, wodurch der Durchsatz erhöht wird.

Load Balancing

Wenn für eine Route mehrere gesunde Ziele verfügbar sind, kann einer der folgenden Load Balancing Algorithmen konfiguriert werden:

  • Random
  • Round Robin
  • Least Requests
  • Power of Two Choices
  • First

An dieser Stelle kann auch ein selbst entwickelter Algorithmus verwendet werden.

Health Checks

Der Reverse Proxy kann den Gesundheitszustand jedes Knotens analysieren und den Client-Verkehr zu ungesunden Knoten stoppen, bis sie sich erholen. YARP implementiert diesen Ansatz in Form von aktiven und passiven Prüfungen.

Passiv

YARP kann passiv auf Erfolge und Misserfolge beim Weiterleiten von Client-Anfragen achten. Die Antworten auf die Proxy-Anfragen werden von einer dedizierten Middleware zur passiven Gesundheitsprüfung abgefangen, die sie an eine auf dem Cluster konfigurierte Richtlinie weiterleitet. Die Richtlinie analysiert die Antworten, um festzustellen, ob die Ziele, die sie erzeugt haben, gesund sind oder nicht. Dann berechnet sie neue passive Gesundheitszustände, weist sie den jeweiligen Zielen zu und baut die Sammlung der gesunden Ziele des Clusters neu auf.

Aktiv

YARP kann den Zustand der Ziel-Server auch aktiv überwachen. Dafür werden regelmäßig Anfragen an vordefinierte Zustandsendpunkte gesendet. Diese Analyse wird durch eine für einen Cluster festgelegte Richtlinie zur aktiven Gesundheitsprüfung definiert. Am Ende wird anhand der Richtlinie jedes Ziel als gesund oder ungesund markiert.

Durch die aktiven und passiven Checks werden ungesunde Cluster automatisch geblockt und es können Wartungsarbeiten durchgeführt werden, ohne dass die Anwendung beeinträchtigt wird.

Transformer

Mit Hilfe von Transformern kann der Proxy Teile der Anfrage oder Antwort modifizieren. Dies kann notwendig sein, um z. B. definierte Anforderungen des Ziel-Servers zu erfüllen. Dabei wird das ursprüngliche Anfrage-Objekt nicht verändert, sondern nur die Proxy-Anfrage. Es wird keine Auswertung des Anfrage-Bodys durchgeführt und es erfolgt keine Änderung des Anfrage- und Antwort-Bodys. Allerdings kann dies über eine zusätzliche Middleware erreicht werden – falls notwendig. An dieser Stelle könnte beispielsweise das ebenfalls auf .NET basierende API-Gateway Ocelot seine Stärken ausspielen. Dieses kann Konvertierungen wie XML zu JSON vornehmen oder mehrere Antworten zusammenführen und richtet sich vor allem an .NET-Anwendungen mit einer Microservice- oder serviceorientierten Architektur.

Es gibt einige Transformer, die standardmäßig aktiviert sind. Dazu gehören unter anderem das Protokoll (X-Forwarded-Proto), der angefragte Server (X-Forwarded-Host) und die Ursprungs-IP (X-Forwarded-For).

Der Ursprung der Anfrage ist dementsprechend nach dem Routing des Reverse Proxys im Backend über die hinzugefügten Headerinfos weiterhin bekannt – dies ist nicht bei klassischen Reverse Proxys gegeben.

Authentifizierung und Autorisierung

Vor der Weiterleitung sind eine Authentifizierung und Autorisierung möglich. Dadurch können konsistente Richtlinien über mehrere Services abgebildet werden und müssen somit nicht separat gepflegt werden. Außerdem führt das zu einer Lastreduzierung bei den Zielsystemen. Die Autorisierungsrichtlinien sind ein ASP.NET Core-Konzept. Es wird eine Richtlinie pro Route festgelegt und der Rest wird von den vorhandenen ASP.NET Core-Authentifizierungs- und Autorisierungskomponenten erledigt.

Folgende Verfahren werden von YARP unterstützt:

  • Cookie, Bearer, API Keys
  • OAuth2, OpenIdConnect, WsFederation
  • Client-Zertifikate

Nicht unterstützt werden hingegen die Windows-, Negotiate-, NTLM- und Kerbereos-Authentifizierung, da diese meist an eine bestimmte Verbindung gebunden sind.

Cross-Origin Resource Sharing – CORS

YARP kann Cross-Origin Requests behandeln, bevor sie an den Ziel-Server geleitet werden. Dies reduziert die Last auf den Ziel-Servern und sorgt für einheitliche Richtlinien.

Direkte Weiterleitung mit IHttpForwarder

Wenn die Applikation nicht den vollständigen Funktionsumfang benötigt, kann anstelle der kompletten Feature-Menge auch nur der IHttpForwarder verwendet werden. Dieser dient als Proxy-Adapter zwischen eingehenden und ausgehenden Verbindungen.

Der Proxy übernimmt in diesem Fall die Erstellung einer HttpRequestMessage aus einem HttpContext, das Senden und die Weiterleitung der Antwort.

Der IHttpForwarder unterstützt die dynamische Zielauswahl, wobei man selbst das Ziel für jede Anfrage festlegt.

Es können Anpassung an Anfrage und Antwort vorgenommen werden, wobei der Body ausgeschlossen ist. Und zu guter Letzt werden die Streaming-Protokolle gRPC und WebSockets sowie Fehlerbehandlungen unterstützt.

Diese minimale Variante unterstützt kein Routing, Load Balancing, Session Affinity und Retries – bringt aber einige Performance-Vorteile mit sich.

Ausblick

Für kommende Releases arbeitet das Team hinter YARP an der Unterstützung von HTTP/3, Service Fabric, einer Integration in Kubernetes sowie weiteren Performance-Verbesserungen.

Zusätzlich versucht Microsoft mit LLHTTP (Low Level HTTP) eine Alternative zum aktuellen HttpClient zu entwickeln, um mehr Kontrolle darüber zu haben, wie Anfragen gestellt und verarbeitet werden. Es soll insbesondere in Szenarien eingesetzt werden, bei denen die Performance wichtiger ist als eine einfache Verwendung. In YARP soll es für mehr Kontrolle über ausgehende Verbindungen und eine effizientere Verarbeitung von Headern eingesetzt werden.

Fazit

In diesem Artikel wurden die Grundlagen von YARP und die umfangreichen Funktionen erläutert. Mit Hilfe des gewonnenen Wissens und der Menge an guten Code-Beispielen im YARP-Repository auf GitHub können Sie jetzt einschätzen, ob die Funktionalitäten für einen gegebenen Anwendungsfall ausreichen und Ihren eigenen Reverse Proxy erstellen.

Da das Toolkit auf dem ASP.NET Core Stack basiert, kann es auf jeder Umgebung ausgeführt werden, die Sie bisher für Ihre .NET Core-Projekte verwendet haben.

Microsoft liefert mit YARP einen schnellen und zuverlässigen Reverse Proxy der nächsten Generation und wird in vielen Projekten Verwendung finden – nicht nur in denen von Microsoft.

Tester-Tea-Time (Teil 2): Rechtschreibung in Anwendungen – mehr als nur Kleinlichkeit

Die „Tester-Tea-Time“ ist ein Beitragsformat auf diesem Blog, in dem Themen aufgegriffen werden, die Testerinnen und Tester tagtäglich beschäftigen. Gewisse Problemstellungen oder Themen kehren immer wieder, daher soll hier eine Basis geschaffen werden, solche Phänomene zu erläutern und Lösungen dafür zu finden. Zudem sollen Diskussionen und neue Denkweisen angeregt werden. Im Testing können wir viel voneinander lernen, indem wir unseren Alltag beobachten!

Moderator: Willkommen zur Tester-Tea-Time! Im Interview mit Testerinnen und Testern der ZEISS Digital Innovation (ZDI) werden wir erneut spannende Themen diskutieren.

Widmen wir uns nun dem heutigen Thema. Dazu sprechen wir mit Sandra Wolf (SW), Testerin bei ZDI. Warum beschäftigen wir uns dieses Mal mit dem Thema „Rechtschreibung“ und wo siehst du den Zusammenhang mit der Softwareentwicklung?

SW: Der Alltag eines Testers hält viele Herausforderungen bereit. Gerade während des Testprozesses ist große Konzentration gefragt, wenn jedes Detail auf Qualität überprüft werden muss. Eines dieser Details ist die Rechtschreibung und Grammatik. Oft wird es unterschätzt, wie wichtig die korrekte Orthografie sein kann.
Im Arbeitsalltag passiert es oft, dass Rechtschreibfehler in der Software gefunden werden. Doch wenn diese zur Behebung an die Entwicklung gemeldet werden, kommt es nicht selten vor, dass der Tester dafür belächelt wird. Die vorherrschende Meinung ist, dass das nur sehr kleine und unwichtige Fehler wären. Im heutigen Gespräch soll mit dieser Meinung aufgeräumt werden. Rechtschreibung und Zeichensetzung sind nicht gerade die beliebtesten Themen und werden häufig als sehr trocken empfunden. Dabei sind gerade diese Regeln, die wir seit der Schulzeit lernen, eine Orientierungshilfe für uns und unser Gehirn. Ein Wort, das richtig geschrieben wird, wird auch leichter gelesen, im Satz zu einer Aussage kombiniert und somit im Gehirn verarbeitet. Aufmerksame Leser – oder im Fall der Softwareentwicklung – Nutzer werden zwangsläufig über falsche Rechtschreibung in der Software stolpern. Es wurde sogar nachgewiesen, dass bestimmte Persönlichkeitstypen unterschiedlich emotional auf falsche Orthografie reagieren (vgl. Weiß, 2016). Somit können Fehler in diesem Bereich im Gegensatz zu ihrem trockenen Ruf Emotionen auslösen, die dann als Konsequenz den Umgang mit der Software beeinflussen.

Zwei Kollegen zum Interview über Videokonferenz verbunden
Abbildung: Stanislaw Traktovenko und Sandra Wolf in der virtuellen Tester-Tea-Time im Gespräch.

Moderator: Von welcher Art der Beeinflussung sprechen wir in diesem Fall?

SW: Korrekte Rechtschreibung strahlt zum Beispiel Seriosität aus. In Bewerbungen und amtlichen Anträgen wird eine fehlerfreie Rechtschreibung vorausgesetzt. Es ist sogar in Studien belegt worden, dass beispielsweise die Chancen auf Bewilligung eines Kreditantrags durch sprachliche Fehler vermindert werden (vgl. Weiß, 2016). Übertragen wir das nun auf die Software, die wir entwickeln, ist nur ein möglicher Schluss zu ziehen: Rechtschreibung ist essenziell für eine adäquate Nutzung und die Außenwirkung der Software beim Kunden. Und somit sollte dieses Thema innerhalb des Entwicklungsprozesses eindeutig ernster genommen werden und mehr Aufmerksamkeit bekommen als bisher.
Schauen wir uns den Alltag von Testern und Entwicklern an, dann wissen wir, dass die Funktionalität der Software im Mittelpunkt steht. Natürlich ist nachvollziehbar, dass ein kosmetisch wirkendes Thema wie die Rechtschreibung hinter aufwendig programmierten Anwendungsteilen zurücktritt. Das sollte alle Beteiligten des Prozesses allerdings nicht über die Wichtigkeit hinwegtäuschen. Denn ganz klar ist, dass der Erfolg eines Produktes und somit auch einer Anwendung von der sprachlichen Qualität beeinflusst werden kann. Der erste Eindruck beim Lesen eines Textes oder beim Nutzen einer Software lässt uns automatisch auch auf den Bildungsgrad der Schöpfer schließen (vgl. Frost, 2020). Somit kann durch eine fehlerhafte Rechtschreibung ein schlechtes Licht auf eine gute Software geworfen werden.

Moderator: Wie muss ich mir dieses “schlechte Licht”, in dem die Software dann steht, im Detail vorstellen?

SW: Durch eine schlechte Rechtschreibung kann das Vertrauen in die Qualität der Software verloren gehen und die Akzeptanz für die Anwendung sinken. Der Nutzer könnte davon ausgehen, dass generell wenig Wert auf Qualität gelegt wird, wenn schon mit der Rechtschreibung nachlässig umgegangen wird. Schließlich drückt eine korrekte Orthografie nicht nur Professionalität, sondern auch einen gewissen Respekt gegenüber dem Leser/Nutzer aus. Es konnte sogar festgestellt werden, dass eine Textqualität beeinflusst, ob jemand vom Interessenten zum Käufer wird. Wird das auf die Softwareentwicklung bezogen, kann es auf jeden Fall Budget einsparen, wenn von Anfang an auf die Rechtschreibung geachtet wird und die Meldung solcher Fehler ernst genommen wird (vgl. Frost, 2020).
Letztendlich präsentieren wir in unseren Projekten auch unser Unternehmen, weshalb das Thema der Orthografie weitreichendere Auswirkungen haben kann, als wir zunächst denken. Im besten Fall kann durch eine gute Rechtschreibung der Ruf unserer Softwareentwicklung verbessert werden bzw. erhalten bleiben. Dadurch können wiederum mehr Kunden und höhere Umsätze erzielt werden, weil die gleichbleibende Qualität unserer Softwareprodukte ein Argument für eine Zusammenarbeit mit der ZDI sein kann.

Moderator: Hier möchte ich gern anknüpfen und Stanislaw Traktovenko (ST) aus unserem Usability-Team zu Wort kommen lassen. Welche Bedeutung nimmt das Thema der Rechtschreibung aus deiner Sicht ein? Siehst du ebenfalls die Auswirkungen in dem von Sandra Wolf beschriebenen Maße?

ST: Aus meiner Sicht hat die Rechtschreibung einen Einfluss auf die Lesbarkeit und dadurch auf die Wahrnehmung der Informationen in der Anwendung. Wir ordnen das den Usability-Prinzipien Konsistenz und Sprache zu. Rechtschreibfehler haben also potenziell eine direkte Auswirkung auf die Usability einer Anwendung. Eine inkorrekte Orthografie stört zum Beispiel den Lesefluss und somit die Wahrnehmung der Software durch den Nutzer. Es entsteht ein negatives Gefühl und der Nutzer beschäftigt sich nicht mehr mit der Aufgabe, die er mit der Software eigentlich verfolgt hatte. Er wird durch eine falsche Rechtschreibung abgelenkt und das beeinflusst seine Effektivität und Effizienz. Auch wenn Rechtschreibung nur ein kleiner Bruchteil der Usability ist, kann sie somit größere Auswirkungen haben als gedacht, so wie Sandra bereits vorher erläutert hat.

Moderator: Vielen Dank, Sandra und Stanislaw für diese interessanten Einblicke. Die Auswirkungen sind tatsächlich weitreichender als erwartet, das ist sehr erstaunlich. Wir können somit zusammenfassen, dass das trocken wirkende Thema der Rechtschreibung in allen Softwareprojekten ernst genommen werden muss, um eine möglichst hohe Qualität zu liefern und sowohl die Produkte als auch uns als Unternehmen adäquat zu präsentieren. Das Thema der Rechtschreibung wirkt im ersten Moment vielleicht banal, hat aber im Endeffekt eine große Wirkung und somit Wichtigkeit für uns alle. Das Thema sollte daher unbedingt die Aufmerksamkeit bekommen, die es verdient hat.

In den folgenden Beiträgen werden wir weitere Problemstellungen aus dem Alltag von Testerinnen und Testern aufgreifen und besprechen, welche möglichen Lösungsansätze es dafür gibt.