UI-Dev-Session (Teil 2) – Erfahrungsbericht aus dem Projektalltag

Im ersten Beitrag dieser Blogartikelreihe wird eine leichtgewichtige Methode beschrieben, um Abweichungen zwischen dem vorgegebenen User Interface Design und der implementierten Anwendung zu beseitigen. Dabei arbeiten Entwicklerinnen und Entwickler sowie Spezialistinnen und Spezialisten für User Interface (UI) / User Experience (UX) mittels Pair Programming eng zusammen, um die Usability und das Erscheinungsbild einer Anwendung unkompliziert zu optimieren. 

In unserem Projekt führen wir regelmäßig solche „UI-Dev-Sessions“ durch. In diesem Blogbeitrag möchte ich von unseren Erfahrungen berichten – weg von der Theorie, hin zur Praxis. 

Wieso sind die UI-Dev-Sessions für uns wichtig? 

Im Rahmen des Projektes wird eine Standalone-Software entwickelt, welche Fachleuten der Augenheilkunde als Unterstützungstool zur Erhebung von Patientendaten sowie zur Analyse der Ergebnisse von operativen Laser-Sehkorrekturen dient. Auch im medizinischen Umfeld entwickelt sich User Experience immer mehr zu einem wichtigen Kaufkriterium. Neben Sicherheit, dem wohl wichtigsten Kriterium für Medizinprodukte, gewinnen weiche Kriterien wie “Joy of Use” und das Erscheinungsbild an Bedeutung. Die UI-Dev-Sessions sind für uns eine Möglichkeit, unserer Anwendung den Feinschliff zu verleihen. 

„The details are not the details. They make the design.” 

Charles Eames, Designer
Screenshot der Software, die Fachleuten der Augenheilkunde als Unterstützungstool zur Erhebung von Patientendaten sowie zur Analyse der Ergebnisse von operativen Laser-Sehkorrekturen dient
Abbildung 1: Screenshot der Software

Wie laufen die UI-Dev-Sessions bei uns ab? 

Unser Projektteam arbeitet agil und nutzt Scrum als Rahmenwerk für sein Vorgehen. Wie ein Großteil der Teams bei ZEISS Digital Innovation (ZDI) arbeiten die Teammitglieder verteilt, das heißt sie befinden sich nicht am selben Standort und damit auch nicht im selben Büro. Unser Projektteam ist über vier Standorte in zwei Ländern verteilt. Dabei sind die Rollen Scrum Master, Entwickler, Tester, Business Analyst und UI-/UX-Spezialist vertreten. 

An einer UI-Dev-Session nehmen bei uns meist jeweils Personen aus den Bereichen UI/UX sowie Entwicklung teil. Die Spezialistinnen und Spezialisten für UI/UX haben ihren Fokus auf zwei verschiedenen Aspekten, wodurch sie sich optimal ergänzen: einerseits auf dem visuellen Design des UI sowie andererseits auf dem Verhalten der UI-Komponenten. Die teilnehmenden Entwicklerinnen und Entwickler besitzen eine hohe Affinität für Frontend-Entwicklung. Eine von diesen Personen nimmt an jeder UI-Dev-Session teil und hat den Überblick über die zu erledigenden Punkte. Einige Tage vorher erinnern die Spezialistinnen und Spezialisten für UI/UX im Daily daran, dass eine UI-Dev-Session stattfinden wird und dass noch eine Person aus dem Entwicklungsteam als Unterstützung benötigt wird. Je nach Verfügbarkeit wird dann abgestimmt, wer unterstützen kann. Es gilt damit das Vier-Augen-Prinzip auf beiden Seiten (Design und Entwicklung) wodurch Fehler und umfangreiche Review-Runden vermieden werden können. 

Die Liste mit den zu lösenden UI-Fehlern wird im Projekt-Wiki von den Expertinnen und Experten für UI/UX gepflegt, strukturiert und priorisiert und ist jedem Teammitglied zugänglich. Dazu wird Confluence von Atlassian als Tool eingesetzt. Ein Ausschnitt der Themen ist in Abbildung 2 dargestellt. 

Beispiel für eine Liste mit zu lösenden UI-Fehlern
Abbildung 2: Ausschnitt aus der Liste der UI-Fehler

Da unsere Liste mit möglichen Themen aktuell recht umfangreich ist, sind regelmäßige Sessions notwendig. Eine UI-Dev-Session findet einmal pro Sprint – das heißt einmal alle drei Wochen – für zwei Stunden statt. Haben andere Themen im Sprint Priorität, kann der Termin auch kurzfristig verschoben werden, bestenfalls jedoch innerhalb des gleichen Sprints. Der Termin wird remote mit Hilfe von Microsoft Teams durchgeführt, da die Teilnehmenden über die Standorte Dresden, Leipzig und Miskolc verteilt sind. 

Ein bis zwei Tage vor der UI-Dev-Session suchen sich die Entwicklerinnen und Entwickler aus der Liste im Projekt-Wiki einige Punkte heraus und beginnen, diese vorzubereiten. Dazu zählt beispielsweise, die entsprechenden Stellen im Code mit To-dos zu markieren, um die Zeit in der UI-Dev-Session effizient für die eigentlichen Anpassungen zu nutzen. 

Zu Beginn der UI-Dev-Session gehen alle Teilnehmenden gemeinsam kurz die ausgewählten UI-Fehler durch, welche im Termin verbessert werden sollen. Anschließend werden die Themen von oben nach unten erledigt. Eine Person aus dem Bereich Entwicklung überträgt den Bildschirm und hat die Entwicklungsumgebung sowie den Styleguide in Figma geöffnet. Die weiteren Teilnehmenden haben ebenfalls den Styleguide geöffnet. Einer der Vorteile von Figma besteht darin, dass die Anwesenden sehen können, wo die anderen Beteiligten sich gerade im Styleguide befinden. So können die relevanten Stellen von allen schnell gefunden werden. Die Spezialistinnen und Spezialisten für UI/UX helfen den Entwicklerinnen und Entwicklern dabei, sich schneller im Styleguide zu orientieren und die relevanten Informationen zu finden. Wichtig dabei ist, dass sich die Personen aus dem Entwicklungsteam die relevanten Stellen selbst ansehen können und z. B. Farbwerte nicht einfach nur “vorgesagt” werden. So wird auch der Umgang mit dem Styleguide trainiert. 

Die ausgewählten Punkte werden nach und nach erledigt. Werden die ausgewählten UI-Fehler schneller behoben als vermutet, werden innerhalb des Termins neue Themen nachgezogen. Bleiben ausgewählte Themen offen, werden diese zu Beginn des nächsten Termins erledigt. 

Während der Vorbereitung oder in der UI-Dev-Session stellt sich hin und wieder heraus, dass Themen aufwändiger sind als zunächst angenommen. Die Entwicklerinnen und Entwickler teilen das den Spezialistinnen und Spezialisten für UI/UX mit. Diese verschieben das Thema dann aus dem Projekt-Wiki in ein eigenes Backlog Item in Jira, beispielsweise als Improvement oder neue User Story. 

In einem Anschlusstermin, der meist ein bis zwei Tage nach der UI-Dev-Session stattfindet und maximal 30 Minuten dauert, werden die Ergebnisse den Testerinnen und Testern vorgestellt. Das ist wichtig, um festzustellen, ob Testfälle von den Änderungen betroffen sind. Anschließend wird die Themenliste im Projekt-Wiki von den Spezialistinnen und Spezialisten für UI/UX aktualisiert. Die erledigten Punkte werden in Tabellenform dokumentiert, um das Nachvollziehen der durchgeführten Änderungen zu ermöglichen. 

Ausschnitt aus der Liste der behobenen UI-Fehler
Abbildung 3: Ausschnitt aus der Liste der behobenen UI-Fehler

Es muss nicht überall einen Haken geben 

In unserem Projekt hat sich der Einsatz der UI-Dev-Sessions bewährt, um das Erscheinungsbild der Anwendung schnell und unkompliziert zu optimieren. Für uns bringen die Sessions primär folgende Vorteile mit sich: 

  • Es werden UI-Fehler beseitigt, welche schon lange bekannt sind, denen aber gegenüber der Entwicklung neuer Features nur eine geringe Priorität beigemessen wurde. 
  • Die leichtgewichtige Methode mit geringem Dokumentationsaufwand lässt sich unkompliziert in unsere Sprints integrieren. 
  • Wir erreichen eine hohe Compliance mit dem ZEISS Styleguide für User Interfaces. 

Darüber hinaus stärken die Sessions die Kollaboration und die Wissensverteilung im Team: 

  • Durch die Zusammenarbeit zwischen den Bereichen Entwicklung und UI/UX können UI-Fehler effizient behoben werden, da die Entwicklerinnen und Entwickler sich auf die Implementierung konzentrieren können und die UI-/UX-Spezialistinnen und -Spezialisten die designspezifischen Vorgaben (z. B. Schriftfarbe, Abstand) direkt mündlich weitergeben können. 
  • Die Expertinnen und Experten für UI/UX lernen Implementierungsprobleme der Entwicklerinnen und Entwickler kennen, welche beispielsweise aus den eingesetzten Technologien resultieren. 
  • Mit den gesammelten Erfahrungen aus den UI-Dev-Sessions können die UI-/UX-Spezialistinnen und -Spezialisten zukünftige Designentscheidungen noch besser anhand des Entwicklungsaufwandes treffen. 
  • Das Entwicklungsteam lernt das Design-Tool Figma inklusive des Styleguides besser kennen. 
  • Das Team aus in UI/UX spezialisierten Personen hat die Gelegenheit, Designentscheidungen zu erklären und den Entwicklerinnen und Entwicklern einen Einblick zu geben, worauf es bei den Designs ankommt.
  • Das Entwicklungsteam arbeitet ein besseres Bewusstsein für Feinheiten im Design aus und kann so zukünftig UI Defects eher vermeiden. 

Die Liste der Vorteile, welche die Methode für uns mit sich bringt, ist somit lang. Doch wo ist der Haken? Für uns gibt es aktuell keinen und wir sind von der Methode überzeugt. Wir empfehlen sie daher jedem Team, bei welchem sich über die Zeit eine Vielzahl kleinerer UI-Fehler im Projekt angesammelt haben. Das Vorgehen ist flexibel und lässt sich je nach Bedarf des Teams adaptieren. Beispielsweise kann der Teilnehmerkreis minimiert oder das Zeitfenster erweitert werden. 

Ausblick 

Unser Ziel ist es, mit Hilfe der UI-Dev-Sessions die Liste der bestehenden UI-Fehler kontinuierlich zu verkleinern. Um die Anzahl neu hinzukommender UI-Fehler möglichst gering zu halten, wollen wir zukünftig die UI-Dev-Sessions schon während der Implementierung einer User Story in den Sprint integrieren. So können neue Abweichungen vom Design von vornherein vermieden werden.

UI-Dev-Session (Teil 1) – UI-Fehler im Team effizient lösen

Das zentrale Ziel eines jeden Styleguides ist es, ein einheitliches Erscheinungsbild und eine konsistente User Experience (UX) über mehrere Anwendungen hinweg zu gewährleisten. Für Anwendungen der ZEISS Gruppe gibt es aus diesem Grund detaillierte Vorgaben, wie ein User Interface (UI) auszusehen und sich zu verhalten hat. Jede Anwendung, die veröffentlicht und kommerziell genutzt werden soll, muss diese Vorgaben erfüllen. 

Abbildung 1 verdeutlicht die Komplexität und die vielfältigen Zustände, die sich selbst hinter sehr einfachen UI-Elementen verbergen. Die Aufwände für die korrekte Umsetzung solcher Zustände sind meist versteckt und werden bei der Anwendungsentwicklung gerne übersehen bzw. gegenüber der Implementierung von Funktionen niedriger priorisiert.

Grafik, die die verschiedenen Zustände eines Buttons im ZEISS Styleguide zeigt
Abbildung 1: Verschiedene Zustände eines Buttons im ZEISS Styleguide

