Continuous-Integration-Pipeline

In agilen Entwicklungsumgebungen verbreitete Praktiken wie Continuous Integration (CI), Continuous Deployment (CD) und DevOps haben alle ein Ziel: kleine, häufige Releases von hochqualitativer, auslieferungsfähiger Software.
Damit dabei auch die Qualitätssicherung Schritt halten kann, sind integrierte automatisierte Tests unabdingbar – ganz egal, ob Sie Ihren Entwicklungszyklus in Tagen oder Wochen messen.

Automatisierte Tests in einer CI-Pipeline

Das untenstehende Bild veranschaulicht eine typische CI-Pipeline. Ein Entwickler checkt Code aus dem gemeinsamen Repository des Version Control Systems (VCS) aus (z.B. Git, TFS oder Subversion) aus. Wenn seine Arbeiten am Code abgeschlossen sind, führt der Entwickler einen Commit mit seinen Änderungen im VCS durch und löst so einen CI-Job aus. Der CI-Server baut nun automatisch die AUT und löst die automatisierten Tests aus, um zu überprüfen, ob der Build auch mit den Codeänderungen „green“ ist, also funktioniert. Die Testergebnisse werden an das gesamte Team weitergeleitet, das dann eine Entscheidung bezüglich Deployment treffen kann. In einer CD-Umgebung wird der Build automatisch in die Produktivumgebung deployt.

Beispiel für eine CI-Pipeline

Continuous Integration mit automatisierten Tests bietet mehrere Vorteile für Unternehmen:

  • Entwickler bekommen Feedback in Bezug auf Qualität, Funktionalität und Systemeinfluss ihrer Codeänderungen schnell und zu einem Zeitpunkt, wo die Defektbehebung noch einfacher und günstiger ist.
  • Durch die stetige Integration kleiner Änderungen treten weniger Merge-Konflikte durch die Arbeit am selben Code auf. Und solche, die auftreten, sind einfacher zu lösen.
  • Der Status des Builds ist für jedes Teammitglied klar ersichtlich.
  • Es steht jederzeit ein „good Build“ der Anwendung zu Test-, Demonstrations- oder Releasezwecken zur Verfügung.

Empfehlungen für automatisierte Tests in CI-Pipelines

Die folgenden Empfehlungen haben die Testautomatisierung in CI-Pipelines zum Fokus, überlappen sich aber zum Teil mit allgemeinen Best Practices für den CI-Prozess selbst. Mehr Best Practices für den CI-Prozess finden Sie im Wikipedia-Artikel zu Continuous Integration.

Icon unit testing

Nicht nur auf Unittests verlassen

Unittests in der Codeumgebung eines einzelnen Entwicklers haben nicht genug Aussagekraft darüber, wie sich der Code bei Integration in die Anwendung verhalten wird. Der neue oder überarbeitete Code kann dann den Build fehlschlagen lassen. Beispielsweise können Änderungen eines Entwicklers einen Konflikt mit denen eines anderen auslösen. Auch Unterschieden zwischen der Codeumgebung des Entwicklers und der Produktivumgebung können zu fehlerhaften Builds führen. Deswegen ist es wichtig, Integrations- und Regressionstests ebenso durchzuführen. Auch funktionale UI-Tests mit hoher Priorität sollten schon im Buildprozess integriert sein.
Icon self-testing build

Selbsttestende Builds

Komponententests überprüfen einzelne Codeeinheiten. Diese Tests werden oft auch Unittests genannt, werden aber auch als Modul- oder Programmtests bezeichnet. Entwickler schreiben und führen Unittests aus, um Defekte in ihrem Code so früh wie möglich im Entwicklungsprozess zu finden und zu beheben. In agilen Umgebungen ist das essentiell, da nur durch schnelles Feedback kurze Releasezyklen eingehalten werden können. Unittests sind sogenannte White-Box-Tests, da man den Code kennt, für den man sie schreibt.
Icon refactor automated test

Refactoring von automatisierten Tests

Builds, die lange zur Fertigstellung benötigen, unterbrechen den CI-Prozess. Um Ihre Tests effizient zu halten, sollten Sie sie daher wie den Anwendungscode selbst behandeln. Prüfen Sie sie regelmäßig auf eliminierbare Redundanzen, wie mehrere Tests, die dasselbe Feature abdecken, oder datengetriebene Tests, die Wiederholungen in den Daten aufweisen. Techniken wie Grenzwertanalyse und Äquivalenzklassenbildung können dabei helfen, Ihre datengetriebenen Tests auf die wesentlichen Fälle zu reduzieren.
Icon stopwatch

