Contenido principal

Verificar un algoritmo de MATLAB utilizando pruebas basadas en requisitos

Este ejemplo muestra cómo verificar un algoritmo de MATLAB® creando enlaces de verificación de líneas de código de MATLAB de las funciones y pruebas a requisitos. Este ejemplo utiliza un proyecto que contiene un algoritmo para calcular la ruta más corta entre dos nodos de una gráfica.

Abra el proyecto ShortestPath.

openProject("ShortestPath");

Examinar los artefactos del proyecto

El proyecto contiene:

  • Conjuntos de requisitos para requisitos funcionales y de prueba, ubicados en la carpeta requirements

  • Un algoritmo de MATLAB, ubicado en la carpeta src

  • Pruebas unitarias de MATLAB, ubicadas en la carpeta tests

  • Enlaces de líneas de código de MATLAB a requisitos, almacenados en archivos .slmx ubicados en las carpetas src y tests

  • Scripts para automatizar el análisis del proyecto, ubicados en la carpeta scripts

Abrir el conjunto de requisitos funcionales

El conjunto de requisitos shortest_path_func_reqs captura el comportamiento funcional que requiere la función shortest_path. Los requisitos describen el comportamiento nominal y el comportamiento esperado para condiciones no válidas, como cuando las entradas para la función no son válidas. Abra el conjunto de requisitos en Requirements Editor.

funcReqs = slreq.open("shortest_path_func_reqs");

Utilizar la función con la ruta más corta

La función shortest_path prueba la validez de las entradas para la función y, después, utiliza el algoritmo de Djikstra para calcular el número de extremos en la ruta más corta entre dos nodos de una gráfica. Las entradas para la función son una matriz de adyacencia que representa una gráfica, el nodo inicial y el nodo final. Por ejemplo, considere esta matriz de adyacencia que representa una gráfica con seis nodos.

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];

Cree una gráfica a partir de la matriz y represéntela.

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

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

Calcule el número de extremos en la ruta más corta entre los nodos 1 y 6.

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

Abrir el conjunto de requisitos de prueba

El conjunto de requisitos shortest_path_tests_reqs contiene requisitos de prueba que describen el comportamiento funcional que debe probar un caso de prueba. Los requisitos de prueba derivan de los requisitos funcionales. Hay requisitos de prueba para el comportamiento nominal y para las condiciones no válidas. Abra el conjunto de requisitos en Requirements Editor.

testReqs = slreq.open("shortest_path_tests_reqs");

Las pruebas unitarias de MATLAB basadas en clases de graph_unit_tests implementan los casos de prueba descritos en shortest_path_tests_reqs. La clase contiene métodos de prueba basados en los requisitos de prueba de shortest_path_tests_reqs. La clase también contiene el método verify_path_length, que los casos de prueba utilizan como un método de cualificación para verificar que el resultado esperado y el real son iguales. La clase también contiene métodos estáticos que crean matrices de adyacencia para los casos de prueba.

Ver el estado de verificación

Para ver el estado de verificación, en la barra de herramientas de Requirements Editor, en la sección View, haga clic en showColumns_16.pngColumns y seleccione Verification Status. Tres de los requisitos funcionales y un requisito de prueba no tienen enlaces de verificación. El estado de verificación es amarillo para cada requisito, lo que indica que las pruebas enlazadas no se han ejecutado.

missingVerification.png

Ejecute las pruebas y actualice el estado de verificación para los conjuntos de requisitos utilizando el método runTests.

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

El estado de verificación está verde para indicar que se han superado las pruebas enlazadas. Sin embargo, algunos de los requisitos no tienen enlaces a pruebas.

Identificar deficiencias de trazabilidad en el proyecto

Los requisitos funcionales y de prueba están enlazados a líneas de código de los archivos shortest_path y graph_unit_tests, pero la trazabilidad no está completa. Utilice una matriz de trazabilidad para identificar requisitos que no estén enlazados a pruebas y crear enlaces para que los requisitos sean totalmente trazables.

Encontrar los enlaces faltantes con una matriz de trazabilidad

Cree una matriz de trazabilidad para ambos conjuntos de requisitos con los requisitos en la parte superior y las pruebas unitarias en la izquierda. Para obtener más información sobre matrices de trazabilidad, consulte 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)

En Filter Panel, en la sección Top, filtre la matriz para que muestre únicamente los requisitos funcionales no enlazados a pruebas haciendo clic en:

  • Top > Link > Missing Links

  • Top > Type > Functional

En la sección Left, muestre únicamente las funciones de prueba del archivo graph_unit_tests haciendo clic en:

  • Left > Type > Function

  • Left > Attributes > Test

Haga clic en Highlight Missing Links en la barra de herramientas.

missingLinksTRMX.png

La ventana Traceability Matrix muestra un requisito de prueba y los tres requisitos funcionales que no contienen enlaces de verificación.

Crear enlaces de verificación para requisitos

El requisito de prueba 2.1.3, Test for a graph that is a tree, no está enlazado a ninguna prueba. Un árbol es una gráfica en la que dos nodos están conectados únicamente por una ruta.