Mit fortgeschrittener Projektlaufzeit sammeln sich kleine Abweichungen vom Styleguide, die das Gesamtbild schnell trügen. Weitere klassische Beispiele für solche UI-Fehler sind: 

  • Fehlende Zustände von UI-Elementen (Hover, Focused, …) 
  • Falsche Verwendung von Schriftgrößen, Schriftschnitten und Schriftfarben 
  • Falsche Verwendung von Graustufen für Flächen, Umrandungen oder Trennlinien 
  • Falsche Abstände und Positionierungen von UI-Elementen 

Zwar können solche Abweichungen meist schnell behoben werden, aber häufig sorgen umfangreiche Erstellungs- und Abnahmeprozesse für einen unverhältnismäßig großen Aufwand bei solchen vergleichsweise kleinen Anpassungen. Kommt es zusätzlich zu Missverständnissen oder Missinterpretationen der Designvorgaben und werden dabei mehrere Feedback-Schleifen benötigt, ist das für alle Beteiligten eine negative Erfahrung. 

Um solche kleinen UI-Fehler effektiver und effizienter zu beheben und das Produkt damit stückweise zu verbessern und dem Styleguide anzupassen, haben wir im Team eine unkomplizierte Form der Kollaboration geschaffen und etabliert.

Pair Programming mit Spezialistinnen und Spezialisten für UI/UX   

Das Pair Programming wird innerhalb des Entwicklungsteams unseres Projektes schon längst erfolgreich genutzt. Es fördert die Zusammenarbeit und die Qualität des Codes durch das Vier-Augen-Prinzip. Dabei arbeiten zwei Personen aus dem Entwicklungsteam gleichzeitig und direkt am Programmcode. Durch Diskussion, Kritik und das Einbringen neuer Ideen sollen hochwertiger Code erzeugt und Entwicklungszeit eingespart werden.  

Dieses Prinzip haben wir uns im Projekt zunutze gemacht und den Kreis der Teilnehmenden um Spezialistinnen und Spezialisten für UI/UX erweitert, um den Entwicklerinnen und Entwicklern direktes Feedback auf ihre Anpassungen am User Interface geben zu können. Die Anforderungen und Änderungswünsche an das User Interface werden durch die Expertinnen und Experten für UI/UX so direkt im Termin kommuniziert und die Änderungen geprüft, statt sie im Backlog zu dokumentieren und darauf zu warten, dass sie irgendwann korrekt umgesetzt werden. Zu den in UI/UX spezialisierten Personen gehören die Verantwortlichen für die Vorgaben an das User Interface, welche maßgeblich an der Entwicklung des Figma-UI-Designs beteiligt sind.  

Dem regelmäßigen Austausch in diesem Kreis haben wir den Namen UI-Dev-Session oder kurz einfach nur Dev-Session gegeben. Das Ganze funktioniert sehr gut auch dezentral im mobilen Arbeiten, denn dank Microsoft Teams und seiner Screen-Sharing-Funktion sehen alle teilnehmenden Personen gleichzeitig die Änderungen am Code und dem User Interface.  

Um einen Rahmen für das Pair Programming zu schaffen, haben wir dafür folgende „Spielregeln“ aufgestellt: 

  1. Es nehmen sowohl Personen aus dem Bereich Entwicklung als auch aus dem Bereich UI/UX teil. Insgesamt besteht die Gruppe aus zwei bis maximal vier Personen. Gemeinsam wird fokussiert nach der Lösung für konkrete UI-Fehler gesucht und live am Code programmiert. 
  1. Eine UI-Dev-Session hat von vornherein keinen vordefinierten Umfang. Vielmehr werden die erreichten Ziele durch die zur Verfügung stehende Zeit beschränkt. 
  1. Je nach Erfordernis des Projektes soll eine UI-Dev-Session in regelmäßigen Abständen stattfinden und einen klaren zeitlichen Rahmen umfassen. Zum Beispiel können 2-3 Stunden je Sprint, Woche oder Monat für eine UI-Dev-Session vorgehalten werden. Damit soll der zeitliche Aufwand zur Lösung von UI-Fehlern verhältnismäßig und gleichbleibend sein. 
  1. Mögliche Themen werden in einer Liste von den Spezialistinnen und Spezialisten für UI/UX gepflegt und iterativ in mehreren UI-Dev-Sessions abgearbeitet. Die Grundlage dafür sind z. B. Abweichungen zwischen Implementierung und Styleguide oder das Feedback aus Usability-Tests. 
  1. Das Entwicklungsteam kann Themen aus der Liste frei wählen und ggf. vorab aufbereiten. Dies soll dazu beitragen, dass möglichst viele Themen in kurzer Zeit gelöst werden. Sofern erforderlich, kann dennoch eine Priorisierung der Themen nach größtmöglichem Nutzen erfolgen, damit insbesondere bei engen Zeitrahmen die wichtigsten Themen zuerst gelöst werden. 
  1. Die Aktivitäten an unerwartet aufwändigen Themen, deren Live-Implementierung den zeitlichen Rahmen einer UI-Dev-Session sprengen, werden nach Einvernehmen der teilnehmenden Personen gestoppt und in anderweitige Backlog Items (z. B. User Stories oder Spikes) ausgelagert und später bearbeitet. 

Die bearbeiteten und gelösten UI-Fehler sollten im Nachgang der UI-Dev-Session dokumentiert und dem Projektteam zugänglich gemacht werden. So kann im Nachhinein jedes Projektmitglied nachvollziehen, was für Änderungen in welcher UI-Dev-Session vorgenommen wurden. Außerdem bietet es sich im Sprint-Review an, dem gesamten Projektteam die bearbeiteten Themen kurz vorzustellen.  

Beispiel für Abweichungen von der Implementierung (links) und für Styleguide-konformes Figma-Design (rechts)
Abbildung 2: Beispiel für Abweichungen von der Implementierung (links)
und für Styleguide-konformes Figma-Design (rechts)

Fazit

Ob klare Abweichungen vom Styleguide, Optimierungen nach Usability-Tests oder anderweitige kleinere Anpassungen am User Interface: Das in diesem Artikel beschriebene Vorgehen zur Durchführung einer gemeinsamen UI-Dev-Session mit Entwicklerinnen und Entwicklern sowie Spezialistinnen und Spezialisten für UI/UX fördert die Zusammenarbeit im Team und kann UI-Fehler schnell und effizient lösen. Der Dokumentationsaufwand soll damit auf ein Minimum reduziert werden und der zeitliche Aufwand für die Durchführung klar definiert sein. Durch iterative Durchführungen der UI-Dev-Sessions wird stückweise die Liste von UI-Fehlern abgearbeitet, wobei im Projektteam ein gegenseitiges Bewusstsein für solche Themen geschärft wird. 

Die UI-Dev-Session ist mittlerweile ein bewährtes Mittel in unserem Projekt und fester Bestandteil eines jeden Sprints. Einen ausführlichen Erfahrungsbericht aus unserem Projekt wird meine Kollegin Franziska Kubitz im zweiten Teil dieser Blogartikelreihe beschreiben. 

MAUI – Mehr als eine Insel

Im Mai 2020 hat Microsoft eine neue, vereinheitlichte UI-Plattform für alle Systeme unter dem klangvollen Namen MAUI bzw. in voller Länge „.NET Multi-Platform App UI“ vorgestellt, die voraussichtlich im November 2021 auf den Markt kommen wird. Doch was genau verbirgt sich hinter diesem Namen? Diese Frage soll in diesem Artikel beantwortet werden. Dabei sollen die Plattform vorgestellt, die technischen Hintergründe erläutert und vor allem auch das Potential der Technologie herausgestellt werden.  

Um MAUI als Plattform zu verstehen, muss man zunächst Xamarin kennen. Xamarin (und im speziellen Xamarin.Forms) ist eine Plattform zur Entwicklung von nativen Apps für iOS, Android und UWP mit C#, XAML und .NET. Man kann dabei aus einer Code-Basis für alle unterstützten Betriebssysteme eine App erzeugen. Somit ist der Aufwand für die Entwicklung für verschiedene Betriebssysteme im Vergleich zur nativen Codierung der Anwendungen deutlich geringer. Aktuell sind tatsächlich die diversen SPA-Frameworks für den Browser die einzige Technologie, welche vergleichbare Portabilität bei ähnlichem Gesamtaufwand bieten. 

Schematische Darstellung von MAUI
Abbildung 1: Mit Xamarin.Forms kann man aus einer Code-Basis native Apps für alle unterstützten Betriebssysteme erzeugen. MAUI wird der direkte Nachfolger von Xamarin.Forms.

Aber was ist nun dieses geheimnisvolle MAUI und was hat es mit Xamarin zu tun? Diese Frage lässt sich recht simpel beantworten: MAUI ist das neue Xamarin oder, präziser ausgedrückt, dessen direkter Nachfolger, der erstmals mit .NET 6 ausgeliefert wird. 

Genau wie mit Xamarin.Forms lassen sich mit MAUI aus einem Projekt und mit derselben Code-Basis Apps für alle unterstützten Betriebssysteme erstellen. Aus dem Code werden Installationspakete generiert, die dann auf den verschiedenen Plattformen installiert werden können. Offiziell werden von Microsoft Android ab Version 10, iOS, macOS und natürlich Windows, sowohl nativ als auch als UWP-App, unterstützt. Zudem soll es eine Community-Implementierung für Linux-Betriebssysteme sowie eine von Samsung zur Verfügung gestellte Implementierung für deren Tizen-Plattform geben.  Das Projekt- und Build-System wird für alle Plattformen vereinheitlicht und das Erzeugen der Apps wird sowohl über Visual Studio als auch das .NET CLI möglich sein. 

Ein weiteres Feature wird die geteilte Nutzung von Ressourcen wie Bildern oder Übersetzungen sein. Diese sollen von MAUI automatisch in die entsprechenden nativen Formate umgewandelt und in die erstellten Pakete integriert werden können. Außerdem wird man jederzeit auf die APIs des jeweiligen Betriebssystems zugreifen können. Hierzu soll es im Projekt einen speziellen Ordner geben, unter dem man die nativen Code-Hooks ablegt und die dann beim Kompilieren automatisch ins Paket integriert werden.  

Alle im .NET-Standard verfügbaren Funktionalitäten wie zum Beispiel Dependency Injection sollen dabei auch für eine MAUI-App genutzt werden können. Durch die Verwendung von C# und XAML wird auch die Nutzung entsprechender Entwurfsmuster wie dem viel genutzten MVVM-Pattern möglich sein. Neu ist zudem der Support für das Model-View-Update-Pattern, ein von Elm entliehenes Muster, mit dem man einen unidirektionalen Datenfluss analog zu Redux abbilden können soll. Auch Microsofts webbasierte Client-Technologie Blazor soll unterstützt werden. 

Leider wird MAUI erst mit der Einführung von .NET 6 im November 2021 offiziell zur Verfügung stehen. Zudem wurden Teile des Frameworks nach .NET 7 und damit ins Jahr 2022 verschoben. Hier sind vor allem der offizielle Support für Blazor und das MVU-Pattern zu nennen. Da MAUI der offizielle Nachfolger von Xamarin ist, wird dieses auch mit dem Release von .NET 6 noch für ein Jahr unterstützt und dann eingestellt.  

Damit scheint Microsofts Strategie für die Zukunft der UI-Entwicklung mit dem .Net-Framework klar zu sein: MAUI ist der neue „First Class Citizen“, wenn es um die Erstellung von nativen User Interfaces geht.  

Das klingt zunächst alles danach, dass Microsoft eine native Cross Platform-Unterstützung ins .NET-Framework integrieren möchte. Dieser Plan wird jedoch nur aufgehen, wenn MAUI von den Entwicklerinnen und Entwicklern akzeptiert wird. Durch das sehr späte Release und einer Menge hervorragender Open Source-Alternativen wie Uno könnte sich MAUI am Ende eventuell nicht etablieren. Aktuell kann man deshalb nur abwarten und sehen, was die Zukunft bringt. Die Migration von bestehenden WPF-Anwendungen gestaltet sich beispielsweise schwierig, da der ersehnte XAML-Standard, der eine Vereinheitlichung der Elemente und Tags für alle XAML-Dialekte definieren sollte, scheinbar wieder verworfen wurde und sich MAUI und WPF wegen unterschiedlicher Elemente nicht übergangslos austauschen lassen werden.

