In diesem Artikel werde ich über Softwaretests sprechen, die auf Systemebene durchgeführt werden können. Diese Tests sind ein wesentliches Glied in der kontinuierlichen Integrationskette, sie können funktionsfähig sein oder auch nicht, und sie weisen sehr spezifische Merkmale auf. Ich werde die zu befolgenden bewährten Methoden und Implementierungsprobleme anhand des Beispiels von Systemtests einer API erörtern. Sehen wir uns also an, was die Teststufen sind und was wir einen Systemtest nennen.

Die Teststufen 

In Übereinstimmung mit den Empfehlungen des ISTQB (International Software Testing Qualification Board) werden Softwaretests in verschiedene Stufen eingeteilt. Hier sind die traditionellen Teststufen, die in der klassischen Testpyramide zu finden sind: 

Pyramid of the traditional system tests
  • Komponententests: diese Tests zielen darauf ab, jede Codeeinheit zu validieren, indem sie isoliert wird (mit Stubs, Mocks oder Fälschungen …).
  • Integrationstests: diese Tests konzentrieren sich auf Kommunikation oder den Nachrichtenaustausch zwischen verschiedenen Codeeinheiten.
  • Systemtests: diese Tests stellen sicher, dass die verschiedenen Aspekte eines kompletten Softwaresystems den Anforderungen entsprechen.
  • Akzeptanztests: diese Tests zielen darauf ab, die Akzeptanz des Systems als Ganzes durch den Kunden, Anwender oder Vertreter zu erhalten.

Da unsere Softwarelösung bei AT Internet sehr umfangreich und komplex ist, haben wir uns entschieden, zwei Teststufen hinzuzufügen:

Pyramid of At Internet system tests
  • Systemintegrationstests: diese Tests konzentrieren sich auf den Austausch zwischen verschiedenen Systemen, aus denen unsere Lösung besteht.
  • Lösungstests: diese Tests bestätigen das ordnungsgemäße Funktionieren unserer Lösung, die aus verschiedenen Systemen besteht.

Die Systemtests

Diese „System“-Tests sind die erste Stufe der sogenannten „Black Box“-Tests, d. h. sie werden auf der Grundlage der Produktspezifikationen (Geschäftsregeln, Leistungsanforderungen usw.) ohne Zugriff auf den Quellcode definiert. Die sogenannten „White Box“-Tests hingegen werden auf der Grundlage der internen Struktur des Produkts (Architektur, Code, Codeteile usw.) definiert.

Black box and white box tests

Diese Tests müssen völlig unabhängig von der internen Struktur des Systems sein (Sprache und verwendete Technologien, Implementierungsdetails usw.). Sie müssen sich einfach auf die Ein- und Ausgänge des Systems konzentrieren und es völlig objektiv beobachten. Das macht sie leistungsstark und nützlich: Sie ermöglichen es dann, einen Beruf oder Verhaltensweisen zu validieren, die für den Kunden direkt wahrnehmbar sind.

Systemtests sind bei der Änderung der internen Struktur des Systems (Umgestaltung, Austausch interner Komponenten, Hinzufügen von Funktionalitäten usw.) von wesentlicher Bedeutung: Sie stellen sicher, dass diese Änderungen nicht zu Nebenwirkungen (Regressionen) für die Kunden führen.

In Agility haben wir keine andere Möglichkeit, als diese Tests zu automatisieren, da kontinuierliche Integration durch längere Bereitstellungszeiten aufgrund manueller (potenziell endloser) Testphasen beeinträchtigt wird. Ich werde mich hier daher nur mit automatisierten Systemtests befassen.

Während Komponenten- und Integrationstests unerlässlich sind und so weit wie möglich bereitgestellt werden müssen, ist es wichtig, in Tests auf Systemebene zu investieren, um sicherzustellen, dass das gewünschte Geschäft an den Kunden geliefert wird.

Jeder Geschäftsstein kann in der Tat genau das tun, wofür er ausgelegt ist, aber der Zusammenbau der einzelnen Steine kann mitunter zu eigenartigem Verhalten führen. Andererseits kann die Aufgabe erfüllt werden, während sich Teile des Systems mitunter in einem schlechten Zustand befinden, was noch seltener ist.

Systemtests sind die ersten Tests, die direkt mit den Abnahmekriterien des Kunden im Testprozess zusammenhängen. Diese Tests, wenn automatisiert, ermöglichen es, mögliche Regressionen so früh wie möglich zu erkennen, sonst besteht die Gefahr unangenehmer Überraschungen in späteren Projektphasen: wenn das System in die Gesamtlösung integriert ist oder schlimmer, beim Kunden oder einem seiner Vertreter (z. B. Product Owner).

Es ist dann viel teurer, die festgestellten Probleme zu beheben, und das Risiko, dass sich die Auslieferung des Projekts verzögert, ist viel größer.

