Modultest

Modultest

In der Softwareentwicklung wird ein Computerprogramm üblicherweise in einzelne Teile mit klar definierten Schnittstellen, sogenannte Module, unterteilt. Der Modultest (auch Komponententest oder oft vom engl. unit test als Unittest bezeichnet) ist der Softwaretest dieser Programmteile, die zu einem späteren Zeitpunkt zusammengefügt (integriert) werden (vgl. Integrationstest). Ziel des Modultests ist es, frühzeitig Programmfehler in den Modulen einer Software (z. B. von einzelnen Klassen) zu finden. Die Funktionalität der Module kann so meist einfacher getestet werden, als wenn die Module bereits integriert sind, da in diesem Fall die Abhängigkeit der Einzelmodule mit in Betracht gezogen werden muss.

Inhaltsverzeichnis

Automatisierte Modultests

Mit der Verbreitung von agilen Softwareentwicklungsmethoden und insbesondere testgetriebener Entwicklung hat sich die Ansicht verbreitet, Modultests ausschließlich automatisiert durchzuführen. Dazu werden üblicherweise mit Hilfe sogenannter Test Frameworks wie beispielsweise JUnit Testprogramme geschrieben, welche die zu testenden Module, in der Regel etwa eine Methode oder eine Funktion, aufrufen und auf korrekte Funktionsweise testen.

Die automatisierten Modultests haben den Vorteil, dass sie rasch und von jedermann ausgeführt werden können. Somit besteht die Möglichkeit, nach jeder Programmänderung durch Ablauf aller Modultests nach Programmfehlern zu suchen. Dies wird üblicherweise empfohlen, da damit etwaige neu entstandene Fehler schnell entdeckt und somit kostengünstig behoben werden können. Dies setzt allerdings voraus, dass die Modultests vor Programmänderungen 100% durchlaufen, also Entwickler nur dann ihren Sourcecode einchecken, wenn alle Modultests erfolgreich durchlaufen.

Eigenschaften von Modultests

Isoliert
Modultests testen die Module isoliert, d. h. ohne die Interaktion der Module mit anderen. Ist das nicht der Fall spricht man nicht von Modultests, sondern von Integrationstests. Dazu müssen andere Module beziehungsweise externe Komponenten wie etwa eine Datenbank, Dateien oder Backendsysteme, die von dem Modul verwendet werden, simuliert (engl. to mock) werden. Diese Module nennt man Mock-Objekte. Auch dafür verwendet man üblicherweise Frameworks wie beispielsweise Easymock.
Test von Fehlverhalten
Modultests testen ausdrücklich nicht nur das Verhalten des Moduls im Gutfall, beispielsweise bei korrekten Eingabewerten, sondern auch im Fehlerfall, beispielsweise bei unkorrekten Eingabewerten oder von anderen Modulen gelieferten Fehlermeldungen. Auch dafür ist das Mocken anderer Module hilfreich, da sich ein Fehlzustand anderer Module, wie beispielsweise der Verbindungsabbruch bei Netzwerkverbindungen, durch Mock-Objekte leichter simulieren als in der Realität nachstellen lässt.
Laufende Ausführung
Modultests sollten im Laufe der Entwicklung regelmäßig durchgeführt werden, um zu verifizieren, dass Änderungen keine unerwünschten Nebeneffekte haben. Modultests sollten daher von jedem Entwickler vor dem Einchecken durchgeführt werden, automatisierte Modultests auch bei Kontinuierlicher Integration auf sogenannten Continuous Integration Servern wie beispielsweise Jenkins.
Test des Vertrages und nicht der Algorithmen
Modultests sollen gemäß dem Design-by-contract-Prinzip möglichst nicht die Interna einer Methode testen, sondern nur ihre externen Auswirkungen (Rückgabewerte, Ausgaben, Zustandsänderungen, Zusicherungen). Werden auch interne Details der Methode geprüft (dies wird als White-Box-Testing bezeichnet), droht der Test fragil zu werden, er könnte auch fehlschlagen, obwohl sich die externen Auswirkungen nicht geändert haben. Daher wird in der Regel das sogenannte Black-Box-Testing empfohlen, bei dem man sich auf das Prüfen der externen Auswirkungen beschränkt.
Testgetriebene Entwicklung
Bei der Testgetriebenen Entwicklung (TDD von Test driven development) wird jeweils ein Modultest vor dem Erstellen bzw. Ändern des eigentlichen Programmcodes erstellt und gepflegt. Dies hat verschiedene Vorteile: Es wird verifiziert, dass der Test ohne die Änderung wirklich fehlschlägt, es reduziert die Gefahr des übermäßigen White-Box-Testings, es verbessert das Design, da sich der Entwickler so besser über das benötigte Verhalten der Methode klar werden kann, bevor er mit der Entwicklung beginnt. Darum ist es in der Praxis meist weniger aufwendig einen Test vor der Implementierung zu schreiben als umgekehrt.
Pro Bug ein Test
Die Erstellung eines Modultests vor Behebung eines Fehlers bietet einige Möglichkeiten. Einerseits stellt der Test sicher, dass der Bug wirklich in dem Programmcode vorhanden ist, wo man ihn auszubessern gedenkt, andererseits dass der Bug auch durch die Programmänderung tatsächlich behoben wurde und auch in Zukunft nicht mehr auftreten kann. Einige Open-Source-Projekte fordern daher, dass bei Fehlern des Programms nicht nur ein Fix, sondern auch ein Test mitgeliefert wird, der ohne den Fix fehlschlägt, aber mit dem Fix korrekt abläuft.