Wenn die Technologie aber tatsächlich hält, was sie verspricht, die Entwicklerinnen und Entwickler sie breitflächig einsetzen und MAUI so hochklassig wird, wie Microsoft es in Aussicht stellt, könnte hier eine Cross Platform-Revolution unter .NET in den Startlöchern stehen.

Web Components (Teil 2) – Einbindung in React

Im ersten Teil dieser Artikelreihe haben wir uns angeschaut, wie man eigene Web Components baut. Nun schauen wir uns die Einbindung in React-Anwendungen an.

Ihrer Idee nach sind Web Components unabhängig von JavaScript-Frameworks einsetzbar. Während dies beispielsweise bei Angular auch mit wenigen Handgriffen ohne Probleme funktioniert, sieht die Situation bei React leider etwas anders aus.​ Warum das so ist und wie man das Problem lösen kann, wird im Folgenden näher erläutert.

Prinzipiell lassen sich Web Components auch in React vollständig nutzen. Allerdings muss man für bestimmte Fälle zusätzlichen Aufwand betreiben und von üblichen React-Konventionen abweichen. Die Benutzung entspricht nicht mehr unbedingt dem, was React-Entwicklerinnen und -Entwickler erwarten würden.

Im Wesentlichen gibt es zwei Problemfelder: Einerseits handelt es sich dabei um das Problem „Attribute vs. Properties“, welchem wir uns in diesem Artikel widmen. Andererseits gibt es das Problem der „Custom-Events“ – dieses wird im nächsten Teil dieser Reihe behandelt.

Problembeschreibung „Attribute vs. Properties“

Wie wir im ersten Teil der Reihe gesehen haben, gibt es zwei Möglichkeiten, um Daten an eine Web Component zu übergeben – als HTML-Attribut oder als JavaScript-Property.

In diesem Code-Beispiel wird der „value“ als Attribut im HTML definiert:

<my-component value="something"></my-component>

Hier wird dagegen mittels JavaScript das gleichnamige Property gesetzt:

const myComponent = document.createElement("my-component")

myComponent.value = "something"

In JavaScript ist es aber auch möglich, explizit das Attribut zu setzen:

myComponent.setAttribute("value", "something")

JavaScript ist in dieser Hinsicht also flexibler, denn in HTML sind nur Attribute möglich – Properties lassen sich nicht in HTML setzen.

Wichtig zum Verständnis ist hierbei: Ob und wie Attribute und Properties von der Komponente verarbeitet bzw. berücksichtigt werden, liegt vollständig in der Implementierung der Komponente. Es gibt zwar die Best Practice, im Regelfall sowohl Attribute als auch Properties anzubieten und diese synchron zu halten, aber technisch ist niemand daran gebunden. Es wäre daher ohne Weiteres möglich, entweder nur Attribute oder nur Properties zu akzeptieren oder die beiden mit völlig unterschiedlichen Namen zu versehen (womit man aber sicherlich den Unmut der Benutzerinnen und Benutzer der Komponente auf sich ziehen würde).

Auf der anderen Seite gibt es jedoch auch handfeste Gründe, in manchen Fällen von dieser Best Practice bewusst abzuweichen.

Ein wichtiger Faktor ist, dass Attribute und Properties unterschiedlich mächtig sind: Attribute erlauben nur solche Werte, die als String repräsentiert werden können, d. h. Strings und Zahlen. Außerdem kann man durch die An- bzw. Abwesenheit eines Attributes auch Boolean-Werte abbilden. Komplexere Daten wie JavaScript-Objekte oder Funktionen können nicht als Attribut übergeben oder müssten serialisiert werden.

Bei JavaScript-Properties gibt es diese Beschränkung naturgemäß nicht. Allerdings haben Properties den Nachteil, dass sie in der Benutzung stets imperativ und nicht deklarativ sind. Anstatt  wie bei HTML einfach deklarativ zu sagen, welchen Zustand man haben möchte, muss man Properties mittels Befehlen imperativ der Reihe nachsetzen. Aus Entwicklersicht ist das eher unschön, denn besonders durch Frameworks wie React und (mit leichten Abstrichen) Angular hat man sich an die Vorzüge von deklarativem Arbeiten gewöhnt.

Ein weiterer Unterschied zwischen Attributen und Properties betrifft die Performance: Sowohl Attribute als auch Properties werden nicht nur dafür genutzt, Daten von außen in die Komponente zu geben, sondern auch, um auf Informationen der Komponente zugreifen zu können. Ein schönes Beispiel hierfür ist der Standard-HTML-Tag <video>, welcher die aktuelle Wiedergabeposition des abgespielten Videos mittels der JavaScript-Property „currentTime“ anbietet. Bei Abfrage dieser Properties erhält man die Position in Sekunden als Dezimalzahl. Ein dazu passendes HTML-Attribut existiert dagegen nicht. Ein solches Attribut müsste andernfalls ständig mit der aktuellen Abspielzeit aktualisiert werden, was im DOM eine relativ kostspielige Operation wäre. Die Abfrage über ein JavaScript-Property lässt sich dagegen recht performant lösen, da hierfür eine Lazy-Getter-Methode implementiert werden kann, die nur anspringt, wenn die Position tatsächlich abgefragt wird.

Wir haben bei Web Components somit zwei unterschiedliche Mechanismen für einen sehr ähnlichen Zweck, die sich dennoch in einigen Aspekten recht deutlich unterscheiden.

AttributeProperties
deklarativimperativ
String, Number, BooleanString, Number, Boolean, Date, Object, Function

React Props

Bei React sieht die Sache etwas übersichtlicher aus: React kennt lediglich so genannte „Props“. Da React einen starken Fokus auf deklaratives Programmieren legt, ähnelt die Benutzung der von HTML-Attributen:

<MyComponent value="something" />

React-Props sind aber nicht auf bestimmte Datentypen beschränkt, sondern erlauben das Übergeben von beliebigen Daten und auch von Funktionen. Hierfür wird anstelle der Anführungsstriche eine Syntax mit geschwungenen Klammern benutzt:

<MyComponent
    aDate={ new Date() }
    aNumber={ 12 }
    aComplexObject={ {firstname: "Hugo", lastname: "Meier" } }
    aFunction={ () => console.log("some action") }
/>

In gewisser Weise kombiniert React die jeweils positiven Aspekte von Attributen und Properties in einem einzigen Konzept. 

In der Komponente kommen die Daten in einem „props“-Objekt an, welches die übergebenen Werte als Key-Value-Paare enthält:

const MyComponent = (props) => {
    const aDate = props.aDate
    const aNumber = props.aNumber
    const aComplexObject = props.aComplexObject
    const aFunction = props.aFunction
    //...
}

Oder etwas kompakter mittels destructuring:

const MyComponent = ({ aDate, aNumber, aComplexObject, aFunction}) => {
    // ...
}

Als React-Entwickler muss ich sagen, dass mir persönlich die React-Variante mit Props deutlich besser gefällt als die Unterscheidung zwischen Attributen und Properties mit ihren jeweiligen Eigenarten bei Web Components – dies ist aber Geschmackssache.

Web Components in React

Nun ist die API von Web Components aber nun mal so, wie sie ist. Die Frage ist daher: Was passiert, wenn man eine Web Component in React benutzt? Werden „props“ als Attribute oder Properties an die Web Component weitergereicht?

Zunächst entscheidet React anhand der Groß- und Kleinschreibung des Tags, ob es sich um eine React-Komponente (beginnt mit Großbuchstaben) oder einen HTML-Tag handelt, worunter auch Web Components zählen. Mit Ausnahme einiger Sonderfälle bei einigen Standard-HTML-Tags setzt React Props bei HTML-Tags und Web Components immer mittels ​„setAttribute“​. Das heißt, dass die Benutzung von Attributen bei Web Components in React keine Probleme bereitet. Anders sieht es aus, wenn explizit JavaScript-Properties benutzt werden müssen, z. B. weil komplexe Daten oder Funktionen in die Web Component hineingereicht werden sollen. Dies lässt sich gegenwärtig mit React nicht deklarativ umsetzen. In gefühlt 90 % der Fälle stellt dies kein Problem dar, da es, wie oben bereits angemerkt, als Best Practice gilt, Attribute und Properties synchron zu halten und möglichst beide Varianten zu unterstützen. Nur in den restlichen 10 % der Fälle, in denen Properties notwendig sind, weil sich entweder die Autorinnen und Autoren der Web Component nicht an die Best Practice gehalten haben oder ein anderer Grund die Nutzung von Attributen verhindert, müssen wir uns etwas einfallen lassen.

Das heißt allerdings nicht, dass solche Web Components überhaupt nicht in React genutzt werden können! Wir können lediglich nicht den üblichen, rein deklarativen Weg gehen, sondern müssen auf die von React ebenfalls unterstützte, imperative API zurückgreifen. Wie dies funktioniert, wollen wir uns im Folgenden anschauen.

React abstrahiert von konkreten Instanzen von DOM-Knoten. Auch unabhängig von Web Components muss man aber in manchen Fällen direkt auf DOM-Knoten zugreifen, beispielsweise wenn eine Methode wie „.focus()“ aufgerufen werden soll. Für diesen Zweck nutzt React so genannte ​„Refs“​und genau diesen Mechanismus können wir auch für das Setzen von JavaScript-Properties an unseren Web Components benutzen. Im Code sieht das z. B. so aus:

import React, { useRef, useEffect } from "react"

const MyReactComponent = () => {
    const elementRef = useRef(null)

    useEffect(() => {
        if(elementRef.current) {
            elementRef.current.someProperty = "value"
        }
    }, [elementRef])

    return <my-custom-element ref={elementRef} />
}

Mit „const elementRef = useRef(null)“ erstellen wir eine Art Container, in die React nach dem Rendern die Referenz zum DOM-Knoten packt. „useEffect​“ kann dazu genutzt werden, eine Funktion auszuführen, sobald bestimmte Variablen verändert wurden. Dazu geben wir die „elementRef​„-Variable (in ein Array gewrappt) als zweiten Parameter an die​ „useEffect„-Hook-Funktion. Sobald React die Komponente das erste Mal gerendert hat, wird​ die angegebene Funktion ausgeführt, so dass unser Property entsprechend gesetzt wird. Wie man sieht, ist der Code doch um einiges umständlicher als lediglich ein Attribut direkt am Tag zu setzen. Das Beispiel zeigt aber, dass es eben doch möglich ist, Web Components in React zu nutzen. Im vierten Teil dieser Artikelreihe werden wir uns noch eine andere Variante anschauen, die besonders bei größeren Anwendungen, in denen bestimmte Web Components immer wieder eingesetzt werden sollen, besser skaliert. Im nächsten Artikel der Reihe schauen wir uns aber zunächst das zweite Problem von Web Components mit React genauer an: Die Verarbeitung von Custom-Events.

Fazit

Als Zwischenfazit lässt sich feststellen, dass die Situation von Web Components mit React kompliziert ist. Auf der einen Seite ist React hervorragend für die Entwicklung von umfangreichen Web-Anwendungen geeignet und daher auch weit verbreitet. Auf der anderen Seite ist es äußerst ärgerlich, dass React bei einer modernen Web-Technologie wie Web Components solche Probleme hat.

Als Grund hierfür lassen sich mindestens zwei Faktoren nennen: Zum einen entstand React zu einer Zeit, in der Web Components bzw. „custom elements“ noch eine bloße Idee und weit von der praktischen Umsetzung entfernt waren. Gleichzeitig legt das React-Team großen Wert auf Abwärtskompatibilität und schreckt verständlicherweise vor inkompatiblen Änderungen in der Art und Weise, wie React-Komponenten geschrieben werden, zurück. Die Diskussion dazu, welche Optionen im Raum stehen, um React kompatibel zu Web Components zu machen, kann bei Interesse im Issue-Tracker des Projekts​ verfolgt werden.

