Hauptinhalt

Die Übersetzung dieser Seite ist veraltet. Klicken Sie hier, um die neueste Version auf Englisch zu sehen.

Verifizieren eines MATLAB-Algorithmus mithilfe von anforderungsbasierten Tests

Dieses Beispiel zeigt, wie Sie einen MATLAB®-Algorithmus verifizieren, indem Sie Verifikationsverknüpfungen von MATLAB-Programmcodezeilen in Funktionen und Tests zu Anforderungen erstellen. In diesem Beispiel wird ein Projekt verwendet, das einen Algorithmus zur Berechnung des kürzesten Weges zwischen zwei Knoten in einem Graphen enthält.

Öffnen Sie das Projekt ShortestPath.

openProject("ShortestPath");

Untersuchen der Projektartefakte

Das Projekt umfasst:

  • Anforderungssätze für funktionale und Testanforderungen, die sich im Ordner requirements befinden

  • Einen MATLAB-Algorithmus src befindet

  • MATLAB Unit-Tests, die sich im Ordner tests befinden

  • Verknüpfungen von MATLAB Programmcodezeilen zu Anforderungen, die in .slmx-Dateien in den Ordnern src und tests gespeichert sind

  • Skripte zur Automatisierung der Projektanalyse, die sich im Ordner scripts befinden

Öffnen des funktionalen Anforderungssatzes

Der Anforderungssatz shortest_path_func_reqs erfasst das funktionale Verhalten, das die Funktion shortest_path benötigt. Die Anforderungen beschreiben das nominale Verhalten und das erwartete Verhalten bei ungültigen Bedingungen, beispielsweise wenn die Eingaben für die Funktion nicht gültig sind. Öffnen Sie den Anforderungssatz im Requirements Editor.

funcReqs = slreq.open("shortest_path_func_reqs");

Verwenden der Funktion „Shortest Path“

Die Funktion shortest_path prüft die Gültigkeit der Eingaben für die Funktion und berechnet dann mithilfe des Djikstra-Algorithmus die Anzahl der Kanten im kürzesten Weg zwischen zwei Knoten in einem Graphen. Die Eingaben für die Funktion sind eine Adjazenzmatrix, die einen Graphen darstellt, der Startknoten und der Endknoten. Betrachten Sie beispielsweise diese Adjazenzmatrix, die einen Graphen mit sechs Knoten darstellt.

A = [0 1 0 0 1 0;
    1 0 1 0 0 0;
    0 1 0 1 0 0;
    0 0 1 0 1 1;
    1 0 0 1 0 0;
    0 0 0 1 0 0];

Erstellen Sie einen Graphen aus der Matrix und plotten Sie ihn.

G = graph(A);
plot(G,EdgeLabel=G.Edges.Weight)

Figure contains an axes object. The axes object contains an object of type graphplot.

Berechnen Sie die Anzahl der Kanten im kürzesten Weg zwischen den Knoten 1 und 6.

pathLength = shortest_path(A,1,6)
pathLength = 3

Öffnen des Testanforderungssatzes

Der Anforderungssatz shortest_path_tests_reqs enthält Testanforderungen, die das funktionale Verhalten beschreiben, das durch einen Testfall geprüft werden muss. Die Testanforderungen werden aus den funktionalen Anforderungen abgeleitet. Es bestehen Testanforderungen für das nominale Verhalten und für die ungültigen Zustände. Öffnen Sie den Anforderungssatz im Requirements Editor.

testReqs = slreq.open("shortest_path_tests_reqs");

Die klassenbasierten MATLAB Unit-Tests in graph_unit_tests implementieren die in shortest_path_tests_reqs beschriebenen Testfälle. Die Klasse enthält Testmethoden, die auf den Testanforderungen aus shortest_path_tests_reqs basieren. Die Klasse enthält auch die Methode verify_path_length, die von den Testfällen als Qualifizierungsmethode verwendet wird, um zu überprüfen, ob die erwarteten und tatsächlichen Ergebnisse übereinstimmen. Die Klasse enthält auch statische Methoden, die Adjazenzmatrizen für die Testfälle erstellen.

Anzeigen des Verifikationsstatus