El caso de prueba check_invalid_start_1 prueba una gráfica de árbol utilizando el método estático graph_straight_seq para crear la matriz de adyacencia. Utilice el método graph_straight_seq para ver la gráfica de árbol.

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.

Cree un enlace del requisito Test for a graph that is a tree al caso de prueba check_invalid_start_1 utilizando la matriz de trazabilidad que ha generado previamente.

slreq.generateTraceabilityMatrix(mtxOpts)

Haga clic en la celda que se corresponde con el requisito y la prueba, y seleccione Create. En el cuadro de diálogo Create Link, haga clic en Create.

createTestLink.png

Actualice el estado de verificación en Requirements Editor ejecutando las pruebas enlazadas a los requisitos de prueba. La prueba check_invalid_start_1 verifica el requisito Test for a graph that is a tree.

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

Además, tres requisitos funcionales no tienen enlaces a pruebas:

  • Requisito 2.2.1: Returns -9 for invalid adjacency matrices

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

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

Estos requisitos tienen una deficiencia de trazabilidad. No se puede resolver esta deficiencia creando enlaces a las pruebas porque no existen pruebas que verifiquen estos requisitos.

Resolver deficiencias de cobertura y trazabilidad creando pruebas

Los tres requisitos funcionales que no tienen enlaces a pruebas sí tienen enlaces a líneas de código de la función shortest_path. Ejecute las pruebas con cobertura para determinar si esas líneas de código de la función shortest_path están cubiertas con pruebas.

Ejecutar pruebas con cobertura

Utilice el script RunTestsWithCoverage para ejecutar las pruebas con cobertura de funciones e instrucciones, y vea la cobertura en un informe. Para obtener más información, consulte 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

Abra el informe de cobertura. Las instrucciones de código con error en las líneas 20, 25 y 30 no están cubiertas por pruebas.

missingCoverage.png

Tenga en cuenta que la deficiencia de cobertura de estas líneas de código y la deficiencia de trazabilidad de los requisitos 2.2.1, 2.2.2 y 2.2.3 hacen referencia a los mismos códigos de error. Puede resolver las deficiencias de cobertura y trazabilidad de manera simultánea creando pruebas para esas líneas de código y enlaces a los requisitos.

Mejorar la cobertura creando nuevas pruebas

Cree pruebas que mejoren la cobertura para las pruebas y verifique los requisitos 2.2.1, 2.2.2, and 2.2.3. Abra el archivo de prueba graph_unit_tests.

open("graph_unit_tests.m");

Estas funciones prueban los tres códigos de error. Copie y pegue el código de la línea 4 en la sección de métodos de prueba del archivo graph_unit_tests y, luego, guarde el archivo.

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

Vuelva a ejecutar las pruebas con cobertura y abra el informe de cobertura.

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

Las pruebas ahora cubren las instrucciones de código de error.

improvedCoverage.png

Sin embargo, hay una instrucción en la línea 97 que no está cubierta en las pruebas. Las condiciones que requieren las pruebas para cubrir la instrucción de la línea 97 también provocan que se ejecute return en la línea 87, lo que significa que la instrucción en la línea 97 no es accesible y es lógica fallida.

deadLogic.png

Resolver deficiencias de trazabilidad de requisitos

Vuelva a generar la matriz de trazabilidad, aplique los mismos filtros que antes y, luego, haga clic en Highlight Missing Links en la barra de herramientas.

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

  • Top > Type > Functional

  • Left > Type > Function

  • Left > Attributes > Test

Cree enlaces entre requisitos con código de error y las nuevas pruebas.

createLinksImproveCoverage.png

Actualice el estado de verificación en Requirements Editor volviendo a ejecutar las pruebas asociadas a ambos conjuntos de requisitos.

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

Todos los requisitos tienen enlaces a pruebas y todas las pruebas se han superado.

updatedVerificationStatus.png

Realizar trazabilidad de requisitos en código generado

Utilice Embedded Coder® para generar código a partir del algoritmo shortest_path e incluya comentarios de requisitos que permitan realizar trazabilidad de requisitos en el código generado. Para obtener más información, consulte Requirements Traceability for Code Generated from MATLAB Code.

Cree un objeto de configuración de código para generar código con un tipo de compilación LIB.

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

Active el parámetro de configuración de código para incluir comentarios de requisitos en el código generado.

cfg.ReqsInCode = true;

Utilice coder.typeof (MATLAB Coder) para definir un arreglo doble de tamaño variable con un tamaño máximo de 100x100 y un escalar doble para usarlos como entradas del código generado.

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

Genere código C a partir del algoritmo shortest_path con los parámetros de configuración de código y los tipos de entrada especificados. Cree un informe de generación de código e inicie el informe.

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

codegen-report-requirements-comments.png

El archivo shortest_path.c contiene comentarios con el resumen del requisito enlazado, la ruta de archivo completa del archivo shortest_path.m y las líneas de código enlazadas.

Consulte también

| (MATLAB Coder) | (MATLAB Coder)

Temas