Es ist nicht immer einfach, die Ressourcen zu finden, um diese Art von Test einzurichten und zu automatisieren: Es erfordert mehrere Fähigkeiten, sowohl in der Testplanung als auch in der Automatisierungsentwicklung, und wir haben nicht immer das Glück, einen Testentwickler im Team zu haben. In einigen Fällen werden Produktentwickler aufgefordert, einige dieser Implementierungen durchzuführen.

Testen ist sicherlich Teil der Entwicklungsaktivitäten, und die Verantwortung für die Bereitstellung eines Produkts, das funktioniert, ist die des gesamten Teams?

Wie sieht es beim Testen eines Systems aus?

Diagram of a system with in and out

Um ein System richtig testen zu können, müssen Sie zunächst verschiedene Aspekte unseres Systems verstehen:

Die Systemeinträge

All dies sind Auslöser für das Systemverhalten. Wir denken oft an Benutzeraktionen als offensichtliche Auslöser, aber es kann viele andere Auslöser geben. Hier einige Beispiele:

  • Eine Benutzeraktion
  • Empfang von Benachrichtigungen
  • Eine Änderung des Systemstatus
  • Die Verstrichene Zeit (ja, dies kann Aktionen auslösen und es passiert sogar sehr oft: Synchronisationsmechanismen, Aufgabenplanung usw.)

Die Systemausgänge

Wir denken hier oft an die Antwort, die dem Benutzer gegeben wird, aber es gibt andere sehr übliche Ausgaben, an die wir nicht immer denken. Ein Beispiel:

  • Die Antwort an den Benutzer
  • Protokollschreiben (Protokolle)
  • Schreiben von Daten in eine Datenbank
  • Die Ausstellung einer Benachrichtigung

Erwartete Verhaltensweisen (oder Geschäftsregeln)

Wir wissen jetzt, wie man das System aktiviert, indem man mit seinen verschiedenen Eingängen spielt. Wir wissen auch, was wir beobachten können, wenn wir uns die verschiedenen Ausgänge ansehen. Wir müssen dann die Beziehungen zwischen Ein- und Ausgängen kennen. Diese Beziehungen werden als Systemgeschäftsregeln beschrieben und können unterschiedliche Formen annehmen: vom Akzeptanzkriterium einer User Story in Agility bis hin zu detaillierteren Spezifikationen in anderen Kontexten.

Diese mehr oder weniger formal beschriebenen Verhaltensweisen werden direkt verwendet, um die verschiedenen Testfälle zu beschreiben, die die Rolle von Systemtests übernehmen werden.

Ausführungskontexte

Einige Systemverhalten hängen nicht nur von den empfangenen Eingängen ab, sondern auch vom Kontext, in dem sich das System zum Zeitpunkt des Tests befindet.

Nehmen wir das Beispiel eines Aufrufs einer API, um neue Informationen im System aufzuzeichnen. Wir haben dann zwei Fälle mit unterschiedlichen denkbaren Verhaltensweisen:

  • Die Informationen sind bereits im System vorhanden:
    • Wir speichern beide Informationen
    • Wir aktualisieren bestehende Informationen
    • Wir speichern die Historie der Informationswerte
    • Wir lösen einen Fehler aus
  • Die Informationen sind noch nicht verfügbar
    • Wir erfassen die erhaltenen Informationen
    • Wir machen keine Behandlung
    • Wir lösen einen Fehler aus

In beiden Situationen hat der Ausführungskontext direkten Einfluss auf das erwartete Verhalten des Systems.  Hier gewinnt das Test-Dataset an Bedeutung: Wir erzeugen den Kontext, in dem wir vor jedem Test stehen wollen, um die verschiedenen Verhaltensweisen unseres Systems zu validieren. Wir haben dann eine Reihe von Kombinationen all dieser Elemente, die unsere Testfälle bilden werden:

  • Ein Testdatensatz
  • Ein oder mehrere Eingänge zum „Aktivieren“
  • Erwartetes Verhalten
  • Ein oder mehrere zu steuernde Ausgänge

Systemtests können dann implementiert werden. Dies erfordert die Implementierung eines Testmechanismus, der in der Lage sein muss, die Systemeingänge zu beeinflussen und die Gültigkeit seines Verhaltens durch Beobachtung seiner verschiedenen Ausgänge zu kontrollieren:

Test mechanic of the system monitoring

Je nach Fall wird dieser Testmechanismus direkt in Tools auf dem Markt zur Verfügung gestellt, je nach dem zu testenden System:

  • API-Tests: SOAP UI, supertest, Postman, usw.
  • Schnittstellentests: Selenium, Cypress, NightwatchJS, usw.