Der zweite Faktor, den ich hervorheben möchte, ist: Die Konzepte von Web Components und React unterscheiden sich relativ stark voneinander, wenn es darum geht, wie Komponenten benutzt werden. React ist vollständig auf deklaratives Programmieren ausgelegt, während Web Components und auch Standard-HTML-Tags eine Mischform vorsehen, die teilweise deklarativ, an einigen Stellen aber eben auch zwingend imperativ ist. Und da React-Entwicklerinnen und -entwickler genau diesen deklarativen Charakter von React mögen, kann es nicht die Lösung sein, die imperative API von Web Components einfach blind zu übernehmen. Stattdessen müssen Wege gefunden werden, wie eine Zusammenarbeit zwischen diesen beiden „Welten“ möglich ist. Leider dauert der Prozess dieser Lösungssuche mittlerweile schon relativ lange an und zwischenzeitlich schien die Diskussion innerhalb der Community der React-Entwicklerinnen und -Entwickler ein bisschen eingeschlafen zu sein.

Es bleibt daher nur zu hoffen, dass dieser Prozess wieder Fahrt aufnimmt, so dass Web Components in Zukunft auch in React-Projekten einfach und ohne umständliche Umwege eingesetzt werden können. 

Exploratives Testen (Teil 1) – Der Test für Faule oder die Krone der Testschöpfung?

Wir sind Testerinnen und lieben Testmethoden, bei denen die menschlichen Stärken, die Kreativität und die Kollaboration im Vordergrund stehen. Dabei wollen wir aber keinesfalls ohne Regeln bzw. Rahmenbedingungen agieren oder für eine Dokumentationsabstinenz plädieren.

Uns sind bereits einige Vorurteile über das explorative Testen begegnet, daher haben wir uns die Frage gestellt, wie diese zustande kommen. In diesem Artikel gehen wir speziell auf diese Vorurteile ein mit dem Ziel, diese aus dem Weg zu räumen. Doch zuerst betrachten wir das explorative Testen näher.

Was ist exploratives Testen?

Exploratives Testen kann viel mehr als Testfälle stumpf abzuarbeiten: Es fördert das kreative Denken während einer Testsession, sprengt Grenzen auf und befriedigt die Neugier. Gleichzeitig verlangt es Disziplin in Bezug auf das Erreichen des gesetzten Ziels während einer Testdurchführung und im Hinblick auf die Dokumentation.

Das ISTQB (unabhängiges Expertengremium für standardisierte Ausbildung von Softwaretestern) bezeichnet das explorative Testen in seinem Glossar als einen „Testansatz, bei dem die Tests dynamisch entworfen und ausgeführt werden, basierend auf dem Wissen, der Erkundung des Testelements und den Ergebnissen früherer Tests“ (Archivversion 3.4 des ISTQB® GTB Glossary). Anders als beim „klassischen“ Testen mit vorbereiteten Testfällen handelt es sich somit um einen intuitiven Testansatz, bei dem jede vorherige Idee zur nächsten führt. Dabei gibt es verschiedene Hilfsmittel, um einen neuen Ansatzpunkt zu erhalten, Ideen zu entwickeln und mehr Struktur zu schaffen. Dazu zählen bspw. die Test-Charter, die Heuristiken, das Test-Orakel oder auch die Test-Touren.

Hand, die eine Glühbirne hält, aus der untereinander vernetzte Punkte aufsteigen
Abbildung: Exploratives Testen – ein intuitiver Testansatz

Zusammenfassend lässt sich sagen, dass die Testerin oder der Tester die Tests durch Erfahrung, Intuition, Neugier und strukturiertes Vorgehen erstellt. Trotzdem ist diese Art des Testens nicht nur für erfahrene Testerinnen und Tester sondern auch für Projektneulinge gut geeignet, die das Testobjekt und/oder das Vorgehen erst kennenlernen. Um die Person dabei an die Hand zu nehmen, sollte ein Ziel definiert oder ein Überblick des Objekts geschaffen werden. Dies kann entweder im direkten Austausch per Pair Testing erfolgen oder in Gruppen über den Ansatz des Mob Testings.

Vorurteile gegenüber dem explorativen Testen

Aber welche Vorurteile gibt es nun, gegen die sich das explorative Testen behaupten muss?

Exploratives Testen ist oft als strukturlos, nicht nachvollziehbar, nicht quantifizierbar – schlicht und einfach als „Ich-klick-da-mal-so-rum-und-schau-was-passiert“ – verschrien. Die Aussage obsoleter Dokumentation erschwert es zusätzlich, das explorative Testen in Kundenprojekten in Rechnung zu stellen. Das ist ein nachvollziehbarer Grund, wenn davon ausgegangen wird, dass exploratives Testen dokumentationsfrei und somit die Testleistung nicht nachvollziehbar ist. Schnell kommen somit auch die Aussage sowie das Totschlagargument zustande, dass für diesen Test keine Zeit zur Verfügung steht.

Im Folgenden werden wir die eben dargelegten Behauptungen sowie weitere negative Aussagen genauer betrachten und dazu Stellung nehmen.

Vorurteil Nummer 1: “Exploratives Testen ist nicht nachvollziehbar.” / “Explorativ getestete Inhalte kann ich nicht erneut testen.” / “Wie soll ich da einen Bug-Retest machen?” Diese Aussagen haben uns neugierig gemacht. Auf die Frage, was unter explorativem Testen verstanden wird, erhielten wir oft die Antwort, dass es für das spontane Herumklicken im Testobjekt genutzt wird. Es soll das Kennenlernen des Testobjekts fördern oder weitere Varianten testen, die bei der vorherigen Testfallerstellung nicht beachtet wurden. Und somit wird es nebenbei ungeplant sowie unstrukturiert durchgeführt. Eine Dokumentation wurde nicht erwähnt. Somit erklärt sich, wie das Vorurteil zustande kommt, diese Testmethode sei nicht nachvollziehbar und Tests sowie Bugfixes könnten schwer nachgetestet werden. Es ist absolut richtig, dass explorative Tests die spontane Testdurchführung unterstützen. Jedoch muss darauf geachtet werden, die Testschritte, erwartete Ergebnisse oder auch Abweichungen stets zu dokumentieren und die Tests somit nachvollziehbar zu machen. Wie die Dokumentationstiefe dabei aussieht, muss durch die Rahmenbedingungen eines jeden Projekts einzeln definiert werden. Wir halten fest: Exploratives Testen bedeutet nicht, nicht zu dokumentieren.

Um dem ersten Vorurteil entgegenzuwirken und Struktur in das explorative Testen zu bringen, kann man das Session-basierte Testmanagement nutzen. Während einer Session wird das Testobjekt mit größtmöglicher Flexibilität und Freiheit geprüft. Dabei werden die Rahmenbedingungen mithilfe eines definierten Standpunktes und einer Charta (Ziel und Ablauf für eine Session) gesetzt. Dies beinhaltet neben einigen anderen Komponenten auch eine Dokumentation durch Session-Reports, in denen die durchgeführten Testschritte, Abweichungen, das Testobjekt und weitere Informationen festgehalten werden können. Diese können je nach testender Person oder Projekt angepasst werden. Im Internet lassen sich verschiedene Beispiele für Session-Reports finden.

An dieser Stelle sei ein spezieller Anwendungsfall erwähnt: Exploratives Testen im regulierten Umfeld. Hier nimmt die Dokumentation eine zentrale Rolle ein. Das Vorurteil hier: Exploratives Testen ist im regulierten Umfeld unmöglich oder nur sehr schwer umsetzbar, aufgrund der regulatorischen Vorgaben. Wie man es trotz Vorgaben umsetzen kann, werden wir in einem weiterführenden Artikel aufzeigen.

Vorurteil Nummer 2: “Für exploratives Testen haben wir keine Zeit” / “Erst einmal müssen wir unsere vorbereiteten Testfälle abarbeiten, bevor wir explorativ testen können.“

Um die explorative Testmethode aktiv im Projekt umzusetzen, muss man bereit sein, das bisherige Testvorgehen anzupassen und den Vorteil der Zeitersparnis zu erkennen.  Denn sieht man den explorativen Test nur als Ergänzung, ohne eine Angleichung der bisher genutzten Teststruktur, wird dieses Vorgehen nur als Belastung oder als ein lästiger Zusatz gesehen, wodurch das Keine-Zeit-Vorurteil zustande kommt. Erfolgt allerdings, wie beim explorativen Testen vorgesehen, die Testfallerstellung gleichzeitig zur Testfalldurchführung, entfällt die nun überflüssige Erstellung von Testfällen, die zum Schluss nicht durchgeführt werden und somit Zeitverschwender darstellen. Die gewonnene Zeit ermöglicht es der Testerin oder dem Tester, neue Testideen zu entwickeln und somit das Testobjekt intensiver zu testen. So können z. B. Debriefings durchgeführt werden, um die gewonnenen Erkenntnisse mit den anderen Teammitgliedern zu teilen. Auch kann diese Zeitersparnis genutzt werden, um die Testautomatisierungsquote zu erhöhen.

Vorurteil Nummer 3: “Dokumentation schön und gut, aber exploratives Testen ist nicht ausreichend.”:
Diese Aussage ist richtig, wenn damit gemeint ist, dass exploratives Testen für sich stehend als vollumfänglicher Testansatz gelten soll. Neben den explorativen Tests sollten mindestens automatisierte Tests definiert und ausgeführt werden (z. B. Unit-, Integrations- und GUI Tests). Wenn das Projekt einen hohen Automatisierungsgrad besitzt, ist es sogar durchaus möglich, das manuelle Testen rein explorativ durchzuführen. Alternativ kann die explorative Methode als Ergänzung zum klassischen Testansatz genutzt werden, um das manuelle Testen leichter, flexibler und freier gestalten zu können. Wie viel exploratives Testen in einem Projekt angewendet wird, muss stets sorgfältig geprüft werden. Nicht immer ist es möglich, alle manuellen Tests explorativ zu gestalten. Das kann an unterschiedlichen Faktoren liegen z. B. an einem zu niedrigen Automatisierungsgrad oder auch an fehlenden Skills der Testerinnen und Tester. Sie sollten aus unserer Sicht Skills wie Kreativität, Gewissenhaftigkeit, Eigeninitiative, Eigenverantwortung, Verständnis von Qualität sowie soziale Aspekte wie Kommunikations- und Teamfähigkeit mitbringen.

Fazit

In diesem Beitrag haben wir die Vorteile des explorativen Testens aufgezeigt und Argumente zusammengetragen, welche die vorhandenen Vorurteile demgegenüber entkräften sollen. Aus unserer Sicht lohnt es sich, das bisherige Testvorgehen zu überdenken und sich auf das explorative Testen einzulassen, um dessen positive Effekte zu nutzen. Natürlich sollte jedes Projekt für sich betrachtet und die Möglichkeiten zum explorativen Testen ermittelt werden – ohne dieses jedoch von Vornherein komplett auszuschließen. Negative Aussagen oder Erfahrungen sollten ggf. hinterfragt werden. Bei der Wahl der Methode und ihrer Ausführung sind immer auch die Skills der Testerinnen und Tester zu betrachten. An dieser Stelle möchten wir noch einmal besonders darauf hinweisen, dass die Dokumentation auch beim explorativen Testen essenziell ist.

Dieser Beitrag wurde verfasst von:

Katharina Warak

Katharina Warak arbeitet als Senior Softwaretest Engineer bei der ZEISS Digital Innovation. Sie ist für die Automatisierung auf API- und GUI-Ebene zuständig. Außerdem hilft sie den Kunden in den Projekten mehr über die kollaborativen Testmethoden zu erfahren und diese Methoden zur Verbesserung ihrer Arbeitsweise einzusetzen. Dieses Wissen teilt sie auch gerne auf internationalen und nationalen Konferenzen.

Alle Beiträge des Autors anzeigen

Appium – Eine Einführung (Teil 1)

In den folgenden drei Blogartikeln möchte ich Ihnen Appium vorstellen: Ein Testautomatisierungs-Tool, welches speziell für den Test mobiler Anwendungen entwickelt wurde. Appium bietet uns die Möglichkeit, mobile-spezifische Anwendungsfälle wie z. B. Gestensteuerung, SMS oder eingehende Anrufe zu simulieren und entsprechende Testfälle zu automatisieren. Neben virtuellen Geräten bietet uns Appium als zusätzliches Feature die Möglichkeit, automatisierte Testfälle auf realen mobilen Endgeräten auszuführen.

Wieso auf mobilen Geräten automatisieren?

Aber wieso sollten wir unsere Testautomatisierung auf realen Endgeräten ausführen? Wieso sollten wir nicht die virtuellen Geräte der Entwicklungstools Xcode (iOS) und Android Studio (Android) nutzen? Dies sind berechtigte Fragen, denn die Anschaffung von Endgeräten verursacht Kosten.