Modultests sind die Vorstufe zu Integrationstests, die wiederum zum Testen mehrerer voneinander abhängiger Komponenten im Zusammenspiel geeignet sind. Im Gegensatz zu Modultests werden Integrationstests meist manuell ausgeführt.

Anwendungsbeispiele

Modultests werden auch im Automotive-Bereich an programmierbaren Steuereinheiten verwendet. Damit wird die Steuereinheit verifiziert (ihre Übereinstimmung mit der Absicht des Entwicklers geprüft). Hier haben die Modultests auch rechtliche Bedeutung innerhalb des Vertragsdokumentes. Falls eine programmierbare Steuerung versagt, kann es zu Personenschäden kommen. Bei einem solchen Test wird die Durchführung einschließlich aufgetretener Fehler protokollartig festgehalten. Dabei wird dann zwischen Unit-Test (kann der Test einer einzelnen C-Funktion sein) und Modultest (Test des gesamten Moduls, dazu gehören Tests der Units und Tests der Funktionsschnittstellen zwischen den Units) unterschieden. Im Automotive-Bereich stehen bei diesen Tests weniger textuelle Daten als vielmehr Variablen physikalischer Werte und damit Grenzwerte im Vordergrund. So muss z. B. geprüft werden, ob das Ergebnis einer Addition von Ganzzahlen sich in jedem Fall innerhalb des Wertebereiches des Ganzzahl-Datentyps befindet. Man erhält dabei über die Code-Abdeckung hinaus große Mengen an Zahlenlisten, die zu testen sind.

Bei Fluxtests werden die Datenflüsse der Schnittstellen integrierter Systeme abgehört und dem Regressionset für die Unittests beigefügt, da ja sowohl Input als auch Output bekannt ist. Die eigentliche Fluxtestphase erfolgt dabei erst beim nächsten Zyklus der Softwareentwicklung, in der den Units dann die bekannten Aufrufparameter übergeben werden beziehungsweise anhand der bekannten gewünschten Ausgabedaten die Units auf ihre Richtigkeit überprüft werden. Fluxtests können nur aus funktionierenden (teil-)integrierten Systemen gewonnen werden. Damit wird im nächsten Zyklus der Integration vorgegriffen. Bereits fertiggestellte Units werden früher getestet, der Release- oder Entwicklungszyklus verkürzt sich. Besonders bei "hardest-first" Integrationsstrategien zahlen sich Fluxtests somit aus.

Beispieltest

Das folgende Beispiel ist eine Testsuite für eine Model-Klasse einer Ruby on Rails-Anwendung mit dem Shoulda-Test-Framework. Zunächst wird ein einfacher Test für Verknüpfungen zu anderen Objekten (hier Übersetzungen) geprüft. Mit einer setup-Methode wird ein Ort in die Datenbank eingetragen, anhand dessen dann zwei Methoden der Klasse mit unterschiedlichen Werten geprüft werden. Anhand der verschachtelten context- und should-Blöcke generiert Shoulda Methoden mit Namen wie Given I have a place name should return "Schweiz" for Switzerland in German oder Given I have a place name_with_local should return "Switzerland (Schweiz)" or "Switzerland (Suisse)" for Switzerland in English. I18n.locale setzt dabei die Spracheinstellung, während assert_equal und assert_contains die Methode aufrufen und den Rückgabewert mit den erwarteten Werten vergleichen.

