Verbosità del test unitario in lingue non tipizzate

3

Mi sto chiedendo quanto dovrei essere prolisso quando testare i progetti unitari scritti in linguaggi non tipizzati come Javascript .

Facciamo un esempio per un linguaggio strongmente tipizzato ( C# )

public bool Foo(MyClass myClass) { /* ... */ }

Siccome C# è strongmente digitato posso essere sicuro che myClass sia null o un'istanza reale di MyClass (o qualsiasi istanza di una sottoclasse, se possibile) quindi i miei valori testabili sono solo questi. < br>

Ora portiamo questo metodo su Javascript :

function foo(data) { /* ... */ }

Ora non posso essere sicuro del tipo data di come potrebbe essere qualsiasi cosa.
Dentro foo Posso controllare quale tipo data ha ma per assicurarmi che la funzione funzioni anche con tipi non validi dovrei testare tutti i tipi possibili nei miei test di unità che producono molto codice extra.

Questo argomento mi infastidisce soprattutto nelle lingue non tipizzate in cui non riesco a determinare il tipo effettivo semplicemente osservando il codice. Da un lato non voglio scrivere un sacco di codice per testare ogni tipo possibile. D'altra parte mi sento come se mi mancasse qualcosa se provassi solo i tipi che mi aspetto.

Esistono raccomandazioni generali o best practice per questo problema?

    
posta TorbenJ 19.02.2016 - 02:13
fonte

2 risposte

4

Alcune lingue ti permettono di garantire più condizioni al momento della compilazione rispetto ad altre. Per quelle condizioni espresse (e quindi garantibili) al momento della compilazione, non è necessario testare per.

Quelle condizioni che non possono essere espresse dalla lingua, o che in qualche modo non possono essere espresse in fase di compilazione, dovrebbero essere testate. Dovrai testare entrambi sul lato dei chiamanti e sul lato dei chiamanti - che i chiamanti forniscano validi e non forniscano input non validi (ai callees), e che i callees respingano appropriatamente input non validi pur accettando input validi (e viceversa per i valori di ritorno).

C'è una variazione tra le lingue, ad esempio, usando nullable (o talvolta opzionale), alcune lingue possono spostare il controllo nullo nel set di tempo di compilazione garantito.

È una questione di gradi dove e quanti sistemi di tipo eliminano il controllo. Molte condizioni non possono essere espresse in fase di compilazione nella maggior parte delle lingue odierne (ad esempio, una lista non è vuota).

Inoltre, alcuni linguaggi strongmente tipizzati rendono alcuni indebolimenti, come un typedef o un alias di tipo che considera due tipi come equivalenti quando forse dovrebbero essere distinti.

Molte lingue popolari tipizzate in modo statico consentono di eseguire il casting su Oggetto e quindi eseguire il casting in un secondo momento. Tali operazioni di downcasting rinunciano anche al controllo del tempo di compilazione, e quindi sono soggette ad aumentare i requisiti di test.

Se stai lavorando in una lingua con un sistema di tipi deboli, dovresti certamente cercare in un modo generico di testare la presenza di tutte le qualità richieste (di parametri, valori di ritorno, ecc ...) e di rifiutare qualsiasi funzione non consentita qualità.

I sistemi di tipo sono buoni per quello che fanno, ma detto questo, un sistema di tipi non sarà mai in grado di garantire tutte le possibili condizioni necessarie, e che varia anche in base al linguaggio (anche tra quelli strongmente tipizzati), e anche tra quelli , secondo lo stile di programmazione scelto.

    
risposta data 19.02.2016 - 03:40
fonte
3

On the one hand I don't want to write a whole lot of code to test every possible type. On the other hand I feel like I'm missing something if I test just the types I'm expecting.

Onestamente, devi solo superarlo.

I coder che lavorano in linguaggi tipizzati dinamicamente non si preoccupano generalmente di cosa succede quando i tipi errati vengono passati alla loro funzione. Non scrivono codice extra per controllare i tipi e non scrivono test per verificare quali funzioni fanno quando vengono trasmessi i tipi sbagliati. Scrivono più o meno gli stessi test che avrebbero scritto se avessero lavorato in un linguaggio tipizzato staticamente.

Ad un certo livello, ciò che accade in una funzione passata con tipi di argomenti errati non ha importanza, poiché non si passeranno questi tipi di argomento in un programma funzionante. Ma, ovviamente, li accidentalmente li supererai in alcuni casi. Ecco la perdita che subisci quando adotti la digitazione dinamica, poiché impiegherà più tempo per identificare il problema.

Se questa perdita è accettabile o meno è una domanda molto discussa. I sostenitori della tipizzazione dinamica sostengono che, in pratica, questo tipo di errore non è eccessivamente comune e facilmente rilevato e risolto. Quindi è una perdita accettabile. I sostenitori della tipizzazione statica sostengono che questo tipo di errore è molto comune, spesso non facilmente rilevabile e non sempre banale da risolvere. Quindi non è una perdita accettabile.

Tuttavia, l'unica cosa che non dovresti fare è provare a programmare in un linguaggio tipizzato dinamicamente come se fosse un tipo tipizzato staticamente. Non cercare di ottenere le stesse garanzie che avevi in una lingua tipizzata in modo statico. Questo porterà solo alla pazzia. Riuscirai solo a creare un linguaggio tipizzato staticamente scadente da uno tipizzato dinamicamente.

    
risposta data 19.02.2016 - 07:51
fonte

Leggi altre domande sui tag