Um den Verifikationsstatus anzuzeigen, klicken Sie in der Symbolleiste Requirements Editor im Abschnitt View auf showColumns_16.pngColumns und wählen Sie Verification Status. Bei drei funktionalen Anforderungen und einer Testanforderung fehlen Verifikationsverknüpfungen. Der Verifikationsstatus ist für jede Anforderung gelb, was darauf hinweist, dass die verknüpften Tests nicht ausgeführt wurden.

missingVerification.png

Führen Sie die Tests aus und aktualisieren Sie den Verifikationsstatus für die Anforderungssätze mithilfe der Methode runTests.

status1 = runTests(funcReqs);
Running graph_unit_tests
.......... ..
Done graph_unit_tests
__________
status2 = runTests(testReqs);
Running graph_unit_tests
.......... ...
Done graph_unit_tests
__________

Der Verifikationsstatus ist grün, um anzuzeigen, dass die verknüpften Tests bestanden wurden. Einige der Anforderungen sind jedoch nicht mit Tests verknüpft.

Identifizieren von Lücken in der Rückverfolgbarkeit des Projekts

Die funktionalen und Testanforderungen sind mit Codezeilen in den Dateien shortest_path und graph_unit_tests verknüpft, jedoch ist die Rückverfolgbarkeit nicht vollständig gewährleistet. Verwenden Sie eine Rückverfolgbarkeitsmatrix, um Anforderungen zu identifizieren, die nicht mit Tests verknüpft sind, und um Verknüpfungen zu erstellen, damit die Anforderungen vollständig rückverfolgbar sind.

Finden fehlender Verknüpfungen mithilfe einer Rückverfolgbarkeitsmatrix

Erstellen Sie eine Rückverfolgbarkeitsmatrix für beide Anforderungssätze, wobei die Anforderungen oben und die Unit-Tests links aufgeführt sind. Weitere Informationen zu Rückverfolgbarkeitsmatrizen finden Sie unter Track Requirement Links with a Traceability Matrix.

mtxOpts = slreq.getTraceabilityMatrixOptions;
mtxOpts.topArtifacts = {'shortest_path_func_reqs.slreqx','shortest_path_tests_reqs.slreqx'};
mtxOpts.leftArtifacts = {'graph_unit_tests'};
slreq.generateTraceabilityMatrix(mtxOpts)

Filtern Sie im Filter Panel im Abschnitt Top die Matrix, um nur die funktionalen Anforderungen anzuzeigen, die nicht mit Tests verknüpft sind, indem Sie auf Folgendes klicken:

  • Top > Link > Missing Links

  • Top > Type > Functional

Im Abschnitt Left werden nur die Testfunktionen in der Datei graph_unit_tests angezeigt, indem Sie auf Folgendes klicken:

  • Left > Type > Function

  • Left > Attributes > Test

Klicken Sie in der Symbolleiste auf Highlight Missing Links.

missingLinksTRMX.png

Das Fenster „Traceability Matrix“ zeigt die drei funktionalen Anforderungen und eine Testanforderung, für die keine Verifikationsverknüpfungen vorhanden sind.

Erstellen von Verifikationsverknüpfungen für Anforderungen

Die Testanforderung 2.1.3, Test for a graph that is a tree, ist nicht mit einem Test verknüpft. Ein Baum ist ein Graph, in dem jeweils zwei Knoten nur über einen einzigen Pfad miteinander verbunden sind.

Der Testfall check_invalid_start_1 testet einen Baumgraphen, indem er die statische Methode graph_straight_seq verwendet, um die Adjazenzmatrix zu erstellen. Verwenden Sie die Methode graph_straight_seq, um das Baumdiagramm anzuzeigen.

A = graph_unit_tests.graph_straight_seq;
G = graph(A);
plot(G,EdgeLabel=G.Edges.Weight)

Figure contains an axes object. The axes object contains an object of type graphplot.

Erstellen Sie mithilfe der zuvor erstellten Rückverfolgbarkeitsmatrix eine Verknüpfung von der Anforderung Test for a graph that is a tree zum Testfall check_invalid_start_1.

slreq.generateTraceabilityMatrix(mtxOpts)