Das erste Argument für eine Automatisierung auf realen Endgeräten mag banal klingen, fällt jedoch schwer ins Gewicht: Ihre Anwenderinnen und Anwender nutzen keine virtuellen Geräte.

Man könnte annehmen, dass virtuelle Geräte reale Endgeräte eins zu eins widerspiegeln. Diese Annahme ist jedoch falsch. Der Hauptgrund dafür ist, dass virtuelle Geräte keine eigene Hardware besitzen. Sie nutzen die Hardware des Rechners, auf dem sie installiert sind. Die Erfahrung zeigt auch, dass Fehler, die auf einem realen Endgerät entdeckt wurden, in virtuellen Geräten nicht immer zuverlässig reproduziert werden können.

Das Automatisieren auf realen Endgeräten ermöglicht Ihnen außerdem, die Performance Ihrer Anwendung zu überprüfen. Selbst wenn alle Funktionen in Ihrer Anwendung einwandfrei funktionieren, kann eine schlechte Performance auf dem Endgerät dazu führen, dass Ihre Anwendung unbrauchbar ist. Tests auf virtuellen Geräten liefern uns diesbezüglich keine verlässlichen Daten.

Auch das Problem der Hardware- und Software-Fragmentierung ist als ein Argument für die Automatisierung auf realen Endgeräten zu verstehen.

Sowohl bei iOS- als auch bei Android-Geräten entsteht durch immer größere Produktpaletten sowie Betriebssystemversionen, die immer länger im Umlauf bleiben, eine Art natürliche Fragmentierung – wie die folgenden Statistiken zeigen.

iOS Verteilung auf Apple-Geräten - Q2 2020
Abbildung 1: iOS Verteilung auf Apple-Geräten – Q2 2020 | https://developer.apple.com/support/app-store/
Android OS Verteilung - Q2 2020
Abbildung 2: Android OS Verteilung – Q2 2020 | https://9to5google.com/2020/04/10/google-kills-android-distribution-numbers-web

Bei Android-Geräten können wir eine weitere Software-Fragmentierung beobachten. Den Herstellern ist es möglich, das Android-Betriebssystem in einem gewissen Rahmen zu verändern. So können System-Apps wie die virtuelle Tastatur unterschiedlich funktionieren.

Nehmen wir als Beispiel das Gboard von Google und die virtuelle Tastatur OneU von Samsung. Beide unterstützen Swipe-Steuerelemente oder die Eingabe von Gesten, unterscheiden sich jedoch in der Ausführung.

Googles virtuelle Tastatur zeigt Ihnen das Wort, das gebildet wird, wenn Sie über die Tastatur gleiten. Samsungs Tastatur hingegen zeigt Ihnen das Wort erst, wenn Ihre Finger nicht mehr gleiten. Man sollte nicht davon ausgehen, dass die virtuellen Geräte von xCode oder Android Studio diese Unterschiede simulieren.

Natürlich können wir keinen unendlich großen Pool mit mobilen Endgeräten aufbauen. Wir können jedoch eine Auswahl von Geräten treffen, die bei Ihren Anwenderinnen und Anwendern stark vertreten sind.

Endgeräte von Apple, Samsung und Huawei sind sicher entscheidender für einen Endgeräte-Pool als Geräte anderer Hersteller, wie die folgenden Statistiken zeigen.

Hersteller Marktanteile Deutschland Q2 2020
Abbildung 3: Hersteller Marktanteile Deutschland Q2 2020 | de.statista.com
Hersteller Marktanteile USA Q2 2020
Abbildung 4: Hersteller Marktanteile USA Q2 2020 | https://www.canalys.com/newsroom/canalys-us-smartphones-shipments-Q2-2020

Problematik – Testautomation Tool-Fragmentierung

Nachdem ich nun auf die Vorteile der Testautomatisierung auf realen Endgeräten eingegangen bin, stellt sich natürlich noch immer die grundsätzliche Frage für Projekte mit einer vorhandenen Testautomatisierung: Wieso sollte Appium als zusätzliches Testautomatisierungstool eingeführt werden?

Das Problem der Software-Fragmentierung lässt sich auch in der Testfallautomatisierung beobachten. Es gibt immer mehr Tools, die bestimmte Funktionen und Umgebungen unterstützen, untereinander jedoch nur bedingt kompatibel sind. Im Idealfall wollen wir aber nur ein einziges Testautomatisierungstool nutzen, um die Hürden in der Testfallautomatisierung gering zu halten.

Um die zuletzt gestellte Frage zu klären, lassen Sie uns von einem Multiplattformprojekt ausgehen.

Unsere Anwendung wurde als Desktop-Webseite, native iOS-App und hybride Android-App programmiert. Zusätzlich haben wir eine responsive Web-App erstellt, denn Ihre Webseite besitzt bereits eine gute Abdeckung an automatisierten Testfällen durch Selenium.

Die folgenden Statistiken zeigen, dass eine Testfallautomatisierung, welche sich lediglich auf die Webseite beschränkt, für unser Multiplattformprojekt nicht mehr ausreicht.

Besitz und Nutzung von Smartphones nach Altersgruppen in Deutschland 2019
Abbildung 5: Besitz und Nutzung von Smartphones nach Altersgruppen in Deutschland 2019 | de.statista.com
Umsatz Mobile Stores in Mrd. US$
Abbildung 6: Umsatz Mobile Stores in Mrd. US$ | https://sensortower.com/blog/app-revenue-and-downloads-1h-2020

Wir sollten davon ausgehen, dass alle relevanten Zielgruppen unsere Anwendung auch auf mobilen Endgeräten nutzen.

Appium vs. Selenium

Ein kurzer Blick zurück auf die Ursprünge der Testautomatisierungstools zeigt, wieso die Einführung von weiteren Tools in unserem Beispiel sinnvoll ist.

Die ersten Applikationen, für die Testfälle auf Endgeräten automatisiert wurden, waren unter anderem Webseiten. Durch das Aufkommen von immer mehr Browsern wurde eine Automatisierung von Testfällen auch im Frontendbereich notwendig.

Eines der erfolgreichsten Testautomatisierungs-Tools in diesem Bereich ist Selenium. Den Ursprüngen entsprechend ist Selenium allerdings auf die Testfallautomatisierung von Webseiten ausgerichtet. Mobile spezifische Anwendungsfälle wie Gestensteuerung werden ohne Weiteres nicht unterstützt.

Doch gehen wir in unserem Multiplattformprojekt einmal davon aus, dass nur ein kleiner Teil der User die mobilen Anwendungen nutzt. Der Großteil nutzt die Desktop-Webseite und diese besitzt, wie wir wissen, eine gute automatisierte Testfallabdeckung durch Selenium. Lohnt sich dennoch die Einführung von Appium?

Nachdem ich das Problem der Tool-Fragmentierung kurz erläutert habe, wäre die Einführung von Appium eventuell mit mehr Kosten als Nutzen verbunden. Man könnte annehmen, unsere in der Selenium-Automatisierung erfahrenen Teams können die wichtigsten Testfälle mit Selenium und ein paar Workarounds für unsere mobilen Anwendungen automatisieren. Doch schauen wir uns Appium etwas genauer an, um zu überprüfen, ob diese Behauptung zutrifft.

Automatisierung mobile-spezifischer Anwendungsfälle mit Appium

Gehen wir zunächst auf die Problematik der mobile-spezifischen Anwendungsfälle ein. Lassen Sie uns einen Blick auf einige Anwendungsfälle werfen, die Appium unterstützt, bei denen sich für unsere Experten für Testautomatisierung mit Selenium sicher schnell Hürden aufbauen.

Gestensteuerung

In unserer Anwendung existiert eine Liste, deren Ende unsere Benutzerinnen und Benutzer gerne erreichen würde. In der Desktop-Browser-Version nutzen die User dafür sicher das Mausrad, den Scrollbalken oder die Pfeiltasten auf der Tastatur. In den mobilen Anwendungen werden sie allerdings auf diverse Gesten zurückgreifen, um das Ende der Liste zu erreichen.

Sie könnten den Finger auf den unteren Bildschirmbereich setzen, ihn halten, nach oben ziehen und wieder lösen, um nur einen bestimmten Teil der Liste zu bewegen. Eine weitere Möglichkeit wäre, den Finger auf den unteren Bildschirmrand zu setzen und mit einer schnellen Wischgeste nach oben ein automatisches Scrollen nach unten auszulösen. Für diese Fälle können wir auf die TouchAPI von Appium zurückgreifen.

Anrufe und SMS

Eingehende Anrufe und SMS wirken sich auf mobilen Endgeräten viel schwerer auf die Nutzung unserer Anwendung aus. Wo sich auf dem Desktop bei einem Anruf meistens nur ein weiteres Fenster öffnet, wird auf mobilen Endgeräten die laufende Anwendung meist unterbrochen und die jeweilige Anwendung für Telefonanrufe in den Vordergrund geholt. Auch eingehende SMS lösen meist eine Benachrichtigung über der laufenden Anwendung aus. Für diese Fälle können wir auf die Phone-Call-API von Appium zurückgreifen.

Systemanwendungen

Auf mobilen Endgeräten kommt unsere Anwendung wahrscheinlich viel häufiger in Verbindung mit Systemanwendungen. Sei es der Kalender, die Fotogalerie oder die hauseigene Kartenanwendung. Appium bietet uns an dieser Stelle – abhängig davon, welchen Appium Driver wir nutzen – die Möglichkeit diese Systemanwendungen ebenfalls in unsere Testautomatisierung zu integrieren.

Automatisierung von hybriden Apps

Betrachten wir nun die Problematik der Tool-Fragmentierung in der Testfallautomatisierung. Ein Teil des Problems besteht in den verschiedenen Entwicklungsarten von mobilen Applikationen. In unserem Beispielprojekt sind die üblichen Arten vertreten.

Werfen wir einen genaueren Blick darauf, wie Appium mittels der Context API, mit den komplexeren hybriden Anwendungen umgeht.

Um Elemente zu finden oder mit ihnen zu interagieren, geht Appium standardmäßig davon aus, dass sich all unsere Befehle auf native UI-Komponenten beziehen, die auf dem Bildschirm angezeigt werden. Unsere Testsession befindet sich also noch im sogenannten Native Context.

Nutzen wir z. B. den Appium-Befehl getPageSource im Rahmen einer hybriden Anwendung, werden wir in der Ausgabe bezüglich der Web Views nur Elemente finden wie <XCUIElementType…>. Wichtige Elemente wie Anchor Tags oder Divs werden uns zunächst nicht angezeigt.

Solange wir uns also im Native Context bewegen, sind alle Web Views oder sogenannter Web Context eine Blackbox für Appium. Wir sind zwar in der Lage, Web View UI-Elemente auszumachen und eventuell auch einige Buttons, die zum Beispiel iOS mit sich bringt. Elemente anhand von CSS-Selektoren auszumachen, wird jedoch nicht möglich sein.

Um besseren Zugriff auf den Web Context zu bekommen, müssen wir unsere Appium Session in den Web Context bringen. Dies können wir tun, indem wir zunächst den Namen des Web Contexts mit dem Befehl driver.getContextHandles ausmachen. Dieser gibt ein Array aller Context-Namen zurück, die Appium erstellt hat, um sie dem verfügbaren Context zuzuordnen. In unserem Fall wird uns ein Web Context namens WebView1 und ein Native Context namens NativeElement1 ausgegeben.

Um unsere Appium Session nun in den Web Context zu bringen, nutzen wir den Befehl driver.setContext(WebView1). Wenn dieser Befehl ausgeführt wurde, nutzt Appium die Context-Umgebung, die dem angegebenen Context entspricht.

Alle weiteren Befehle operieren nun innerhalb des Web Context und beziehen sich auf WebView1. Um wieder das native Element ansprechen zu können, nutzen wir den gleichen Befehl erneut mit dem Namen des Native Context, den wir ansprechen wollen. In unserem Fall also driver.setContext(NativeElement1). Wenn wir herausfinden möchten, in welchem Context wir uns aktuell befinden, können wir den folgenden Befehl nutzen: String currentContext = driver.getContext();

