Skip to main content

Einzeltestbaustein implementieren

Grundgerüst für den Testfall erstellen

Ein Testfall ist ein Funktionsbaustein, der einem bestimmten Schema folgt. Um das Einhalten des Schemas zu erleichtern, empfehlen wir, den Wizard zu nutzen. Wenn Sie einen Testfall manuell erstellen, sollte er immer von TM.Testcase ableiten. (Obsolete Testbaustein-Implementierungen).

Prozedur. Objekt Unittest einfügen
  1. Fügen Sie den Testfall-Funktionsbaustein unter einer Applikation oder im POU-Pool hinzu. Wählen Sie dazu den Befehl Objekt hinzufügenUnittest aus den Kontextmenü.

    Der Dialog Unittest hinzufügen öffnet sich.

  2. Geben Sie folgende Parameter ein:

    Name der POU: TestCase_1

    Typ: Extend TM.Testcase (empfohlen)

    _cds_icon_checked.png Optionale Methoden hinzufügen

    _cds_icon_checked.png Implementierungsvorlagen hinzufügen

    _cds_icon_checked.png Erklärende Kommentare hinzufügen

    Testfallkategorie: BasicTests

  3. Bestätigen Sie den Dialog mit Hinzufügen und speichern Sie das Projekt.

    Es entsteht ein neuer Funktionsbaustein mit den Methoden Execute, Setup, Teardown und Abort.

Für weitere Informationen siehe: Unittest hinzufügen

Testlogik implementieren

Dieser Abschnitt beschreibt anhand eines einfachen Beispiels, wie das generierte Testfall-Template mit einer Testlogik ergänzt werden kann. Dazu wird ein einfacher CTU (Counter Up) als Prüfling eingesetzt.

Anmerkung

Der Testfall-Funktionsbaustein ist als Sandbox für den Prüfling zu verstehen. Das bedeutet, dass der Testfall-Funktionsbaustein beispielsweise eine dedizierte Instanz des Prüflings beinhaltet und die für den Aufruf des Prüflings nötige Umgebung vorbereiten und nachbereiten muss. Der Prüfling sollte daher im Sinne eines Unittests möglichst kontextfrei sein. Der Unittest kann daher nicht für Systemtest-Szenarien verwendet werden.

  1. Deklarieren Sie eine Instanz des Prüflings im Deklarationsteil des Testbausteins. Testen Sie hier beispielsweise einen CTU-Standardbaustein.

    {attribute 'test'}
    {attribute 'testcasename':='TC01'}
    {attribute 'testcasetimeout':='15000'}
    FUNCTION_BLOCK TestCase EXTENDS TM.Testcase
    VAR_INPUT
    END_VAR
    VAR_OUTPUT
    END_VAR
    VAR
    	counter : CTU;	// testee instance
    	cycleCounter : INT; // independant test control variable
    END_VAR
  2. Fügen Sie die Initialisierung des Prüflings im Implementierungsteil der Methode Setup ein. Das Beispiel initialisiert den CTU per Reset und setzt die Zählergrenze auf 5. Die Setup-Methode wird einmalig vor Execute aufgerufen.

    // Initialize the testee
    counter(CU:=FALSE, RESET:=TRUE, PV:=5);	// reset the counter, set expected upper limit
    
    // Initialize the test itself
    cycleCounter := 0;	// we'll count cycles
  3. Rufen Sie den Prüfling in der Methode Execute auf und prüfen Sie dessen Ergebnis. Dabei wird die Methode Execute solange aufgerufen, bis sie TRUE zurückliefert. Der Prüfling kann somit über mehrere SPS-Zyklen aufgerufen werden.

    cycleCounter := cycleCounter + 1;	// count cycles
    
    IF (cycleCounter <= 10) THEN // stimulate testee as long as we expect: 5 rising edges to count to 5 equals minimum 10 cycles
         
        // stimulate testee
        counter(CU:= (NOT counter.CU), RESET:=FALSE);	// Trigger counter with rising edges
    	
        Execute := FALSE;   // signal test still running
    ELSE
        // check result with suitable assertions for any occasion
        TM.Assert_Bool_IsTrue(THIS^, counter.Q, "CTU did not signal that it's limit was reached");
        TM.Assert_Word_Equal(THIS^, 5, counter.CV, "CTU did not reach expected limit");
         
        Execute := TRUE;    // mandatory: signal test completed
    END_IF
  4. Sie könnten den Prüfling in der Methode Teardown deinitialisieren. Dies wird jedoch in diesem Beispiel nicht benötigt. Sie können die Methode löschen.

  5. Ebenso muss kein besonderer Code ausgeführt werden, wenn der Test in einen Timeout läuft. Sie können die Methode Abort löschen.

