I percorsi di cortocircuito sono considerati per la copertura del percorso?

3

In un libro, Doron A. Peled, afferma che "

path coverage does not subsume multiple condition coverage because you can execute all the paths without exercising all the conditions.

Ma credo che non sia giusto (implica che il percorso sia solo "visibile"), perché anche la complessità ciclomatica è aumentata di uno per ogni operatore logico in una decisione, affermando che un nuovo nodo decisionale viene creato nel controllo del programma diagramma di flusso, creando percorsi immediati che devono essere esercitati - nei linguaggi di cortocircuito. Quindi: se (A & & & C; C) ha due percorsi dalla prospettiva tradizionale (rami), ma precisamente c'è di più se il linguaggio consente il cortocircuito. Quindi, credo che la dichiarazione citata non sia corretta. Anche per una singola decisione, sono ugualmente forti. Nel contesto di un intero metodo, la copertura del percorso è ovviamente più strong in quanto ad ogni decisione il numero totale raddoppia.

Mi manca qualcosa o il mio ragionamento è corretto?

    
posta John V 27.04.2018 - 13:07
fonte

4 risposte

2

Quindi capisco cosa stai dicendo per dire che questo:

if(A && B && C) { ... }

Ha questo grafico:

Che dopo averlo estratto, penso che in effetti debba essere corretto. Se A, B e C non hanno effetti collaterali, ad es. se sono solo valori booleani primitivi, allora penso che puoi farcela a ridurli allo stesso grafico della versione non a taglio corto:

if (A & B & C) { ... }

Ma se A, B e C sono funzioni, non si può davvero ignorare il fatto che B non valuterà a meno che A sia vero e C non valuterà se A e B non sono veri. Quindi, per ottenere tutti i percorsi, non si può semplicemente testare la situazione in cui A è falso e la situazione in cui A, B e C sono tutti vere. Devi testare dove A è vero e B è falso, A e B sono veri e C è falso e così il cortocircuito aggiunge due percorsi.

Il mio primo pensiero è stato che hai ragione e questo è un errore nella descrizione dell'autore. Ma ho appena realizzato che questo punto potrebbe avere senso se consideriamo il non-corto circuito. Prendere in considerazione:

if (A | B | C) {...}

In questo caso valutiamo sempre tutte e tre le condizioni, quindi ci sono solo due percorsi. Tuttavia, ci sono 8 diverse combinazioni di condizioni. Pertanto possiamo valutare entrambi i percorsi senza verificare tutti gli stati di condizione possibili. Forse questo è ciò che l'autore intende qui?

    
risposta data 27.04.2018 - 18:07
fonte
0

Esistono un paio di tipi di copertura del codice strumenti. La maggior parte degli strumenti ha copertura informativa o copertura delle filiali. Tuttavia, alcuni forniscono la copertura delle condizioni. La dichiarazione di Doron vale per tutti gli strumenti di copertura che non forniscono copertura delle condizioni. Supponendo che tu abbia avuto una corsa in cui A e C erano vere, allora quelle due parti della codifica saranno contrassegnate come coperte, ma B non lo sarà. Detto questo, non dimostra che hai completamente testato le condizioni.

In caso di cortocircuito, le domande che devi porre sono:

  • I miei test hanno effetti collaterali? In altre parole, B o C fa cose che mi aspetto da linea?
  • È in cortocircuito quello che voglio? In molti casi, sì.
  • Ho testato il significato semantico?

Se i tuoi test hanno effetti collaterali, ciò può portare ad errori molto difficili da trovare, in particolare se il codice down-stream si aspetta che gli effetti collaterali di B vengano applicati anche se A è falso. È sempre meglio ridurlo al minimo. Non dirò di eliminarlo dal momento che potresti contare sul cortocircuito per evitare un'azione costosa se possibile.

Non hai semanticamente testato la tua condizione a meno che tu non abbia provato tutte le eventualità progettate. In altre parole, in questo caso potrebbero essere necessari ben 9 test per valutare completamente la semantica di quel ramo, in particolare se si hanno effetti collaterali su cui si sta contando. Certo, se puoi dimostrare che la semantica è davvero che tutto deve essere vero per eseguire il codice all'interno dell'istruzione if o non viene chiamato affatto, potrebbe essere semanticamente corretto avere solo 2 test.