Nachdem wir nun kurz auf die Context API von Appium eingegangen sind, lassen Sie uns einen Blick auf die Funktionsweise werfen.

Auf iOS nutzt Appium das sogenannte „remote Debugger Protocol“, welches von Safari unterstützt wird. Dieses „remote Debugger Protocol“ ermöglicht es uns, Information über die in Safari angezeigten Seiten zu erhalten oder das Browserverhalten zu kontrollieren. Eine Methode, auf die wir zurückgreifen können, ist die Möglichkeit, JavaScript in die aktuelle Webseite einzufügen.

Appium verwendet diese Funktion, um alle in der WebDriver API verfügbaren Befehle durchzuführen.

Unterstützung von Codesprachen

Mit Appium können Sie Tests in verschiedenen Codesprachen schreiben. Dies ist ein Vorteil des Client-Server-Modells. Das Appium-Entwicklungsteam kann alle Appium-Funktionen in nur einer Server-Codebasis implementieren, welche in JavaScript geschrieben ist (Appium Server = NodeJS Plattform). Dennoch können die Nutzerinnen und Nutzer, die Code in einer anderen Programmiersprache schreiben, Zugriff auf diese Funktionen erhalten. Der Zugriff erfolgt über die Appium Client Libraries, die uns Appium zur Verfügung stellt. Wenn wir zum Bespiel unsere automatischen Tests in Java schreiben möchten, müssen wir die entsprechenden Appium Java Libraries in unseren Appium Client integrieren.

Appium Client-Server-Modell

Wie bereits beschrieben senden wir unseren Testcode (Befehle/Requests) über den Appium Client mit den entsprechenden Libraries an den Appium Server. Als Appium Client kann zum Bespiel das Entwickler-Tool Eclipse dienen. Der Appium Server wiederum schickt unseren Testcode (Befehle/Requests) an das mobile Endgerät, auf dem dieser dann ausgeführt wird. Doch gehen wir etwas mehr ins Detail.

Damit der Appium Server den Appium Client Testcode (Befehle/Requests) interpretieren kann, nutzt er das WebDriver Protocol oder das ältere JSON Wire Protocol, welche unseren Testcode in einen HTTP RESTful request konvertieren.

Danach schickt der Appium Server unseren Testcode, je nachdem welches Endgerät wir ansprechen wollen, an das plattformspezifische Testframework, welches wiederum den Testcode auf dem Endgerät ausführt. Der Appium Server ist an dieser Stelle in der Lage, mit den unterschiedlichen Testframeworks zu kommunizieren.

Damit der Appium Server entscheiden kann, mit welchem dieser plattformspezifischen Testframeworks bzw. mit welchem Endgerät er kommunizieren soll, muss unser Testcode sogenannte „Desired Capabilities“ als JSON Object an den Appium Server mitschicken. In den Desired Capabilities geben wir zum Beispiel den Gerätenamen, die Plattform (iOS, Android…) und die Plattformversion an.

Appium Client-Server-Modell
Abbildung 7: Appium Client-Server-Modell

Es gibt nicht unbedingt nur ein Testframework pro Plattform. So gibt es beispielsweise unter Android drei verschiedene Automatisierungstechnologien von Google. Die älteste, UiAutomator, wurde von UiAutomator2 abgelöst. UiAutomator2 hat eine Vielzahl neuer Automatisierungsfunktionen hinzugefügt.

Das neueste Testframework heißt Espresso und funktioniert mit einem ganz anderen Modell als UiAutomator2, bietet jedoch eine viel größere Stabilität und Testgeschwindigkeit.

Sie können Ihre Appium-Tests anweisen, sich auf eine dieser Testframeworks zu beziehen, basierend auf deren spezifischen Funktionen und der Plattformunterstützung.

Theoretisch könnten Sie die Testframeworks auch direkt einsetzen. Appium bietet jedoch einen praktischen Rahmen für die verschiedenen Testframeworks, stellt sie mit demselben WebDriver-Protocol zur Verfügung und versucht, Verhaltensunterschiede zwischen den verschiedenen Testframeworks auszugleichen.

Appium als Rahmen für Testframeworks
Abbildung 8: Appium als Rahmen für Testframeworks

Wenn neue Testframeworks erscheinen, kann das Appium-Team ein Kommunikationsprotokoll (Driver) für diese erstellen, sodass Sie auf diese zugreifen können, ohne all Ihre Testskripte neu schreiben zu müssen. Dies ist die Stärke der Verwendung eines Standardprotokolls und der Client-Server-Architektur.

Es ermöglicht auch die plattformübergreifende Automatisierung. Anstatt zwei verschiedene Testframeworks in zwei verschiedenen Sprachen zu lernen, können Sie in vielen Fällen ein Appium-Skript schreiben und dieses auf unterschiedlichen Plattformen ausführen.

Wer Appium nutzt, für den ist es nicht erforderlich, viel über diese zugrunde liegenden Testframeworks zu wissen, da sie sich nur mit der Appium API befassen und beispielsweise keinen XCUITest- oder Espresso-Test schreiben.

Zusammenfassung

Zusammenfassend ist zu sagen: Appium ist ein Tool zur Automatisierung mobiler Anwendungen, welches von Selenium inspiriert wurde. Tatsächlich basieren Appium-Tests auf demselben Protocol wie Selenium-Tests. Selenium bietet seinen Nutzerinnen und Nutzern die Möglichkeit, Webbrowser zu steuern. Aus historischen Gründen wird es daher manchmal als „WebDriver“ oder „Selenium/WebDriver“ bezeichnet.

Wie Sie eventuell bereits am Namen erkennen können, wurde Appium so konzipiert, dass es so gut wie möglich mit Selenium kompatibel ist. Appium übernahm das gleiche Protocol wie Selenium, so dass Appium- und Seleniumtests größtenteils gleich aussehen und sich gleich „anfühlen“.

Tatsächlich wurden die Appium Client Libraries auf den Selenium Client Libraries aufgebaut. Es gab jedoch ein Problem: Das Selenium Protocol wurde nur zur Automatisierung von Webbrowsern entwickelt. Daher musste Appium dem Protocol Befehle hinzufügen, um mobilspezifische Automatisierung zu unterstützen. Dies bedeutet, dass Appium-Befehle eine Erweiterung der Selenium-Befehle sind.

Die zuvor aufgestellte Behauptung, dass die Einführung von Appium in unser Beispielprojekt aufgrund des Kosten-Nutzen-Faktors nicht sinnvoll wäre, ist also falsch. Es ist sogar davon auszugehen, dass eine Einführung, neben einer besseren Abdeckung hinsichtlich der Testautomatisierung, auch zu einer Prozessverbesserung beitragen kann.

Ich hoffe, dieser kurze Exkurs in die Welt der Testautomatisierung und in den technischen Hintergrund von Appium hat Ihnen etwas Freude bereitet.

In meinem zweiten Blog zum Thema Appium zeige ich Ihnen, wie wir Appium einrichten. Zusätzlich werde ich anhand konkreter Codebeispiele zeigen, was wir mit Appium in unserem Multiplattformprojekt leisten können. Dabei gehen wir auf die bereits angesprochenen Fälle ein.

Ich würde mich freuen, wenn Sie auch in den nächsten Beitrag dieser Blogreihe wieder reinschauen. Bis dahin, happy testing.

Der Test Analyst – nur ein Reviewer für automatisierte Testfälle? Ein Erfahrungsbericht im agilen Umfeld

Einleitung

Im agilen Umfeld tragen Regressionstests dazu bei, die Qualität aufrecht zu erhalten. Mit jeder User Story kommen neu entwickelte Funktionalitäten hinzu, alte Funktionalitäten müssen weiterhin funktionieren. Spätestens nach zehn Sprints ist der Regressionsaufwand so hoch geworden, dass man mit manuellen Tests nicht mehr alles nachtesten kann. Also bleibt nur eines: Testautomatisierung.

Ein Projekt, das auf der grünen Wiese entsteht, ermöglicht es, von Anfang an die Testautomatisierung sauber zu integrieren. Gleichzeitig findet man sich im Testumfeld oft als Einzelkämpfer mehreren Entwicklern gegenüber. Wie lässt sich also eine zeitintensive Automatisierung der Funktionalitäten im alltäglichen Doing eines Test Analysten realisieren?

Umfeld in unserem Projekt 

In unserem Projekt erstellen wir eine neue Software im JavaScript-Umfeld. Umgesetzt wird diese mit dem Electron Framework. Für die Automatisierung von Testfällen ist dadurch Spectron als Mittel der Wahl gesetzt. Als Projektplattform wird Jira genutzt und das Projekt wird nach dem SCRUM-Modell durchgeführt. Das Projektteam besteht aus (bezogen auf Vollzeit-Tätigkeit):

  • 6 Entwicklern inkl. 1 Architekt 
  • 1 Scrum Master 
  • 1 Business Analyst 
  • 1 ½ Testern  

Ansatz 

Bereits zum Kick-off des Projektes war absehbar, dass die Testautomatisierung durch die Tester nicht geleistet werden kann. Daher hat sich das Team folgende Lösung überlegt:

  • die Testautomatisierung erfolgt durch die Entwickler 
  • der Review für die Testfälle erfolgt durch die Tester 
  • die Erstellung und die Abnahme der Spectron-Testfälle wird in der Definition of Done festgeschrieben 

Vorteile

  • Zeiteinsparung Test: Der eigentliche Grund für dieses Vorgehen ist die Ressourcenknappheit seitens der Tester. Hätten diese auch die Automatisierung übernehmen müssen, wäre das Ganze nicht möglich gewesen.
  • Perspektivwechsel Test: Die Tester können im Gespräch und im Review einiges lernen. So wird bei Fragen, warum ein Test so geschrieben wurde, die Umsetzung verständlicher. Dadurch entstehen auch Testfälle, an die man sonst nicht gedacht hätte.
  • Know-how-Entwicklung: Da es zum Alltag des Programmierers dazugehört, entwicklungsbegleitende Tests zu schreiben, ist das Grundverständnis für die Erstellung der automatisierten Tests sehr hoch. Bei unserem Projekt ist dies bereits mehrfach von Nutzen gewesen:  
    • Teile der Anwendung konnten mit technischen Kniffen abgedeckt werden, die ein Tester nicht ohne Weiteres hätte liefern können. Ein Beispiel hierfür ist die automatisierte Prüfung der korrekten Darstellung einer Punktewolke in einem Chart und die Anzeige der Details eines gewählten Punktes. 
    • Über technische Refinements konnten die Performanz und die Stabilität der Spectron-Tests deutlich verbessert werden. 
    • Nach veränderter Toolauswahl dauerte die Ausführung eines kompletten Spectron-Durchlaufes eine halbe Stunde weniger (25% Zeiteinsparung).
  • Perspektivwechsel Entwicklung: Dadurch, dass der Entwickler sich mit der Sichtweise eines Nutzers auf die Funktionalität und die Oberfläche der Software beschäftigt hat, konnte eine Vielzahl von Fehlern vermieden werden und das Grundverständnis stieg durch den regen Austausch mit den Testern.

Nachteile 

  • Erhöhter Zeitaufwand Entwickler: Was an einer Stelle an Zeit eingespart wird, wird an anderer Stelle wieder benötigt. Der Aufwand kann aber in diesem Fall auf mehrere Schultern verteilt werden.
  • Gliederung: Entwickler gliedern Testfälle in technisch logische Bereiche. Da dies nicht immer identisch zur fachlichen Logik ist, kann es für die Tester schwer werden, bestimmte Testfälle wiederzufinden und zu überprüfen.

Herausforderungen und Lösungen 

  • Traceability DEV-QA: Der Review findet im Projekt im git (Diff-Tool) statt. Im Projekt wurden angepasste und angelegte Spectron-Testfälle durch das Test-Team gereviewed, gelöschte Testfälle aber nicht – in der Annahme, dass diese bei der Anpassung ersetzt wurden. Dadurch waren Requirements nicht mehr abgedeckt.
    Lösung: Um den Problemen im Review entgegenzutreten, ist ein Training für den Umgang mit git für alle, die im git arbeiten und reviewen müssen, besonders hilfreich. Auch ein Walkthrough zwischen Test- und Entwicklungsteam bei großen Anpassungen bring einen Mehrwert, damit die Tester besser verstehen, was die Entwickler umgesetzt haben.