Testelement IEC-Unittest konfigurieren

  1. Geben Sie in Titel einen Testfallnamen ein.

    Beispiel: N_001_Test

    Bei Testausführung erscheint der Titel als Testfallname.

  2. Geben Sie in Timeout Gerät lesen (ms) eine Zeit an. Beispiel: 5000

    Anmerkung

    Bei jedem Testfall wird mindestens beim Auslesen von Teststatus und Testergebnis gewartet. Außerdem wird beim Einloggen gewartet, wenn der Applikationsstatus ausgelesen wird.

    Beim Auslesen von Variablen wird gewartet, bis der Timeout abgelaufen ist, erst dann wird gelesen.

  3. Geben Sie in Erneute Login-Versuche an, wie oft maximal versucht wird den Onlinebetrieb herzustellen. Beispiel: 3

  4. Klicken Sie links oben in der Tabelle Ausgewählte Kategorien.

    Ein Eingabefeld erscheint.

  5. Geben Sie alle Kategorien ein, die in diesem Testfall aufgerufen werden.

    Beispiel: BasicTests

    Alle Test-Funktionsbausteine, die mit dem Attribut 'testcategory' := 'BasicTests' dekoriert sind, werden in diesem Testfall aufgerufen.

Testskript ausführen

Voraussetzung: Die Testumgebung ist vorbereitet. Das Testprojekt ist im CODESYS Development System geöffnet und die Geräte- und Kommunikationseinstellungen sind konfiguriert. Diese notwendigen Anweisungen werden durch einen vorbereitenden Testfall im Testskript vorgenommen.

  1. Der Inhalt des Ordners Generated Unit Tests wird gelöscht, um die generierten Bausteine eines vorherigen IEC-Unittests zu entfernen.

  2. Das Projekt und die Bibliotheken zum Testen werden nach Testtabellen durchsucht. Dann werden die Funktionsbausteine für die Ausführung der Testtabellen im Ordner Generated Unit Tests generiert.

  3. Das Projekt und die Bibliotheken, die unter Bibliotheken zum Testen aufgelistet sind, werden durchsucht nach Funktionsbausteinen und Programmen, die als Test markiert sind.

    Dann werden unter den ermittelten Programmen und Funktionsbausteinen diejenigen entfernt, die über die Testkategorien oder den Namen ausgeschlossen sind.

    Die verbleibenden Programme und Funktionsbausteine werden für den Test berücksichtigt.

  4. Ein Backup der ursprünglichen Applikation wird erstellt.

  5. Die Testfälle werden als IEC-Code in PLC_PRG eingefügt. Die (in der Deklaration und in der Implementierung) hinzugefügten Codezeilen werden mit Generated by IEC Unit Test markiert.

  6. Wenn die Applikation zu groß für die Steuerung ist, werden automatisch die Tests auf mehrere Applikationen aufgeteilt. Eine oder mehrere ablauffähige Applikationen werden generiert.

  7. Der Test mit der erzeugten Applikation / den erzeugten Applikationen wird ausgeführt.

    Folgenden Einzelschritte werden abgearbeitet:

    • Eine Testapplikation wird auf die Steuerung geladen.

    • Die Testapplikation wird gestartet.

    • Die Testfälle werden ausgeführt. Wenn in den Testfunktionsbausteinen die Stringvariable sInfo oder wsInfo verwendet wird, erscheint deren Inhalt im Testreport.

    • Der Timeout wird überwacht.

    • Das Testergebnis wird überprüft und danach Testreport übermittelt.

    • Applikation wird von der Steuerung entfernt.

  8. Ein Testreport, der alle Testergebnisse enthält, wird generiert.

Tipp

Beachten Sie das Testrepository Default-Test-Repository. Dort finden Sie das Testskript Examples.IecUnitTest. In diesem Testskript können Sie einen IEC-Unittest nachvollziehen, also die vorbereitenden Maßnahmen Projekt laden, Gerät aktualisieren und Kommunikationseinstellungen setzen. Dann folgt ein IEC-Unittest. Die Testfälle, die durchlaufen werden, kommen aus dem Projekt Example_IecUnitTest.project. Sie finden das Projekt im Verzeichnis C:\ProgramData\CODESYS Test Manager.

Die Beispielskripte sind für eine Steuerung CODESYS Control Win (32 Bit) erstellt. Falls Sie eine andere Steuerung einsetzen, müssen Sie die Parameter der Skript-Aktion UpdateDevice anpassen.