Klicken Sie auf die Zelle, die der Anforderung und dem Test entspricht, und wählen Sie Create. Klicken Sie im Dialogfeld „Create Link“ auf Create.

createTestLink.png

Aktualisieren Sie den Verifikationsstatus im Requirements Editor, indem Sie die mit den Testanforderungen verknüpften Tests ausführen. Der Test check_invalid_start_1 überprüft die Anforderung Test for a graph that is a tree.

status3 = runTests(testReqs);
Running graph_unit_tests
.......... ...
Done graph_unit_tests
__________

Darüber hinaus sind drei funktionale Anforderungen nicht mit Tests verknüpft:

  • Anforderung 2.2.1: Returns -9 for invalid adjacency matrices

  • Anforderung 2.2.2: Returns -19 if the start node is encoded incorrectly

  • Anforderung 2.2.3: Returns -29 if end node is encoded incorrectly

Es besteht eine Lücke in der Rückverfolgbarkeit dieser Anforderungen. Sie können diese Lücke nicht durch Verknüpfungen zu Tests schließen, da es keine Tests gibt, die diese Anforderungen überprüfen.

Beheben von Lücken in der Abdeckung und Rückverfolgbarkeit durch das Erstellen von Tests

Die drei funktionalen Anforderungen, die keine Verknüpfungen zu Tests aufweisen, sind mit Codezeilen in der Funktion shortest_path verknüpft. Führen Sie die Tests mit Abdeckung durch, um festzustellen, ob diese Codezeilen in der Funktion shortest_path von den Tests abgedeckt werden.

Ausführen von Tests mit Abdeckung

Verwenden Sie das Skript RunTestsWithCoverage, um die Tests mit Funktions- und Anweisungsabdeckung auszuführen und die Abdeckung in einem Bericht anzuzeigen. Weitere Informationen finden Sie unter Collect Statement and Function Coverage Metrics for MATLAB Source Code.

RunTestsWithCoverage
Running graph_unit_tests
.......... ....
Done graph_unit_tests
__________

MATLAB code coverage report has been saved to:
 C:\Users\ahoward\AppData\Local\Temp\tpc3b346ea_31dd_409d_be4c_5e787898bf8f\index.html

Öffnen Sie den Abdeckungsbericht. Die Fehlercode-Anweisungen in den Zeilen 20, 25 und 30 werden nicht durch Tests abgedeckt.

missingCoverage.png

Beachten Sie, dass sich die Abdeckungslücke für diese Codezeilen und die Rückverfolgbarkeitslücke für die Anforderungen 2.2.1, 2.2.2 und 2.2.3 auf dieselben Fehlercodes beziehen. Sie können die Lücken in der Abdeckung und Rückverfolgbarkeit gleichzeitig schließen, indem Sie Tests für diese Codezeilen erstellen und Verknüpfungen zu den Anforderungen herstellen.

Verbessern der Abdeckung durch das Erstellen neuer Tests

Erstellen Sie Tests, die die Abdeckung der Tests verbessern und die Anforderungen 2.2.1, 2.2.2 und 2.2.2 überprüfen. Öffnen Sie die Testdatei graph_unit_tests.

open("graph_unit_tests.m");

Diese Funktionen überprüfen die drei Fehlercodes. Kopieren Sie den Code in Zeile 4 in den Abschnitt der Testmethoden der Datei graph_unit_tests und speichern Sie die Datei anschließend.

function check_invalid_nonsquare(testCase)
    adjMatrix = zeros(2,3);
    startIdx = 1;
    endIdx = 1;
    expOut = -9;
    verify_path_length(testCase, adjMatrix, startIdx, endIdx, expOut, ...
        'Graph is not square');
end

function check_invalid_entry(testCase)
    adjMatrix = 2*ones(4,4);
    startIdx = 1;
    endIdx = 1;
    expOut = -9;
    verify_path_length(testCase, adjMatrix, startIdx, endIdx, expOut, ...
        'Adjacency matrix is not valid');
end

function check_invalid_noninteger_startnode(testCase)
    adjMatrix = zeros(4,4);
    startIdx = 1.2;
    endIdx = 1;
    expOut = -19;
    verify_path_length(testCase, adjMatrix, startIdx, endIdx, expOut, ...
        'Start node is not an integer');
