Anche se sono d'accordo con la dichiarazione di Robert Harvey, che lo sviluppo guidato dai test è un approccio utile, spesso ho l'impressione che la gente pensi che con un numero sufficiente di test unitari sul posto siano sicuri e sia loro permesso di smettere di pensare test utili. Questo, penso, è lontano dall'essere vero.
Secondo me la creazione di test ragionevoli è qualcosa tra un'arte e una buona abilità artigiana, dove conoscere gli strumenti esistenti e le migliori pratiche insieme a loro e applicarli correttamente è la parte dell'artigianato. Una buona conoscenza degli errori di programmazione comuni come ingrediente aggiuntivo aiuterà anche a trovare test utili. Ma devi anche capire il problema risolto dall'algoritmo e devi avere un'idea di dove una implementazione rischia di fallire. Tu, almeno in parte, spesso sarai da solo qui. Cercherò di trovare almeno un algoritmo alternativo ed eseguirli contemporaneamente. Spesso ne scegli uno specifico per le prestazioni: nei test automatici puoi utilizzare uno più lento per il controllo dei croos. Qualsiasi cosa ti aiuti è qualcosa che puoi mettere nella scatola delle migliori pratiche.
Senza spendere troppo tempo su di esso, per il problema che hai fornito come esempio, proverei a trovare un modo (automatico) per (a caso) creare (molte) sequenze di lunghezza variabile per le quali posso prevedere il risultato. Quindi inserirli nell'algoritmo e registrare l'input nel caso in cui non riesca. Inoltre, lo farei per un insieme di sequenze fisse (non casuali) come protezione contro le modifiche al codice che potrebbero infrangere il codice. Farei in modo che ci siano sequenze con più di una soluzione e cercare di capire se esistono sequenze con soluzioni sovrapposte e se sì, prova a crearne anche alcune.
Vorrei aggiungere che per me, in quanto matematico, un algoritmo è corretto o sbagliato per almeno un insieme di dati di input ed è qualcosa per cui puoi (spesso) dare prova (il link è scelto più o meno a caso) - ovviamente c'è sempre il fattore umano .... Ma anche se ci credi, non puoi farlo (prova) per l'implementazione di un algoritmo (sufficientemente complesso), che è la cosa che è in realtà sotto test.
Modifica Penso che un esempio sufficientemente chiaro ed elaborato allo stesso tempo possa essere utile. Per questo vorrei attirare la vostra attenzione su "The art of computer programming" di Knuth vol 2, dove sotto il titolo "Gli algoritmi classici" viene presentato un algoritmo che mostra come dividere un intero positivo (arbitrario) con un altro intero positivo . Knuth in realtà fornisce (un po 'difficile da capire) la prova del perché il suo algoritmo è corretto. Una certa parte di quella dimostrazione mostra che esiste un modo semplice per eseguire una determinata attività in quell'algoritmo e un caso eccezionale. Il caso eccezionale (vedi la fase D3 dell'algoritmo D se si vuole veramente cercarlo) si verifica molto raramente e, in realtà, richiede un calcolo più complesso.
Ora, mentre esiste un modo abbastanza ovvio per creare test unitari per questo algoritmo (applicarlo a due interi e quindi eseguire l'operazione inversa per verificare se si arriva da dove si è iniziato) non è assolutamente ovvio come assicurarsi il caso eccezionale è testato. Per prima cosa devi conoscerlo (cioè devi capire i dettagli pelosi della dimostrazione dell'algoritmo), quindi devi trovare i dati per cui si verificherà effettivamente. Fare l'intera catena (trovare l'algoritmo, che in questo caso è fatto per te dall'autore, trovarne una dimostrazione, identificare i casi eccezionali e accertarsi che i dati dei test siano trovati che testano anche questo) non è coperto da qualsiasi tipo di best practice.