Ciò dipende in parte da come scegli di interpretare questi due termini, ma la risposta è probabilmente che entrambi sono possibili.
Prima di tutto, le definizioni più ragionevoli dei due termini rendono molto facile ottenere la copertura del percorso e della filiale senza copertura delle condizioni. Ad esempio:
function isPositive(x) {
return x > 0;
}
Il test di isPositive
con un solo valore di x ti fornirà la copertura del percorso e della diramazione ma non la copertura delle condizioni.
Allo stesso modo, è anche molto facile ottenere la copertura delle condizioni e delle diramazioni senza riuscire a ottenere la copertura del percorso.
function printPositivities(x, y) {
if(x > 0) {
std::cout << "x is positive";
} else {
std::cout << "x is non-positive";
}
if(y > 0) {
std::cout << "y is positive";
} else {
std::cout << "y is non-positive";
}
}
Se lo provi una volta con numeri positivi, poi di nuovo con numeri non positivi, otterrai la copertura delle condizioni (entrambe se le condizioni risultano vere e false) e la copertura delle filiali (poiché tutte e quattro le dichiarazioni std :: cout vengono eseguite) ma non la copertura del percorso (poiché ti perdi i percorsi in cui uno è positivo e l'altro no).
La domanda più interessante (che non hai chiesto, ma per qualche motivo pensavo di averlo fatto) è se puoi ottenere la copertura delle condizioni senza copertura della filiale.
Per fare ciò hai bisogno di un motivo per il ramo di ramo che non si qualifica come una "condizione". In molte lingue, il x
in if(x)
non deve essere un booleano, ma nella maggior parte dei casi è probabilmente più una scappatoia poco interessante rispetto a una risposta autentica poiché x
dovrà essere ancora "veritiera" o "falsy". I casi non-scappatoie più interessanti di "branchie non booleane" che riesco a trovare sono:
1) catch
blocchi. Nella maggior parte (tutti?) Delle lingue con eccezioni, un blocco catch
non viene mai eseguito a meno che non venga lanciata un'eccezione, quindi è facile scrivere codice con copertura delle condizioni perfetta che non genera mai eccezioni e quindi aggiungere un blocco try / catch anche anche se non c'è niente da catturare.
2) Go's select
sintassi sui canali:
select {
case msg1 := <-channel1:
fmt.Println("received", msg1)
case msg2 := <-channel2:
fmt.Println("received", msg2)
}
Questo fa sì che il programma attenda fino a quando channel1
o channel2
ha dati che possono essere ricevuti, quindi riceve quei dati ed esegue il blocco di codice corrispondente al canale da cui ha ricevuto. Nota che in realtà questo blocca l'esecuzione per un periodo di tempo arbitrario, piuttosto che chiamare channel1.isReady()
o qualcosa, motivo per cui credo che ciò valga. Se assicuri semplicemente che channel1
abbia sempre i dati da ricevere e channel2
no, hai un errore di copertura delle filiali.