Schnelle Builds

Es ist essentiell, dass Builds so schnell wie möglich nach Auslösen fertiggestellt werden, da Entwickler sonst davon abgehalten werden könnten, neuen Code zu committen. Daher sollten bei jedem Build nur jene automatisierten Tests durchgeführt werden, die zur Validierung des Builds absolut notwendig sind. Aufgrund ihrer größeren Komplexität sind Integrationstests gewöhnlich langsamer als Unittests. Führen Sie zuerst Ihre Smoke- und Sanity-Tests aus, um zügig zu überprüfen, ob der Build fehlerhaft ist, bevor weiterer Testaufwand betrieben wird. Wenn Ihr Team häufig neuen Code committet, kann es sinnvoll sein, Integrationstests nur für den täglichen Build durchzuführen anstatt für jeden neuen Commit. Führen Sie einen kompletten Regressionstestlauf nur als Vorbereitung auf ein Deployment in die Produktivumgebung durch. In Ranorex Studio können Sie das mithilfe sogenannter Run Configurations lösen. Sie erlauben es Ihnen, nur gewisse Tests einer größeren Suite auszuführen, wie z.B. Smoke-Tests oder Tests für ein bestimmtes Feature, das sich verändert hat. Regressionstests, die geringe Priorität haben und seit mehreren Testzyklen keine Fehler aufgewiesen haben, sollten Sie aus Ihren Buildtests entfernen.

Icon source control

Source Control für automatisierte Tests

Verwalten Sie Ihre Tests im selben Repository wie Ihren Code. Das macht es einfacher, einen Tests der passenden Version des Sourcecodes zuzuordnen. Ranorex Studio bietet Integrationen für beliebte VCS wie Git, Microsoft Team Foundation Server und Subversion.
Icon test environment

In der richtigen Umgebung testen

Stellen Sie sicher, dass Ihre Testumgebung stabil ist und z.B. nicht durch eine inkorrekte Version des Betriebssystems oder fehlende Dienste unnötig Tests fehlschlagen. Im Idealfall setzen Sie eine isolierte Testplattform auf, die nur für Tests  verwendet wird. Ihre Testumgebung sollte Ihrer Produktivumgebung so ähnlich wie möglich sein, was allerdings sehr schwierig umzusetzen sein kann. Es kann dann realistischer sein, gewisse Abhängigkeiten wie Drittanwendungen zu virtualisieren. Bei komplexen Umgebungen kann eine Containervirtualisierung (z.B. mit Docker) eine effiziente Lösung zur Reproduktion der Produktivumgebung darstellen.

Icon parallel testing

Parallel testen

Wie bereits erwähnt ist Schnelligkeit eine essentielle Metrik in CI-/CD-Umgebungen. Sparen Sie Zeit, indem Sie Ihre automatisierten Tests auf einem Selenium-Grid verteilen oder sie parallel auf mehreren virtuellen oder physischen Maschinen ausführen. Um dies zu ermöglichen, sollten Sie Ihre Tests so modular und voneinander unabhängig wie möglich aufbauen, wie bereits in einem früheren Artikel dieser Serie erwähnt.
Icon functional UI testing

Funktionale UI-Tests und exploratives Testen einbinden

Um zu prüfen, ob Ihre Anwendung wirklich bereit zum Deployment in die Produktivumgebung ist, sind mehrere verschiedene Arten automatisierter Tests nötig. Zusätzlich zu Ihren automatisierten Unit- und Integrationstests sollten Sie auch UI-Tests durchführen, um Grundfunktionalitäten, typische Nutzungswege durch die Anwendung und komplexe Workflows lückenlos zu testen. Exploratives Testen dient abschließend dazu, Defekte aufzudecken, die automatisierten Tests entgehen.

Icon verify deployment

Den deployten Build prüfen

Nach Deployment des Builds in die Produktivumgebung sollten Sie noch einmal die Smoke-Tests durchführen, um kurz zu überprüfen, ob alles ordnungsgemäß funktioniert hat.
  Um mehr darüber zu erfahren, wie Sie in Ranorex Studio erstellte Tests in Ihre CI-Pipeline integrieren, lesen Sie unseren Blogartikel Integrate Automated Testing into Jenkins. Obwohl der Artikel Jenkins behandelt, können Ranorex-Studio-Tests natürlich von allen CI-Prozessen ausgelöst werden.

Steigen Sie direkt in die Testautomatisierung ein mit unserer kostenlosen 30-tägigen Testversion: