Über unsMediaKontaktImpressum
Rudolf Grötz & Benjamin Hofmann 10. Januar 2017

DevOps – Testautomation I – Infrastructure as Code

Viele Unternehmen haben ihren Softwareentwicklungs-Prozess agil ausgerichtet, um Releases schneller und hochwertiger produktiv zu setzen, sprich, die "Time to Market" zu reduzieren. Denn noch immer gilt die Regel: nur Software, die vom Kunden genutzt werden kann, bringt dem Unternehmen Geld. Um dieses Vorhaben zu unterstützen, setzen immer mehr Unternehmen auf Continuous Delivery und DevOps.

Dieser zweiteilige Beitrag befasst sich mit der Notwendigkeit einer durchgehenden Testautomation in einer Continuous Deployment-Pipeline (Abb. 1) um erfolgreiche kontinuierliche Auslieferung in das Produktionssystem zu gewährleisten. Es wird erklärt, welche Werkzeuge, Frameworks und technische Ansätze möglich sind, um in vollem Umfang von automatisierten Tests profitieren zu können. Teil 1 behandelt die Testautomation von Applikationsumgebungen (Infrastructure as Code), Teil 2 beschäftigt sich mit der Testautomation von Webapplikationen & Mobile Device Clouds.

Was ist DevOps?

"DevOps is a software development method that emphasizes communication, collaboration (information sharing and web service usage), integration, automation, and measurement of cooperation between software developers and other IT professionals…
… The specific goals of a DevOps approach span the entire deployment pipeline. They include improved deployment frequency, which can lead to faster time to market, lower failure rate of new releases, shortened lead time between fixes, and faster mean time to recovery...
" [1]

Ein kritischer Erfolgsfaktor ist dabei die durchgängige Automatisierung. Doch obwohl viele Unternehmen Releasemanagement, Lieferung und Bereitstellung automatisiert haben, ignorieren einige noch immer die Bedeutung von automatisierten Tests als Teil der DevOps-Werkzeuge.

Deployment-Pipeline

"One of the challenges of an automated build and test environment is you want your build to be fast, so that you can get fast feedback, but comprehensive tests take a long time to run. A deployment pipeline is a way to deal with this by breaking up your build into stages. Each stage provides increasing confidence, usually at the cost of extra time. Early stages can find most problems yielding faster feedback, while later stages provide slower and more through probing. Deployment pipelines are a central part of Continuous Delivery" (Martin Fowler [2])

Testframeworks in der Pipeline

Im Prinzip kann jedes Test-Framework für die Ausführung der Tests verwendet werden. Um aber den wahren DevOps-Gedanken hoch zu halten, sollte eines gewählt werden, dass von allen Teams in der gleichen Art und Weise benutzt werden kann, alle Arten von Teststages unterstützt und leicht in die Continuous Deployment-Pipeline integriert werden kann. In diesem Fall ist einem Framework, das die natürliche Sprache unterstützt, der Vorzug zu geben, weil die natürliche Sprache die Erstellung und Wartung der Tests erleichtert.

Continuous Testing & Testautomation

Continuous Testing mit dem grundlegenden Gedanken "fail early and fail often", ist aus der  agilen Welt nicht mehr wegzudenken. Das Aufkommen von agilen Entwicklungsprozessen und dem DevOps-Gedanken, bei dem die Dauer der Build-Erstellung, das Testen und das Bereitstellen auf Minuten oder Stunden reduziert wurde, hat die Entwicklung und Einführung von Automatisierung-Werkzeugen beschleunigt. An Testautomatisierung führt kein Weg mehr vorbei, um eine angemessene Menge an Tests permanent auf jedem Build und in jeder Stage der Pipeline zu gewährleisten.

Ein wichtiger Aspekt ist dabei nicht nur, den Code der Applikation automatisiert zu testen. Auch der Infrastructure Code der Laufzeitumgebung muss beim Test berücksichtigt werden. Ein durchgängiger Testautomationsansatz für beide Codeteile schafft Sicherheit, dass, wenn alle automatisierten Tests erfolgreich waren, der Code (das Produkt) ausgeliefert werden kann.

