Modultest

aus Wikipedia, der freien Enzyklopädie

Wechseln zu: Navigation, Suche
QS-Informatik

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 mit, die inhaltlichen Mängel dieses Artikels zu beseitigen und beteilige dich an der Diskussion! (+)
Begründung: Sehr holpriger Artikel zu einem sehr wichtigem Thema. Besonders der Bereich Anwendungsbeispiele lässt einem die Haare zu Berge stehen.

Dieser Artikel oder Abschnitt bedarf einer Überarbeitung. Näheres ist auf der Diskussionsseite angegeben. Hilf mit, ihn zu verbessern, und entferne anschließend diese Markierung.

Ein Modultest (auch Komponententest oder oft vom engl. unit test als Unittest bezeichnet) ist Teil des Softwaretests. Er dient zur Verifikation der Korrektheit von Modulen einer Software, z. B. von einzelnen Klassen. Nach jeder Änderung sollte durch Ablauf aller Testfälle nach Programmfehlern gesucht werden.

Ein solcher Test ist selbst ein Programm, welches das zu testende Modul, in der Regel etwa eine Methode oder eine Funktion, aufruft und auf korrekte Funktionsweise testet. Dazu müssen externe Komponenten wie etwa eine Datenbank, Dateien oder Backendsysteme, die von dem Modul verwendet werden, entweder in einen definierten Zustand gebracht werden oder simuliert (engl. to mock) werden, damit das Modul in jedem Fall die erwarteten Auswirkungen hat. Dabei sollen aber ausdrücklich nicht nur die Verarbeitung korrekter Eingabewerte geprüft werden, sondern auch die korrekte Behandlung nicht korrekter Werte. Diese Tests sollen im Laufe der Entwicklung regelmäßig ausgeführt werden, um zu verifizieren, dass Änderungen keine unerwünschten Nebeneffekte haben, etwa an ganz anderen Stellen des Programms.

Modultests sollen möglichst nicht die Interna einer Methode testen, sondern nur ihre externen Auswirkungen (Rückgabewerte, Ausgaben, Änderungen an Dateien, Datenbanken oder Backendsystemen). Werden auch interne Details der Methode geprüft (dies wird als White-Box-Testing bezeichnet), droht der Test fragil zu werden, daher, 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.

Bei der testgetriebenen Entwicklung (TDD von Test driven development) werden die Modultests vor dem Erstellen bzw. Ändern des eigentlichen Programmcodees erstellt und gepflegt. Dies hat verschieden Vorteile, unter anderem wird verifiziert, dass der Test ohne die Änderung wirklich fehlschlägt. Zudem wird die Gefahr des übermäßigen White-Box-Testings reduziert. Dies bedeutet, dass sich der Testentwickler zu sehr an den Interna des eigentlichen Programms orientiert und so möglicherweise bestimmte Fehlerquellen übersieht. Ein weiterer Vorteil ist, dass sich der Entwickler so besser über das benötigte Verhalten der Methode klar werden kann, bevor er mit der Entwicklung beginnt.

Einige Open-Source-Projekte fordern, dass insbesondere bei Fehlern des Programms nicht nur ein Fix, sondern auch Tests 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.

Inhaltsverzeichnis

[Bearbeiten] 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.

[Bearbeiten] 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 werden dann 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

[Bearbeiten] Siehe auch

[Bearbeiten] Literatur

[Bearbeiten] Weblinks

Persönliche Werkzeuge
Buch erstellen