In anderen Fällen wird es notwendig sein, einen Mechanismus zu implementieren, der an Ihre Bedürfnisse angepasst ist, der es Ihnen ermöglichen muss, mit den verschiedenen Ein- und Ausgängen des zu testenden Systems zu spielen:

  • Lesen/Schreiben in einem Kafka-Thema
  • Senden/Abrufen von Benachrichtigungen
  • Einfügen von Daten in Datenbanken
  • Empfangen von E-Mails
  • usw.

Hier zeigt sich, dass das Testtool nicht mit der im zu testenden System verwendeten Technologie verknüpft ist. Es ist oft sehr unterschiedlich und hängt nicht mit den Anforderungen an die Informationsverarbeitung des Systems zusammen, sondern mit den Einschränkungen, die dem/den Mandanten des Systems auferlegt werden.

Nicht-funktionale Aspekte wie Performance oder Belastbarkeit können auch in Systemtests getestet werden, je nach Bedarf mit unterschiedlichen Techniken und Tools.

Testen einer API

Nehmen wir das konkrete Beispiel einer API als zu testendes System. Die wichtigsten Klassiker der SPS-Validierung sind (in der Reihenfolge, in der das System sie überprüfen muss):

  • Die Nutzungsrechte dieser API
    • Ein nicht autorisierter Aufruf kann sofort abgelehnt werden, unabhängig von seiner Gültigkeit
  • Parametervalidierung
    • Das Fehlen verbindlicher Parameter
    • Die Gültigkeit der empfangenen Parameterkombination
      • Einige Parameter sind manchmal inkompatibel und sollten nicht im selben Aufruf übergeben werden.
    • Das Format der einzelnen Parameter
      • Typ, Muster, zulässige Werte,…
    • Die Konsistenz der für verschiedene Parameter empfangenen Werte
      • Beispielsweise kann das Empfangen einer Sortieranforderung für ein unerwünschtes Feld manchmal abgelehnt werden.
  • Relevanz im Zusammenhang mit dem Geschäft des Systems
    • Dazu gehört die Validierung der Geschäftsregeln des Systems selbst. Beispielsweise kann eine Informationsanforderung (GET) für eine nicht vorhandene Eigenschaft einen Fehler auslösen, das Einfügen eines Datensatzes in die Datenbank über die API löst den Empfang ihrer Kennung im Gegenzug aus usw.

Diese Vorgänge werden für das System immer kostspieliger, das versuchen muss, einen Fehler so schnell wie möglich zu melden, wenn dieser relevant ist, ohne die nächsten Schritte einzuleiten, ansonsten würde unnötige Belastung der Server erzeugt und dadurch nicht-funktionale Aspekte des Systems oder sogar seiner Sicherheit verändert.

Für die Gestaltung dieser verschiedenen Tests können unterschiedliche Konstruktionstechniken verwendet werden, einschließlich Grenzwertanalyse, Äquivalenzklassen, Zustandstransitionen, Entscheidungstabellen usw.

Leistungs- oder Sicherheitstests können mit verschiedenen Tools wie LOAD UI, Gatling, JMeter, Neoload usw. durchgeführt werden. In dieser Art von Test finden wir bekannte Techniken wie:

  • Injektionstests
  • Fuzz-Tests
  • Hämmern
  • Allmählicher Anstieg der Last

Zusammenfassung

Ich hoffe, ich konnte Sie über diese Ebene der Tests, ihre Bedeutung und wie Sie das Beste daraus machen können, aufklären. Es ist auch wichtig zu bedenken, dass Test, Design und Implementierung immer von Ihrem Kontext abhängen, und „Best Practices“ müssen kontinuierlich analysiert, neu gestaltet und interpretiert werden, um sie optimal auf Ihre Projekte anzuwenden.

In diesem Sinne investieren wir bei AT Internet in die Implementierung automatisierter Systemtests, entsprechend den Bedürfnissen jedes Projekts und unter Berücksichtigung des Kontextes jedes Teams. Wir fokussieren unsere Investitionen nach unserer Teststrategie mit dem Ziel, die höchste Qualität unserer Produkte zum Nutzen unserer Kunden zu gewährleisten.

Im nächsten Artikel werde ich 10 Fallstricke besprechen, die beim Einrichten von Systemtests zu vermeiden sind.

Ausgewählte Bildnachweise: Markus Spiske

Author

Mit über 10 Jahren Erfahrung mit Software-Testing-Strategie und Implementierungen in einem agilen Umfeld ist Alexandre dafür verantwortlich die Entwicklungen bei AT Internet voranzutreiben. Seine tägliche Herausforderung: Unsere Entwicklungsteams bei der Implementierung von Tools und Methoden anzuleiten. Das Ziel ist es regelmäßige Veröffentlichungen mit hoher Qualität für unsere Kunden zu garantieren.

Comments are closed.