Viel Teams scheitern mit der Automatisierung, da der Aufwand für die Einführung und die Wartung zu groß ist und auch nicht die notwendigen Skills zum Betrieb eines durchgängigen Testautomationsprozesses vorhanden sind. Um jedoch von automatisierten Tests  zu profitieren, ist es wichtig, das richtige Werkzeug, den richtigen Rahmen und die richtige technische Lösung zu verwenden.

Infrastructure as Code (IaC)

Infrastructure as Code erlaubt es Organisationen, dem Zeitdruck gerecht zu werden, unter dem Applikationsumgebungen bereitgestellt und konfiguriert werden müssen. IaC ist die Instanzierung von vordefinierten Umgebungen (Nodes), die in einem Softwarerepository (z. B. GIT[3]) in Form von Konfigurationen, Topologien, Rollen, Beziehungen und Richtlinien beschrieben sind. Bei IaC wird die Konfiguration von Systemen in der gleichen Art und Weise wie Applikationscode behandelt.

Eine wichtige Rolle spielen bei diesem Ansatz Werkzeuge, mit denen sich die Bereitstellung von Applikationsumgebungen automatisieren lässt. Diese ermöglichen, einmal definierte Konfigurationen (IaC) beliebig zu reproduzieren und weiterzuentwickeln. Zu diesen Werkzeugen gehören u. a. Vagrant[4], Puppet[5], Chef[6] und Docker[7].

Übersicht CHEF

Chef ist eine leistungsfähige Automatisierungsplattform, die komplexe Systemkonfigurationen (Infrastructure as Code) in Code transformiert, Server und notwendige Dienste hochfährt und damit die Laufzeitumgebung zum Leben erweckt. Egal ob in der Cloud, On-Premise oder eine Mischform. Chef ist einfach konzipiert: Automatische Erreichung des gewünschten Systemzustands, zentrale Modellierung von IT-Infrastruktur und Ressourcengrundelemente, die als Bausteine für die weitere Verwendung dienen. In Chef-Terminologie wird die Automatisierungslogik als Chef-Rezept geschrieben. Ein Chef-Kochbuch verwendet Rezepte und verwandte Pakete. Folgend dem deklarativen Paradigma, beschreibt ein Rezept eine Reihe von Ressourcen (Web-Server, Applikation-Server, ...) die einen bestimmten Zustand aufweisen sollten.

Der gewünschte Systemzustand einer Applikationsumgebung kann deklarativ beschrieben und via Konfigurationsläufe erstellt werden. Zum Beispiel kann beschrieben werden, dass ein Softwarepaket installiert sein muss, ohne die betriebssystemspezifische Vorgehensweise beschreiben zu müssen.

Diese Konfigurationsläufe sind idempotent, eine mehrfache Ausführung führt also immer zum gleichen Ergebnis. Listing 1 zeigt ein Beispiel für ein Chef-Rezept das folgenden Status für die Applikationsumgebung gewährleisten soll:

  • Verzeichnis /tmp/tomcat6 muss mit den definierten Rechten existieren
  • Package "tomcat6" muss installiert sein
  • Service  "tomcat6" muss beim Systemstart gestartet werden

Listing 1: Chef-Rezept

directory "tmp/tomcat6" do
   action :create
end

package "tomcat6" do
   action :install
end

service "tomcat6" do
   service_name "tomcat6"
   action :start
end

Infrastruktur-Code in Form von Chef-Modulen (o. ä.), muss im Hinblick auf Qualität und Wartbarkeit der gleiche Stellenwert eingeräumt werden wie dem Anwendungscode, da die Applikationsumgebung das Zielsystem ebenso ausmacht wie die Applikation selbst.

Testautomation für Infrastructure as Code

Eine große Herausforderung beim Einsatz von Infrastructure as Code ist die Art und Weise, wie getestet wird. Da bisher kein angemessener Testautomationsansatz vorhanden war, wurde das Setup manuell getestet. Also remote anmelden, verschiedene Befehle manuell ausführen und das System überprüfen. Ein großer Nachteil bei diesem Verfahren ist, dass eine Liste aller zu überprüfender Services vorliegen und gepflegt werden muss. Eine Skalierung ist somit ein schweres Unterfangen. Mit der Entwicklung von Testframeworks wie rSpec-Puppet[8] und ServerSpec[9] ist das Testen ein Kinderspiel geworden. 