Beispiel für Git-Review
Abbildung 1: Beispiel für Git-Review
  • Traceability-Spectron-Anforderungen: Diese Herausforderung ist speziell in unserem Projektumfeld entstanden. Das agile Team verwendet für das Anforderungs- und Testmanagement Jira, während im Umfeld des Kunden aus rechtlichen Gründen die Anforderungen und Testfälle in einer separaten Anforderungsmanagementsoftware spezifiziert werden müssen. Da die Systeme sich nicht kennen, ist eine automatische Traceability nicht gewährleistet.
    Lösung: Um dieser Hürde entgegenzuwirken wurde eine direkte Zuweisung der Req-ID in die Spectron Cluster eingeführt. 
Beispiel für direkte Zuweisung
Abbildung 2: Beispiel für direkte Zuweisung

Fazit

Abschließend lässt sich sagen, dass sich in unserem Projekt der Ansatz bewährt hat, den Test Analysten automatisierte Testfälle nur reviewen zu lassen, statt sie selbst zu schreiben. Die Aufgabenteilung zwischen Testern und Entwicklern fügt sich sehr gut in die agile Vorgehensweise (Scrum) ein. Die Vorteile überwiegen die Nachteile somit bei Weitem. 

Dieser Ansatz ist sehr gut geeignet für ein agiles Projekt mit schmalem Staffing und hohem Qualitätsanspruch, das auf der grünen Wiese startet. Man sollte diesen Ansatz aber von Beginn an verfolgen. Ein nachträgliches Aufsetzen ist kaum noch möglich, da eine sukzessive Erweiterung der Testfälle nach jeder User Story deutlich übersichtlicher und einfacher ist als Testfälle en bloc zu erstellen. Des Weiteren werden bereits zu Beginn Entscheidungen in der Umsetzung, der Gliederung, der Architektur und vor allem in den Prozessen (Definition of Done, …) getroffen.

WCF-Alternativen (Teil 4) – Eine Zusammenfassung

Im letzten Blogpost der Artikelreihe zu den Alternativen der Windows Communication Foundation (WCF) wollen wir diese noch einmal zusammenfassend gegenüberstellen.

Entscheidungsmatrix

EigenschaftWeb APIgRPC
Bidirektionale KommunikationBedingt möglich
Diese muss mit SignalR realisiert werden.
Bedingt möglich
Es wird nur Stream Response unterstützt.
Aufwand Änderung in BestandscodeGering
Durch die Übernahme der Service-Methoden in die Controller und die Generierung des Clients sind nur geringe Anpassungen nötig.
Groß
Das Mapping ist nötig, da teilweise eigene Datentypen
vorgegeben sind: Es muss ein Über- und Rückgabe-Parameter existieren.
Notwendiges VorwissenTechnologiespezifisch
Web-API-Wissen zu Controller und Action-Verwendung, HTTP-Verben
Technologiespezifisch
gRPC-Besonderheiten, Erstellung *.proto-Datei
PlattformunabhängigkeitJa
Bei der Verwendung von .NET Core können Client und Server auf unterschiedlichen Plattformen ausgeführt werden.
Ja
Bei der Verwendung von .NET Core können Client und Server auf unterschiedlichen Plattformen ausgeführt werden.
InteroperabilitätJa
Client und Server können in unterschiedlichen Programmiersprachen erstellt worden sein.
Ja
Client und Server können in unterschiedlichen Programmiersprachen erstellt worden sein.
Browser-UnterstützungJaOptional
Aktuell nur mit 3rd-Party-Bibliotheken möglich
Selbstbeschreibende SchnittstellenOptional
OpenAPI ist durch die Einbindung von 3rd- Party-Bibliotheken möglich.
Nein
Die *.proto-Datei zur Beschreibung der Schnittstelle muss selbst erstellt werden.
Payload-GrößeHöher
JSON, menschenlesbar
Geringer
Binary-Format
GeschwindigkeitGeringerHöher
ZukunftsfähigkeitJa
Web API wird aktuell als zukunftsfähige Alternative von Microsoft empfohlen.
Ja
gRPC wird aktuell als zukunftsfähige Alternative von Microsoft empfohlen.
DebuggingEinfach möglichBedingt möglich
Die übertragenen Daten können aufgrund der Komprimierung nicht eingesehen werden.

Vor- und Nachteile

Web API

gRPC

Vorteile

  • Übertragungsdaten lesbar
  • Weniger Code-Anpassung bei Migration nötig
  • Flexiblere Gestaltung der Endpunkte und Aufrufe in Bezug auf Über- und Rückgabe-Parameter
  • Schnellere Übertragung
  • Typisiert durch Protocol-Buffers-Schnittstellenbeschreibung
  • Einfache Generierung von Client-Klassen

Nachteile

  • Langsamere Übertragung im Vergleich zu gRPC
  • Generierung von Client-Klassen nur durch 3rd-Party-Bibliotheken
  • Keine Typisierung der Schnittstelle möglich
  • Übertragungsdaten nicht lesbar
  • Mapping-Code nötig, da keine Standard-.NET-Typen verwendet werden
  • Größerer Migrationsaufwand, da mehr Code-Anpassungen nötig

Fazit

In unserer Blogpostreihe zum Thema WCF haben wir sowohl ASP.NET Core Web API als auch gRPC vorgestellt. Dabei ist deutlich geworden, dass beide Varianten ihre Vor- und Nachteile haben.

Bei Web API können die Schnittstellen durch den Content-First-Ansatz sowie die Nutzung von HTTP sehr einfach von jedem verwendet werden. Dabei sind die übertragenen Daten jederzeit einsehbar und können gelesen werden.

Durch gRPC werden im Contract-First-Ansatz die Schnittstellenaufrufe abstrahiert, wodurch diese schneller sind und von Entwicklern sehr einfach angesprochen werden können. Dabei können die übertragenen Daten aber nicht eingesehen werden.

Grundsätzlich ist die Migration zu beiden Varianten möglich und beide werden auch von Microsoft empfohlen. Abschließend kann jedoch keine Empfehlung für eine der beiden Alternativen gegeben werden. Eine Entscheidung sollte immer projektspezifisch und nach verschiedenen Kriterien wie Projektgröße, Erfahrung in der jeweiligen Technologie oder bestehender Architektur getroffen werden.

Weihnachtsfeier in Zeiten von Corona: Der 2. ZEISS Digital Innovation Online-Campus

Bereits im Frühjahr beginnen wir als ZEISS Digital Innovation (ZDI) mit der Planung unserer Weihnachtsfeier, die in der Regel am Freitag vor dem ersten Adventswochenende stattfindet. 2020 stand für uns schnell fest, dass eine Weihnachtsfeier, zu der sonst alle Beschäftigten in Dresden zusammenkommen und gemeinsam feiern, dieses Mal leider nicht möglich sein würde. Die Weihnachtsfeier ausfallen zu lassen, kam für uns jedoch ebenfalls nicht in Frage, sodass wir uns auf die Suche nach einem neuen Format begaben.

Hierbei knüpften wir an unseren 1. ZDI Online-Campus an, zu welchem wir bereits viele positive Rückmeldungen erhalten hatten. Besonders wichtig war uns dieses Mal neben der internen Wissensvermittlung, dass die weihnachtliche Stimmung und das „Wir-Gefühl“ nicht zu kurz kommen sollten. Aber wie bringen wir diese zu unseren Kolleginnen und Kollegen nach Hause?

Eine Karte mit allen Standorten, von denen aus unsere Kolleginnen und Kollegen dem Online-Campus zugeschaltet waren.
Abbildung 1: Unsere Kolleginnen und Kollegen nahmen von den unterschiedlichsten Standorten am Online-Campus teil.

Eine kleine Weihnachtsüberraschung für alle Mitarbeitenden

Um verteilt weihnachtliche Stimmung aufkommen zu lassen, haben alle Beschäftigten jeweils ein kleines Weihnachtspäckchen per Post erhalten, mit der Bitte, dieses erst am Tag unseres gemeinsamen Online-Campus zu öffnen.

Die 345 Päckchen wurden von dem Organisationsteam bei stimmungsvoller Weihnachtsmusik eigenhändig gemeinschaftlich verpackt. Wir waren glücklich, dass die Weihnachtsüberraschung bei all unseren Kolleginnen und Kollegen aus Deutschland und Ungarn rechtzeitig zu Hause ankam.

Somit waren alle pünktlich zu unserem 2. ZDI Online-Campus mit weihnachtlichen Leckereien, Glühweingewürz für einen leckeren Punsch, Adventskalender, Weihnachtsmütze und anderen kleinen Aufmerksamkeiten ausgestattet und es konnte losgehen.

2. Online-Campus mit Online-Teamspiel und weihnachtlicher Feierstunde

Mit den positiven Erfahrungen aus unserem 1. ZDI Online-Campus wurden auch dieses Mal verschiedene Vortragsslots von und für unsere Kolleginnen und Kollegen über den gesamten Tag hinweg angeboten. Die technische Umsetzung erfolgte erneut mit Microsoft Teams. Es wurden insgesamt 29 Vorträge zu unterschiedlichen Themen, wie bspw. Java, .NET, Cloud, Usability, Agile und Web, gehalten. Als Lessons Learned passten wir die Dauer der Vortragsslots (45 Minuten statt 30 Minuten) und Wechselpausen (15 Minuten statt 10 Minuten) an. So hatten alle Teilnehmenden zwischen den Slots Zeit durchzuatmen und sich gedanklich auf den nächsten Slot vorzubereiten.

Zeitplan aller Vorträge des 2. ZEISS Digital Innovation Online Campus.
Abbildung 2: Insgesamt 29 Vorträge in 6 parallel laufenden Slots wurden zu fachverwandten Themen gehalten.

Nach einer längeren Mittagspause fand unser Online-Teamspiel mit insgesamt 28 Teams bestehend aus jeweils neun bis zehn Teammitgliedern statt. Bei der Teamzusammenstellung wurde auch dieses Mal auf eine möglichst heterogene Gruppenaufteilung hinsichtlich der Reifegrade, Standorte und Geschäftsbereiche geachtet. Zum gegenseitigen Kennenlernen und der anschließenden Lösung der Aufgaben hatte jedes Team einen eigenen virtuellen Teamraum zur Verfügung. Die Aufgaben beinhalteten unter anderem Wissensfragen, Scharade- und Rätselaufgaben sowie die Abstimmung eines weihnachtlichen Teambeitrags, welcher zum Abschluss unseres Online-Campus im Rahmen der gemeinsamen weihnachtlichen Feierstunde von den Teams live aufgeführt werden sollte.

Zum Auftakt der weihnachtlichen Feierstunde wurde zunächst mit leckerem Glühwein und Punsch gemeinsam angestoßen. Im Anschluss waren die jeweiligen Teams mit ihren weihnachtlichen Live-Beiträgen an der Reihe. Von musikalischen und poetischen Darbietungen bis hin zu Weihnachtsgrüßen in verschiedenen Sprachen und weihnachtlichen Filmtipps waren alle Teams kreativ dabei und auch der verfügbare Teams-Chat wurde rege genutzt. Somit kam trotz der Verteilung und damit einhergehenden physischen Distanz eine besinnliche und weihnachtliche Stimmung unter uns auf.

Fazit

Uns allen war bewusst, dass ein Online-Format mit einer virtuellen weihnachtlichen Feierstunde nicht das Gefühl einer real stattfindenden Weihnachtsfeier vor Ort mit Schlittschuhfahren, leckerem Essen, Tanzen und dem lockeren Austausch untereinander ersetzen kann. Dennoch waren wir überrascht, wie viel weihnachtliche Stimmung und Gemeinschaftsgefühl verteilt online entstehen kann. Es hat uns erneut gezeigt, dass wir als starkes Team an einem Strang ziehen und trotz Corona dazu bereit sind, das Beste aus der aktuellen Situation zu machen und gemeinsam neue Wege zu gehen.

Ob wir in diesem Jahr vielleicht wieder mit allen Kolleginnen und Kollegen gemeinsam in Dresden vor Ort ein Sommerfest oder auch eine Weihnachtsfeier veranstalten können, ist ungewiss. Was wir jedoch bereits jetzt prognostizieren können: Unser neues Format des Online-Campus mit dem Online-Teamspiel wird Corona sicherlich überdauern.