end

function check_invalid_noninteger_endnode(testCase)
    adjMatrix = zeros(4,4);
    startIdx = 1;
    endIdx = 2.2;
    expOut = -29;
    verify_path_length(testCase, adjMatrix, startIdx, endIdx, expOut, ...
        'End node is not an integer');
end

Führen Sie die Tests mit Abdeckung erneut aus und öffnen Sie den Abdeckungsbericht.

RunTestsWithCoverage
Running graph_unit_tests
.......... ....
Done graph_unit_tests
__________

MATLAB code coverage report has been saved to:
 C:\Users\ahoward\AppData\Local\Temp\tpd094de61_604e_45b4_8b53_767a6f4719cb\index.html

Die Tests decken nun die Fehlercode-Anweisungen ab.

improvedCoverage.png

Allerdings gibt es in Zeile 97 eine Anweisung, die von den Tests nicht abgedeckt wird. Die Bedingungen, die erfordern, dass die Tests die Anweisung in Zeile 97 abdecken, führen auch dazu, dass die Anweisung return in Zeile 87 ausgeführt wird, was bedeutet, dass die Anweisung in Zeile 97 nicht erreichbar ist und tote Logik darstellt.

deadLogic.png

Beheben von Lücken in der Rückverfolgbarkeit von Anforderungen

Regenerieren Sie die Rückverfolgbarkeitsmatrix, wenden Sie dieselben Filter wie zuvor an und klicken Sie dann in der Symbolleiste auf Highlight Missing Links.

slreq.generateTraceabilityMatrix(mtxOpts)
  • Top > Link > Missing Links

  • Top > Type > Functional

  • Left > Type > Function

  • Left > Attributes > Test

Erstellen Sie Verknüpfungen zwischen den Fehlercodeanforderungen und den neuen Tests.

createLinksImproveCoverage.png

Aktualisieren Sie den Verifikationsstatus im Requirements Editor, indem Sie die mit beiden Anforderungssätzen verknüpften Tests erneut ausführen.

status4 = runTests(funcReqs);
Running graph_unit_tests
.......... ..
Done graph_unit_tests
__________
status5 = runTests(testReqs);
Running graph_unit_tests
.......... ...
Done graph_unit_tests
__________

Alle Anforderungen sind mit Tests verknüpft, und alle Tests wurden bestanden.

updatedVerificationStatus.png

Nachverfolgen von Anforderungen in generiertem Code

Verwenden Sie Embedded Coder®, um Code aus dem Algorithmus shortest_path zu generieren, und fügen Sie Anforderungskommentare hinzu, mit denen Sie die Anforderungen im generierten Code nachverfolgen können. Weitere Informationen finden Sie unter Requirements Traceability for Code Generated from MATLAB Code.

Erstellen Sie ein Code-Konfigurationsobjekt, um Code mit einem LIB-Build-Typ zu generieren.

cfg = coder.config("lib","ecoder",true);

Aktivieren Sie den Konfigurationsparameter für den Code, um Anmerkungen zu Anforderungen in den generierten Code aufzunehmen.

cfg.ReqsInCode = true;

Verwenden Sie coder.typeof (MATLAB Coder), um ein doppeltes Array variabler Größe mit einer maximalen Größe von 100x100 und einen skalaren Doppelwert als Eingaben im generierten Code zu definieren.

mtxType = coder.typeof(ones(100,100),[],1);
scalarDblType = coder.typeof(1);

Generieren Sie C Code aus dem Algorithmus shortest_path mit den angegebenen Code-Konfigurationsparametern und Eingabetypen. Erstellen Sie einen Code-Generierungsbericht und starten Sie den Bericht.

codegen shortest_path -config cfg -args {mtxType, scalarDblType, scalarDblType} -launchreport
Code generation successful: View report

codegen-report-requirements-comments.png

Die Datei shortest_path.c enthält Kommentare mit einer Zusammenfassung der verknüpften Anforderung, den vollständigen Dateipfad der Datei shortest_path.m und die verknüpften Codezeilen.

Siehe auch

| (MATLAB Coder) | (MATLAB Coder)

Themen