"With Serverspec, you can write RSpec tests for checking your servers are configured correctly. Serverspec tests your servers' actual state by executing command locally, via SSH, via WinRM, via Docker API and so on. So you don't need to install any agent softwares on your servers and can use any configuration management tools, Puppet, Ansible, CFEngine, Itamae and so on" [9]

Im Nachfolgendem zeigen wir ein Beispiel mit dem ServerSpec-Framework, wobei eine ausführliche Einführung in das Framework diesen Artikel sprengen würde. Wir beschränken uns darauf, das oben angeführte Chef-Rezept in einem Testbeispiel zu behandeln.

Testfall – TomcatShouldBeInstalled

In unserem Test (Listing 2) wird geprüft, ob Tomcat, so wie im Chef-Rezept beschrieben, in der Applikationsumgebung installiert ist.

Listing 2 – ServerSpec-Testfall

describe file('tmp/tomcat6') do
   it { should be_directory }
end

describe package('tomcat6') do
   it { should be_installed }?
end

describe process('tomcat6') do
   it { should be_running }?
end

Resource Types

Mit Serverspec gibt es einen eleganten Weg, um das Vorhanden- und Verfügbarsein spezifischer Ressourcen innerhalb eines Testschrittes (Describe Block) zu überprüfen.

Die Prüfung innerhalb eines Testschrittes erfolgt mit Resource Types, welche sogenannte Matcher zur Verfügung stellen, die bestimmte Eigenschaften des Resource Types auf Wahr oder Falsch prüfen.

Resource Types / Matcher

File (Datei und Verzeichnis)

  • Exist - prüft, ob "File" existiert
  • Be_directory - prüft, ob "File" ein Verzeichnis ist.
  • Contains - prüft, ob "File" einen bestimmten Text aufweist.

Package (Software Packages)

  • Be_installed - prüft, ob "Package" installiert ist

Service (Set von Softwarefunktionalität)

  • Be_enabled - prüft, ob "Service" vorhanden ist.
  • Be_installed - prüft, ob "Service" installiert ist.
  • Be_running - prüft, ob "Service" läuft.

Ausführung via rake

Ausgeführt wird der erste automatisierte Test mit dem Rake-Befehl:

$ rake spec

Das Testergebnis:

Finished in 0.42151 seconds
  3 examples, 0 failures

Zusammenfassung

Unternehmen müssen ihren Softwareentwicklungs-Prozess agil ausrichten, um Releases schneller und qualitativ hochwertiger ausliefern zu können. Um dieser Anforderung gerecht zu werden, setzen immer mehr Unternehmen auf DevOps und Continuous Delivery.

Continuous Delivery ohne automatisierte Tests ist aber nur die Hälfte wert. Testautomation ist  eine oft unterschätzte Disziplin und wird stiefmütterlich behandelt. Um die enge Zusammenarbeit von Produktmanagement, Operations, Developement und Testern zu unterstützen, sollten BDD-Frameworks zum Einsatz kommen, die es ermöglichen, Tests in natürlicher Sprache zu spezifizieren.

Testautomation muss aber neben dem Applikationscode auch den Code der Applikationsumgebung abdecken. Mit Testframeworks wie ServerSpec ist dieses ein Leichtes – es muss nur gemacht werden.

Autoren

Rudolf Grötz

Rudolf Grötz ist Engineering Manager bei CISCO ServiceGrid Austria und versucht, als Head of Test Engineering die richtige Dosierung zu finden, um Software-Tests "agile" und wirtschaftlich vertretbar, erfolgreich zu machen.
>> Weiterlesen

Benjamin Hofmann

Benjamin Hofman ist Senior Test Engineer bei MaibornWolff GmbH in München. Nach Abschluss seiner Ausbildung am Technikum Wien sammelte er bei Audi und Jumio Inc. seine erste Erfahrung im Bereich Software-Test und Automatisierung.
>> Weiterlesen
Das könnte Sie auch interessieren
Kommentare (0)

Neuen Kommentar schreiben