Con un buon design è possibile separare il codice che manipola lo stato dal codice che lo controlla. Ciò semplificherà notevolmente la semantica per il tuo if(A && B && C) a if(true) e if(false) .

    
risposta data 27.04.2018 - 14:42
fonte
0

Considera l'ipotetico refactoring in cui sostituiamo

function(bool A, bool B, bool C) { ..
    if(A && B && C) {..

Con

function(Func<bool> conditionFn) { ..
    if(conditionFn()) {..

Non importa quanto sia complesso il conditionFn , function ha solo due percorsi.

Ma! ovviamente non dovresti testare entrambi i percorsi, anche se questo ti darebbe una copertura del percorso del 100%, ma anche se il percorso corretto è seguito per i parametri di input A, B e C. es. prova per conditionFn

se tuttavia abbiamo

function(Func<bool> A, Func<bool>B, Func<bool> C) { ..
    if(A() && B() && C()) {..

Quindi, sì abbiamo più rami dovuti a cortocircuiti che potrebbero impedire l'esecuzione del codice in queste funzioni se, ad esempio, A restituisce false.

    
risposta data 27.04.2018 - 15:50
fonte
0

L'affermazione che hai citato è vera, ma non direttamente utile a causa della prevalenza degli operatori di cortocircuito nelle lingue moderne. Non è corretto interpretare && o || in linguaggi di tipo C come operatori logici. Invece, sono operatori di flusso di controllo e un punto di sequenza. Altri linguaggi rendono questo più chiaro (ad es. Il logico and rispetto al flusso di controllo andalso in Standard ML).

Per un programma che utilizza solo operatori di cortocircuito, è possibile interpretare la copertura di più condizioni in base alla copertura della diramazione e alla copertura delle condizioni semplice. Quindi, la copertura del percorso include la copertura di più condizioni. Questa interpretazione è sostanzialmente corretta, ma non molto utile.

La copertura di più condizioni non riguarda fondamentalmente il flusso di controllo del programma, ma il flusso di dati . La copertura delle condizioni richiede: i valori di cui sono state trattate le espressioni booleane? La copertura di più condizioni è quindi interessata alle combinazioni di sottoespressioni booleane all'interno di un operatore decisionale. Ai fini del calcolo di questa metrica di copertura, può essere ragionevole ignorare il comportamento di cortocircuito.

Quindi, in una condizione senza cortocircuitare gli operatori booleani o quando si trascura il comportamento di cortocircuito, è chiaro che la copertura completa del percorso per if (a & b) ... può essere ottenuta con due soli casi (ad esempio a=false, b=false e a=true, b=true ) , mentre mancano i test per la copertura completa di più condizioni (qui: a=false, b=true e a=true, b=false ).

Un vantaggio pratico dell'utilizzo della copertura delle condizioni è dimostrare che la condizione può effettivamente influenzare il risultato della decisione. In caso contrario, potremmo inaspettatamente avere un codice morto. Per questo, la copertura multipla delle condizioni non è necessaria, ma la copertura delle condizioni / decisione modificata è sufficiente. Per l'esempio if (a & b) , avremmo bisogno di tre casi di test per MC / DC: a=true, b=true ; %codice%; %codice%. Pertanto, la copertura del percorso non implica nemmeno la copertura MC / DC.

Un problema con qualsiasi tipo di copertura delle condizioni è che questa metrica può essere facilmente utilizzata utilizzando operatori di flusso di controllo invece di operatori logici. Inoltre, la creazione progressiva di una decisione come a=true, b=false rende non ovvio come a=false, b=true e bool d = true; d &= a; d &= b; if (d) ... contribuiscano alla decisione. Pertanto, le metriche di copertura delle condizioni sono generalmente prive di significato a meno che non siano associate a uno stile di codifica specifico.

    
risposta data 28.04.2018 - 14:56
fonte

Leggi altre domande sui tag