class PlaceTest < ActiveRecord::TestCase
  should_have_many :translations
 
  context "Given I have a place" do
    setup do
      @Switzerland = Place.create!
      @Switzerland.translations.create! :name => "Schweiz", :locale => "de", :is_local => true
      @Switzerland.translations.create! :name => "Switzerland", :locale => "en"
      @Switzerland.translations.create! :name => "Suisse", :locale => "fr", :is_local => true
    end
 
    context "name" do
      should "return \"Schweiz\" for Switzerland in German" do
        I18n.locale = :de
        assert_equal "Schweiz", @Switzerland.name
      end
 
      should "return \"Switzerland\" for Switzerland in English" do
        I18n.locale = :en
        assert_equal "Switzerland", @Switzerland.name
      end
 
      should "return \"Switzerland\" for Switzerland in Korean" do
        I18n.locale = :ko
        assert_equal "Switzerland", @Switzerland.name
      end
    end
 
    context "name_with_local" do
      should "return \"Schweiz\" for Switzerland in German" do
        I18n.locale = :de
        assert_equal "Schweiz", @Switzerland.name_with_local
      end
 
      should "return \"Switzerland (Schweiz)\" or \"Switzerland (Suisse)\" for Switzerland in English" do
        I18n.locale = :en
        assert_contains ["Switzerland (Schweiz)", "Switzerland (Suisse)"], @Switzerland.name_with_local
      end
    end
  end
end

Siehe auch

Literatur

Weblinks


Wikimedia Foundation.

Игры ⚽ Нужно решить контрольную?
Synonyme:

Schlagen Sie auch in anderen Wörterbüchern nach:

  • Modultest — ⇡ Testen …   Lexikon der Economics

  • Liste von Modultest-Software — Inhaltsverzeichnis 1 ABAP 2 C 3 C++ 4 Cobol 5 Delphi …   Deutsch Wikipedia

  • Gegenseitiger Ausschluss — Der Begriff Wechselseitiger Ausschluss bzw. Mutex (Abk. für engl. mutual exclusion, auf deutsch etwa wechselseitiger Ausschluss) bezeichnet eine Gruppe von Verfahren, mit denen das Problem des kritischen Abschnitts gelöst wird. Mutex Verfahren… …   Deutsch Wikipedia

  • Mutex — Der Begriff Wechselseitiger Ausschluss bzw. Mutex (Abk. für engl. mutual exclusion) bezeichnet eine Gruppe von Verfahren, mit denen das Problem des kritischen Abschnitts gelöst wird. Mutex Verfahren verhindern, dass nebenläufige Prozesse bzw.… …   Deutsch Wikipedia

  • Wechselseitiger Ausschluss — Der Begriff Wechselseitiger Ausschluss bzw. Mutex (Abk. für engl. mutual exclusion, auf deutsch etwa wechselseitiger Ausschluss) bezeichnet eine Gruppe von Verfahren, mit denen das Problem des kritischen Abschnitts gelöst wird. Mutex Verfahren… …   Deutsch Wikipedia

  • Extreme programming — (XP), auch Extremprogrammierung, ist eine agile Methode, die das Lösen einer Programmieraufgabe in den Vordergrund der Softwareentwicklung stellt und dabei einem formalisierten Vorgehen geringere Bedeutung zumisst. Die Extremprogrammierung… …   Deutsch Wikipedia

  • Extremprogrammierung — Extreme Programming (XP), auch Extremprogrammierung, ist eine agile Methode, die das Lösen einer Programmieraufgabe in den Vordergrund der Softwareentwicklung stellt und dabei einem formalisierten Vorgehen geringere Bedeutung zumisst. Die… …   Deutsch Wikipedia

  • Xtreme Programming — Extreme Programming (XP), auch Extremprogrammierung, ist eine agile Methode, die das Lösen einer Programmieraufgabe in den Vordergrund der Softwareentwicklung stellt und dabei einem formalisierten Vorgehen geringere Bedeutung zumisst. Die… …   Deutsch Wikipedia

  • Komponententest — Dieser Artikel wurde aufgrund von inhaltlichen Mängeln auf der Qualitätssicherungsseite der Redaktion Informatik eingetragen. Dies geschieht, um die Qualität der Artikel aus dem Themengebiet Informatik auf ein akzeptables Niveau zu bringen. Hilf… …   Deutsch Wikipedia

  • Unit-Test — Dieser Artikel wurde aufgrund von inhaltlichen Mängeln auf der Qualitätssicherungsseite der Redaktion Informatik eingetragen. Dies geschieht, um die Qualität der Artikel aus dem Themengebiet Informatik auf ein akzeptables Niveau zu bringen. Hilf… …   Deutsch Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”