Testkostenschätzung – „Handeln wie auf dem Basar?“

Wenn sich ein externer Testdienstleister und der Kunde über den Umfang des nächsten Testprojektes abstimmen, nutzen sie eine Testkostenschätzung. Das Erstellen einer möglichst genauen und von allen Beteiligten akzeptierten Testkostenschätzung stellt aber meist eine Herausforderung dar. Dafür gibt es zwei Gründe – der Zeitpunkt der Erstellung und die festgelegten Parameter zur einzelnen Bewertung von Testszenarien bzw. Testfällen. Die meisten werden sich nun sicher die Frage stellen, wie es mit dieser Problemstellung zu genannter Überschrift gekommen ist. Diese Erkenntnis beruht auf meinen bisherigen Erfahrungen beim Erstellen von früheren Testkostenschätzungen. Dabei kam es immer wieder zu den gleichen Grundsatzdiskussionen und Anpassungen der erstellten Testkostenschätzungen. Darauf wird später noch einmal eingegangen. Zunächst werden die Grundlagen für eine Testkostenschätzung beschrieben. 

Grundlagen der Testkostenschätzung 

Für die Abrechnung von Testdurchführungen durch den Testdienstleister gegenüber dem Auftraggeber gibt es unterschiedliche Varianten. Bisher sind davon zwei in meinen Projekten, in denen ich Testkostenschätzungen erstellt habe, zum Einsatz gekommen: Zum einen über T&M-Basis (time and material), zum anderen über die Komplexität der durchzuführenden Testszenarien. 

Die erste Möglichkeit besteht darin, die Testdienstleistung anhand des Zeit-Aufwandes (Personen-Tage) abzurechnen. Dabei werden die erforderlichen Tage beziehungsweise Stunden und die benötigte Anzahl an Testern für die Testdurchführung geschätzt.  

Da sich diese Art der Testaufwandschätzung meistens auf einen vorgegebenen Zeitraum bezieht, gibt es keine Zuordnung zu bestimmten Szenarien bzw. Testfällen. Daraus ergibt sich, dass diese Schätzung im Allgemeinen durch den Auftraggeber in dem vollen Maße akzeptiert und auch beauftragt wird. 

Handschlag
Abbildung 1: Erfolgreiches Verhandeln

Die zweite Variante, auf welche sich dieser Beitrag bezieht, ist die Abrechnung auf Basis der Testszenarien und des Aufwands über ein Komplexitätsmodell. Dabei werden im ersten Schritt, anhand der durchzuführenden Testaktivitäten, die erforderlichen Testszenarien identifiziert. Im zweiten Schritt werden die zugehörigen Testfälle ermittelt und dem jeweiligen Szenario zugeteilt. Diese Szenarien bilden im besten Fall einen Geschäftsprozess ab und laufen somit über mehrere, im Unternehmen befindliche Systeme. Solch ein Prozess könnte exemplarisch über die folgenden Systeme führen: 

  • Kundenverwaltungssoftware (interne Nutzung durch Auftraggeber) 
  • Dokumentenablage (interne Nutzung durch Auftraggeber) 
  • Abrechnungssoftware (interne Nutzung durch Auftraggeber) 
  • Geräteverwaltung (interne Nutzung durch Auftraggeber) 
  • Kundenportal (externe Nutzung durch Kunden) 
  • Gerätenutzung (externe Nutzung durch Kunden) 
  • zusätzliche Prüfungen in Datenbanken 

Daraus folgt meist, dass unterschiedliche Geschäftsprozesse einen unterschiedlich hohen Aufwand bei der Testdurchführung bedingen. Neben der trivialen Betrachtung des direkten Testaufwandes muss berücksichtigt werden, dass nicht nur die reine Testdurchführung den eigentlichen Aufwand darstellt, sondern bereits die zu erfüllenden Vorbedingungen (z. B. bestimmte Datenkonstellationen) in den Aufwand mit eingerechnet werden müssen. 

Ebenso kann es zu einer höheren Testaktivität kommen, sobald weitere Unterstützung durch den Auftraggeber während der Testdurchführung benötigt wird. Denn aufgrund von Abstimmungen bzw. Verfügbarkeiten der jeweiligen Mitarbeitenden des Unternehmens verlängert sich der zeitliche Aufwand. All diese Aspekte haben einen direkten Einfluss auf den Aufwand der Testdurchführung. 

Komplexität bestimmen 

Um den Aufwand und damit auch den Preis eines Szenarios für die Testdurchführung zu ermitteln, müssen wir die Komplexität der zu erledigenden Testaufgaben bestimmen. Dazu wurden in den vergangenen Projekten unterschiedliche Herangehensweisen genutzt. 

Die erste „einfache“ Variante war die Bestimmung der Komplexität innerhalb von drei Klassen (kleines Szenario, mittleres Szenario oder großes Szenario). Aber auch dort gab es für bestimmte Szenarien mit dem Auftraggeber abgestimmte Ausnahmen, welche mit einem höheren Aufwand beziffert wurden, da zusätzliche externe Dienstleister bei der Testdurchführung beteiligt waren.  

Für eine genauere Bestimmung der Komplexitäten wurde eine ausführlichere Variante mit breiterer Komplexitätskategorie erarbeitet und eingeführt. Diese erweiterte Einteilung reicht von “1” für ein sehr kleines Szenario bis zu “9” für ein sehr aufwendiges Szenario unter Beteiligung von externen Dienstleistern. 

Abstimmung zwischen Auftraggeber und Dienstleister
Abbildung 2: Abstimmung zwischen Auftraggeber und Dienstleister

Zur Bestimmung der Kategorie für ein Szenario wurden die drei folgenden Bereiche innerhalb eines einzelnen Szenarios festgelegt: 

  • Aufwand für Testvorbereitung 
  • Aufwand für Testdurchführung 
  • Aufwand für Testspezifikation 

In diesen drei Bereichen werden jeweils eine gewisse Anzahl an Punkten vergeben, die sich am zeitlichen Aufwand orientieren. Die Summe der gesamten Punkte aus diesen drei Bereichen ergibt mit Hilfe eines Umrechnungsschlüssels die Komplexität eines Szenarios.  

Probleme bei der Testkostenschätzung 

Nachfolgend werden Probleme bei der Testkostenschätzung beschrieben bzw. Gegebenheiten, die dazu führen, dass nach erstellter Schätzung oft ein Handeln um die Kategorien der Szenarien beginnt.  

Aus Sicht des Auftraggebers ist klar, dass es in den meisten Fällen um die Kosten der Testdurchführung geht und diese möglichst geringgehalten werden sollten, ohne den Testumfang zu mindern. 

Da eine Testkostenschätzung zeitlich weit vor der eigentlichen Testdurchführung erstellt werden muss, stehen in den meisten Fällen noch keine genauen Spezifikationen zur Verfügung. Im besten Fall sind bereits erste Versionen von Fachkonzepten vorhanden. Diese verfügen jedoch oft noch nicht über die komplette Systemlandschaft, welche von der Softwareanpassung betroffen ist. Die noch fehlenden Dokumente wirken sich negativ auf die folgenden Punkte aus. 

Bei der Testkostenschätzung wird der Testaufwand eines Szenarios aufgrund der bisherigen Durchführungen ermittelt, bzw. bei neuen Themen geschätzt und entsprechend eingestuft. Da in den einzelnen Bereichen (z. B. Aufwand für Testdurchführung) eine Schätzung auf Grundlage des zeitlichen Aufwandes durchgeführt wird, kommt es immer wieder zu Diskussionen über die geschätzten Zeiten und der damit verbundenen Kategorie eines Szenarios. Der Auftraggeber ist nach dem Prüfen der Schätzung nicht selten der Meinung, dass es möglich ist, die Tests eines Szenarios in kürzerer Zeit durchzuführen. Oft setzt er diese Meinung durch und die Testkostenschätzung wird angepasst – erstes Handeln erfolgreich abgeschlossen.

Diese kleineren Abweichungen können durch erfahrene Tester, welche die beteiligten Systeme in- und auswendig kennen und somit schneller bei der Testdurchführung sind, ausgeglichen werden. Unerfahrene Tester, welche bei einem oder mehreren Systemen innerhalb des Szenarios nicht über das Expertenwissen verfügen, benötigen etwas mehr Zeit, wodurch bereits die erste Diskrepanz zwischen dem geschätzten und dem tatsächlichen Aufwand entsteht. 

Eine weitere Diskrepanz entsteht bei Änderungen an der Software über mehrere Systeme, durch die der Aufwand für das Herstellen der Testvorbedingungen steigt. Dies kann daraus folgen, dass bestimmte Datenkonstellationen nicht mehr ohne Weiteres im Vorsystem erzeugt werden können. Dies geschieht z. B. durch den Wegfall von Schreibrechten auf einer Datenbank. Da in diesem Projekt regelmäßige Softwareanpassungen (halbjährlich) durchgeführt werden, entstehen nach einer gewissen Zeit immer wieder Szenarien, welche den gleichen Geschäftsprozess abbilden. Diese bisherigen Schätzungen werden zum Vergleich herangezogen. Somit werden auch kleinere zusätzliche Aufwände, wie der Mehraufwand beim Herstellen der Testvorbedingungen, in der Kategorie gesenkt. Die Testkostenschätzung wird angepasst – zweites Handeln erfolgreich abgeschlossen

Es kann bei der Testkostenschätzung auch zu dem Punkt kommen, dass ein Szenario in der Kategorie zu gering eingestuft wurde. Dies tritt z. B. bei komplett neuen Funktionalitäten in der Software auf, für die es noch keine Erfahrungswerte gibt. Somit wird es nötig, das Szenario bei der nächsten Schätzung in der höheren Kategorie einzuordnen. Diese Erhöhung der Kategorie wird durch den Auftraggeber geprüft, welcher diesbezüglich kaum Erfahrungswerte besitzt und die vorherige Schätzung als Grundlage verwendet. Die Testkostenschätzung wird in diesem Fall nicht angepasst – drittes Handeln erfolgreich abgeschlossen

Dieses Handeln wird nicht bei jeder Kostenschätzung mit allen Szenarien durchgeführt, kommt aber bei jeder Schätzung mit einzelnen Szenarien immer wieder einmal vor.

Fazit 

Eine Testkostenschätzung auf Grundlage von zeitlichen Aufwänden sollte aus meiner Sicht nur für interne Zwecke beim Testdienstleister zur Ermittlung der Komplexität erfolgen. Denn eine zeitlich abhängige Schätzung für den Aufwand der Testvorbereitung, die Testdurchführung etc. kann nur funktionieren, wenn die einzelnen notwendigen Parameter auch messbar und von beiden Seiten festgelegt sind. Unterschiede ergeben sich bereits bei der Durchführung und Protokollierung von Testfällen durch verschiedene Tester. Der erste Tester protokolliert seine Ergebnisse genauer und mit zusätzlichen Screenshots, wohingegen der zweite Tester mittels Copy & Paste aus dem System die Ergebnisse ausreichend protokolliert. Dadurch kann bereits eine Abweichung von +/- 30 Minuten entstehen. 

Für eine Testkostenschätzung ist es notwendig, Bewertungskriterien heranzuziehen. Diese sollten aber sowohl für den Auftraggeber als auch den Testdienstleister nachvollziehbar und bewertbar sein. Darüber hinaus muss eine gewisse Vertrauensbasis untereinander gegeben sein, damit eine für beide Seiten überzeugende Schätzung erstellt und akzeptiert werden kann. Denn auch wenn manche Schätzungen von einzelnen Szenarien tiefer eingestuft werden, so gibt es wiederum auch solche, die in der Kategorie höher eingestuft sind. Dadurch kann sich die Testkostenschätzung in der Gesamtheit die Waage halten. 

Wenn man einmal eine gemeinsame Basis gefunden hat, erleichtert dies das Arbeiten an einer Testkostenschätzung ungemein. Denn wenn beide Seiten die gleiche Auffassung von dem geschätzten Aufwand vertreten, werden die nachträglichen Anpassungen – das “Handeln wie auf dem Basar” – zum Großteil minimiert.