I test unitari avrebbero aiutato Citigroup a evitare questo costoso errore?


86

Ho letto di questo snafu: la programmazione di un bug costa al Citigroup $ 7 milioni dopo che le transazioni legittime sono state scambiate per 15 anni con dati di test .

Quando il sistema è stato introdotto a metà degli anni '90, il codice del programma ha filtrato tutte le transazioni a cui sono stati dati codici di filiale a tre cifre da 089 a 100 e ha utilizzato tali prefissi a scopo di test.

Ma nel 1998, la società ha iniziato a utilizzare i codici delle filiali alfanumerici mentre espandeva la propria attività. Tra questi c'erano i codici 10B, 10C e così via, che il sistema considerava rientranti nell'intervallo escluso, e quindi le loro transazioni venivano rimosse da qualsiasi report inviato alla SEC.

(Penso che ciò illustri che l'utilizzo di un indicatore di dati non esplicito sia ... subottimale. Sarebbe stato molto meglio popolare e utilizzare una Branch.IsLiveproprietà semanticamente esplicita .)

A parte questo, la mia prima reazione è stata "I test unitari avrebbero aiutato qui" ... ma avrebbero?

Di recente ho letto Perché la maggior parte dei test unitari è uno spreco di interesse, e quindi la mia domanda è: come sarebbero i test unitari che sarebbero falliti nell'introduzione di codici alfanumerici?



17
Sembra che abbiano anche perso un test di integrazione che ha verificato la quantità di transazioni esportate in SEC. Se si crea una funzione di esportazione che sarebbe un controllo ragionevole.
Luc Franken,

31
L'autore dell'articolo non sembra comprendere i test unitari. Alcune affermazioni sono semplicemente ridicole ( "è improbabile che i test unitari testino più di un trilionesimo della funzionalità di un determinato metodo" ), altri distruggerebbero la possibilità di ottenere regressioni ( "guarda i test che non hanno mai fallito in un anno e considera di buttarli via " ). O suggerimenti come "trasformare i test unitari in asserzioni" , che dovrebbero cambiare i test falliti per le eccezioni di runtime?
Groo,

25
@gnat Non ho letto il link esterno e ho ancora trovato questa domanda significativa
Jeutnarg

23
Per quello che vale, non sono affatto d'accordo con tutto in "Perché la maggior parte dei test unitari è spreco". Scriverei una confutazione, ma questo margine è troppo piccolo per contenerlo.
Robert Harvey,

Risposte:


19

Stai davvero chiedendo, "i test unitari avrebbero aiutato qui?", O stai chiedendo "qualsiasi tipo di test avrebbe potuto aiutare qui?".

La forma più ovvia di test che avrebbe aiutato, è un'asserzione preliminare nel codice stesso, che un identificatore di ramo è costituito solo da cifre (supponendo che questa sia l'assunzione invocata dal programmatore nello scrivere il codice).

Ciò avrebbe potuto fallire in una sorta di test di integrazione e non appena vengono introdotti i nuovi ID alfa-numerici del ramo, l'espressione si fa esplodere. Ma questo non è un test unitario.

In alternativa, potrebbe esserci un test di integrazione della procedura che genera il rapporto SEC. Questo test assicura che ogni identificatore di filiale reale riporti le proprie transazioni (e quindi richiede input dal mondo reale, un elenco di tutti gli identificatori di filiale in uso). Quindi neanche questo è un test unitario.

Non riesco a vedere alcuna definizione o documentazione delle interfacce coinvolte, ma può darsi che i test unitari non possano aver rilevato l'errore perché l'unità non era difettosa . Se all'unità è consentito assumere che gli identificativi delle filiali siano costituiti solo da cifre e gli sviluppatori non abbiano mai preso una decisione su cosa dovrebbe fare il codice in caso contrario, allora non dovrebberoscrivere un test unitario per applicare un comportamento particolare nel caso di identificatori non numerici poiché il test rifiuterebbe un'implementazione valida ipotetica dell'unità che gestiva correttamente gli identificatori di rami alfanumerici e di solito non si desidera scrivere un test unitario che impedisca la validità future implementazioni ed estensioni. O forse un documento scritto 40 anni fa, implicitamente definito (tramite un certo intervallo lessicografico nell'EBCDIC grezzo, invece di una regola di confronto più rispettosa per l'uomo) che 10B è un identificatore di prova perché in realtà rientra tra 089 e 100. Ma poi 15 anni fa qualcuno ha deciso di usarlo come un vero identificatore, quindi il "difetto" non risiede nell'unità che implementa correttamente la definizione originale: sta nel processo che non è riuscito a notare che 10B è definito come identificatore di prova e quindi non dovrebbe essere assegnato a un ramo. Lo stesso accadrebbe in ASCII se si definisse 089 - 100 come intervallo di test e si introducesse un identificatore 10 $ o 1.0. Accade semplicemente che in EBCDIC le cifre arrivano dopo le lettere.

Un test unitario (o probabilmente un test funzionale) che concepibilmentepotrebbe aver salvato la giornata, è un test dell'unità che genera o convalida nuovi identificativi di filiale. Tale test affermerebbe che gli identificatori devono contenere solo cifre e verrebbero scritti per consentire agli utenti degli identificativi di filiale di assumere lo stesso. O forse c'è un'unità da qualche parte che importa identificatori di diramazioni reali ma non vede mai quelli di test e che potrebbero essere testati in unità per garantire che rifiuta tutti gli identificatori di test (se gli identificatori sono solo tre caratteri possiamo enumerarli tutti e confrontare il comportamento di il validatore a quello del filtro test per assicurarsi che corrispondano, che si occupa della solita obiezione ai test spot). Quindi, quando qualcuno ha cambiato le regole, il test unitario avrebbe fallito poiché contraddiceva il comportamento appena richiesto.

Dal momento che il test è stato lì per una buona ragione, il punto in cui è necessario rimuoverlo a causa delle mutate esigenze aziendali diventa un'opportunità per qualcuno di ottenere il lavoro ", trovare ogni posto nel codice che si basa sul comportamento che vogliamo modificare". Naturalmente questo è difficile e quindi inaffidabile, quindi non garantirebbe assolutamente di salvare la giornata. Ma se catturi i tuoi presupposti nei test delle unità di cui stai assumendo le proprietà, allora ti sei dato una possibilità e quindi lo sforzo non è completamente sprecato.

Concordo ovviamente sul fatto che se l'unità non fosse stata definita in primo luogo con un input "divertente", non ci sarebbe nulla da testare. Le divisioni difficili dello spazio dei nomi possono essere difficili da testare correttamente perché la difficoltà non sta nell'implementare la tua divertente definizione, sta nel fare in modo che tutti capiscano e rispettino la tua divertente definizione. Questa non è una proprietà locale di un'unità di codice. Inoltre, cambiare un tipo di dati da "una stringa di cifre" a "una stringa di caratteri alfanumerici" è simile a far gestire Unicode a un programma basato su ASCII: non sarà semplice se il tuo codice è fortemente accoppiato alla definizione originale, e quando il tipo di dati è fondamentale per ciò che fa il programma, quindi spesso è fortemente accoppiato.

è un po 'inquietante pensare che sia uno sforzo ampiamente sprecato

Se a volte i tuoi test unitari falliscono (mentre stai eseguendo il refactoring, per esempio), e nel farlo ti danno informazioni utili (la tua modifica è sbagliata, per esempio), lo sforzo non è stato sprecato. Quello che non fanno è verificare se il tuo sistema funziona. Quindi, se stai scrivendo unit test invece di avere test funzionali e di integrazione, potresti usare il tuo tempo in modo subottimale.


Le affermazioni sono buone!

3
@nocomprende: come Reagan aveva, "fidati, ma verifica".
Steve Jessop,

1
Stavo per dire anche "Test unitari cattivi!" ma pensavo che la maggior parte delle persone avrebbe perso il riferimento alla fattoria degli animali e avrebbe iniziato a criticare me invece di pensare a quello che stavo dicendo (le risposte istintive sono inefficaci) ma non l'ho detto. Forse una persona che è più intelligente e ha una maggiore erudizione può fare questo punto.

2
"Tutti i test stanno superando, ma alcuni test sono PIÙ superati di altri!"
Graham,

1
il test è un'aringa rossa. Questi ragazzi semplicemente non sapevano come fosse definito il "codice di filiale". Sarebbe come se l'ufficio postale americano non sapesse che stava cambiando la definizione di codice postale quando ha aggiunto 4 cifre.
radarbob,

120

I test unitari avrebbero potuto rilevare che i codici delle filiali 10B e 10C erano erroneamente classificati come "rami di prova", ma trovo improbabile che i test per quella classificazione delle filiali siano stati sufficientemente ampi da rilevare tale errore.

D'altra parte, i controlli a campione dei rapporti generati avrebbero potuto rivelare che i rapporti ramificati 10B e 10C erano costantemente mancanti dai rapporti molto prima dei 15 anni in cui il bug era ora autorizzato a rimanere presente.

Infine, questo è un buon esempio del perché non è una buona idea mescolare i dati di test con i dati di produzione reali in un database. Se avessero utilizzato un database separato che contiene i dati dei test, non sarebbe stato necessario filtrarli dai report ufficiali e sarebbe stato impossibile filtrare troppo.


80
+1 I test unitari non possono mai compensare decisioni di progettazione sbagliate (come test di miscelazione e dati reali)
Jeutnarg

5
Sebbene sia meglio evitare di mescolare i dati di test con dati reali, può essere difficile convalidare un sistema di produzione se ciò richiede la modifica di dati reali. Ad esempio, è una cattiva idea convalidare un sistema bancario modificando i totali dei conti bancari nella produzione. L'uso di intervalli di codici per designare il significato è problematico. Un attributo più esplicito dei record sarebbe stato probabilmente una scelta migliore.
JimmyJames,

4
@Voo Penso che ci sia un tacito presupposto che esista un livello di complessità o requisito di affidabilità in cui il test del sistema di produzione effettivo e distribuito è considerato utile o necessario. (Considera quanto potrebbe andare storto a causa di una variabile di configurazione errata.) Potrei vedere che questo è il caso di un grande istituto finanziario.
jpmc26

4
@Voo non sto parlando di test. Sto parlando della convalida del sistema. In un vero sistema di produzione, ci sono molti modi in cui può fallire che non hanno nulla a che fare con il codice. Se stai mettendo in produzione un nuovo sistema bancario, potresti avere qualche problema nel database o nella rete, ecc. Che impedisce l'applicazione delle transazioni ai conti. Non ho mai lavorato in una banca, ma sono abbastanza sicuro che non vedrà l'ora di iniziare a modificare i conti reali con transazioni false. Questo ti lascia con l'impostazione di account falsi o aspettare e pregare.
JimmyJames,

12
@JimmyJames In ambito sanitario è comune copiare periodicamente il database di produzione nell'ambiente di test per eseguire test su dati il ​​più vicino possibile al reale; Penso che una banca possa fare lo stesso.
dj18

75

Il software doveva gestire alcune regole aziendali. Se ci fossero test unitari, i test unitari avrebbero verificato che il software gestisse correttamente le regole aziendali.

Le regole aziendali sono cambiate.

Apparentemente nessuno ha capito che le regole aziendali erano cambiate e nessuno ha cambiato il software per applicare le nuove regole aziendali. Se ci fossero stati test unitari, quei test unitari avrebbero dovuto essere cambiati, ma nessuno lo avrebbe fatto perché nessuno si era reso conto che le regole commerciali erano cambiate.

Quindi no, i test unitari non l'avrebbero colto.

L'eccezione sarebbe se i test unitari e il software fossero stati creati da team indipendenti e il team che eseguiva i test unitari modificasse i test per applicare le nuove regole aziendali. Quindi i test unitari sarebbero falliti, il che si spera avrebbe comportato una modifica del software.

Ovviamente nello stesso caso se solo il software fosse cambiato e non i test unitari, anche i test unitari fallirebbero. Ogni volta che un test unitario fallisce, non significa che il software sia sbagliato, significa che il software o il test unitario (a volte entrambi) sono sbagliati.


2
È possibile avere team diversi in cui uno sta lavorando sul codice e l'altro su test "unitari"? Com'è possibile? ... Sto refactoring il mio codice in ogni momento.
Sergio,

2
@Sergio da un punto di vista, il refactoring cambia gli interni mentre preserva il comportamento - quindi se il test è scritto in modo da testare il comportamento senza fare affidamento sugli interni, non è necessario aggiornarlo.
Daenyth,

1
L'ho visto succedere diverse volte. Il software è in produzione senza lamentele, poi all'improvviso gli utenti esplodono con lamentele per il fatto che non funziona più e che si sono gradualmente guastati nel corso degli anni. Questo è ciò che accade quando decidi di andare a modificare le tue procedure interne senza seguire la procedura di notifica standard ...
Brian Knoblauch,

42
"Le regole aziendali sono cambiate" è l'osservazione critica. I test unitari confermano che hai implementato la logica che pensavi di aver implementato , non che la tua logica fosse corretta .
Ryan Cavanaugh,

5
Se ho ragione su ciò che è accaduto, è improbabile che vengano scritti test unitari per catturare questo. Il principio di base per selezionare i test è testare alcuni casi "buoni", alcuni casi "cattivi" e casi che racchiudono eventuali limiti. In questo caso, verifichi "099", "100" e "101". Dato che "10B" era coperto dai test "rifiuta non numeri" nel vecchio sistema, ed è maggiore di 101 (e quindi è coperto dai test che) sotto il nuovo sistema, non c'è motivo di testarlo - tranne che in EBCDIC, "10B" ordina tra "099" e "100".
Mark

29

No. Questo è uno dei grandi problemi con i test unitari: ti cullano in un falso senso di sicurezza.

Se tutti i test vengono superati, ciò non significa che il sistema funzioni correttamente; significa che tutti i test stanno superando . Significa che le parti del tuo progetto a cui hai pensato e scritto consapevolmente i test funzionano come pensavi consapevolmente che avrebbero fatto, il che non è comunque un grosso problema: quelle erano le cose a cui stavi prestando molta attenzione a, quindi è molto probabile che tu abbia capito bene comunque! Ma non fa nulla per individuare casi a cui non hai mai pensato, come questo, perché non hai mai pensato di scrivere un test per loro. (E se lo avessi fatto, avresti saputo che ciò significava che erano necessarie modifiche al codice e le avresti cambiate.)


17
Mio padre mi chiedeva: perché non hai pensato alla cosa a cui non hai pensato? (Solo lui lo rendeva confuso dicendo "Se non lo sai, chiedi !") Ma come faccio a sapere che non lo so?

7
"Significa che le parti del tuo progetto a cui hai pensato e scritto consapevolmente i test funzionano come pensavi consapevolmente che farebbero." Completamente giusto. Questa informazione è preziosa se stai eseguendo il refactoring o se qualcosa cambia da qualche altra parte nel sistema che interrompe i tuoi presupposti. Gli sviluppatori che sono cullati da un falso senso di sicurezza semplicemente non comprendono i limiti del test unitario, ma ciò non rende i test unitari uno strumento inutile.
Robert Harvey,

12
@MasonWheeler: Come te, l'autore pensa che il test unitario dovrebbe in qualche modo dimostrare che il tuo programma funziona. Non Consentitemi di ripeterlo: il test unitario non dimostra che il vostro programma funzioni. I test unitari dimostrano che i tuoi metodi soddisfano il contratto di collaudo, e questo è tutto. Il resto del foglio cade, perché si basa su quella singola premessa invalida.
Robert Harvey,

5
Naturalmente, gli sviluppatori che hanno questa falsa convinzione rimarranno delusi quando i test unitari falliranno completamente, ma questo è colpa dello sviluppatore, non dei test unitari, e non invalida il valore reale fornito dal test unitario.
Robert Harvey,

5
o_O @ la tua prima frase. I test unitari ti danno un falso senso di sicurezza durante la codifica come avere le mani sul volante ti dà un falso senso di sicurezza durante la guida.
Djechlin,

10

No, non necessariamente.

Il requisito originale era di utilizzare codici di derivazione numerici, quindi sarebbe stato prodotto un test unitario per un componente che accettava vari codici e rifiutava qualsiasi 10B. Il sistema sarebbe stato passato come funzionante (quale era).

Quindi, il requisito sarebbe cambiato e i codici aggiornati, ma ciò avrebbe comportato la modifica del codice unit test che ha fornito i dati errati (che ora sono buoni dati).

Ora supponiamo che, le persone che gestiscono il sistema sapessero che era così e avrebbero cambiato il test unitario per gestire i nuovi codici ... ma se sapessero che si stava verificando, avrebbero anche saputo cambiare il codice che gestiva questi codici comunque .. e non l'hanno fatto. Un test unitario che inizialmente respingeva il codice 10B avrebbe detto felicemente "qui va tutto bene" se non si sapesse di aggiornare quel test.

I test unitari sono utili per lo sviluppo originale ma non per i test di sistema, in particolare non 15 anni dopo che i requisiti sono stati dimenticati a lungo.

Ciò di cui hanno bisogno in questo tipo di situazione è un test di integrazione end-to-end. Uno in cui puoi trasmettere i dati che prevedi funzionino e vedere se lo fanno. Qualcuno avrebbe notato che i suoi nuovi dati di input non producevano un rapporto e quindi avrebbero indagato ulteriormente.


Spot on. E il problema principale (solo?) Con i test unitari. Mi ha salvato formulando la mia risposta, poiché avrei detto esattamente la stessa cosa (ma probabilmente peggio!) :)
Razze di leggerezza in orbita

8

Il test di tipo (il processo di test degli invarianti che utilizzano dati validi generati casualmente, come esemplificato dalla libreria di test Haskell QuickCheck e varie porte / alternative ispirate da esso in altre lingue) potrebbe aver colto questo problema, il test di unità quasi sicuramente non avrebbe fatto .

Questo perché quando le regole per la validità dei codici delle filiali sono state aggiornate, è improbabile che qualcuno avrebbe pensato di testare quegli intervalli specifici per assicurarsi che funzionassero correttamente.

Tuttavia, se il tipo di prova era stato in uso, qualcuno dovrebbe al momento il sistema originale è stato implementato hanno scritto un paio di proprietà, uno per verificare che i codici specifici per rami di prova sono stati trattati come dati di test e uno per verificare che nessun altra codici erano ... quando la definizione del tipo di dati per il codice della filiale è stata aggiornata (che sarebbe stata necessaria per consentire ai test di verificare che una qualsiasi delle modifiche per il codice della filiale dalla cifra al lavoro numerico funzionasse), questo test avrebbe iniziato a testare i valori in la nuova gamma e molto probabilmente avrebbe identificato l'errore.

Naturalmente, QuickCheck è stato sviluppato per la prima volta nel 1999, quindi era già troppo tardi per rilevare questo problema.


1
Penso che sia più normale chiamare questo test basato sulle proprietà, e ovviamente è altrettanto possibile scrivere un test basato sulle proprietà che sarebbe comunque superato dato questo cambiamento (anche se penso che sia più probabile che tu scriva un test che potrebbe trovarlo)
jk.

5

Dubito davvero che i test unitari farebbero la differenza per questo problema. Sembra una di quelle situazioni di visione del tunnel perché la funzionalità è stata modificata per supportare i nuovi codici di diramazione, ma non è stata eseguita in tutte le aree del sistema.

Utilizziamo i test unitari per progettare una classe. La riesecuzione di un test unitario è necessaria solo se il progetto è stato modificato. Se una determinata unità non cambia, i test unitari invariati restituiranno gli stessi risultati di prima. I test unitari non ti mostreranno l'impatto delle modifiche ad altre unità (se lo fanno non stai scrivendo test unitari).

È possibile rilevare ragionevolmente questo problema solo tramite:

  • Test di integrazione - ma dovresti aggiungere specificamente i nuovi formati di codice per alimentare più unità nel sistema (cioè ti mostrerebbero il problema solo se i test originali includessero i rami ora validi)
  • Test end-to-end: l'azienda deve eseguire un test end-to-end che includa i formati di codice filiale vecchi e nuovi

Non avere test end-to-end sufficienti è più preoccupante. Non è possibile fare affidamento sul test dell'unità come test SOLO o PRINCIPALE per le modifiche del sistema. Sembra che solo qualcuno abbia bisogno di eseguire un rapporto sui formati di codice di filiale appena supportati.


2

Un'asserzione integrata nel runtime potrebbe aver aiutato; per esempio:

  1. Crea una funzione come bool isTestOnly(string branchCode) { ... }
  2. Utilizzare questa funzione per decidere quali report filtrare
  3. Riutilizzare quella funzione in un'asserzione, nel codice di creazione del ramo, per verificare o affermare che un ramo non è (non può essere) creato usando questo tipo di codice ramo‼
  4. Abilitare questa affermazione in tempo reale (e non "ottimizzata via tranne nella versione per sviluppatori del codice solo per debug")‼

Guarda anche:


2

L'asporto da questo è Fail Fast .

Non abbiamo il codice, né abbiamo molti esempi di prefissi che sono o non sono test di prefissi di ramo in base al codice. Tutto ciò che abbiamo è questo:

  • 089 - 100 => ramo di prova
  • 10B, 10C => ramo di prova
  • <088 => rami presumibilmente reali
  • > 100 => rami presumibilmente reali

Il fatto che il codice consenta numeri e stringhe è più che strano. Naturalmente, 10B e 10C possono essere considerati numeri esadecimali, ma se i prefissi sono tutti trattati come numeri esadecimali, 10B e 10C non rientrano nell'intervallo di test e verrebbero trattati come rami reali.

Questo probabilmente significa che il prefisso è memorizzato come una stringa ma trattato in alcuni casi come un numero. Ecco il codice più semplice che mi viene in mente che replica questo comportamento (usando C # a scopo illustrativo):

bool IsTest(string strPrefix) {
    int iPrefix;
    if(int.TryParse(strPrefix, out iPrefix))
        return iPrefix >= 89 && iPrefix <= 100;
    return true; //here is the problem
}

In inglese, se la stringa è un numero compreso tra 89 e 100, è un test. Se non è un numero, è un test. Altrimenti non è un test.

Se il codice segue questo modello, nessun test unit avrebbe rilevato ciò al momento della distribuzione del codice. Ecco alcuni esempi di test unitari:

assert.isFalse(IsTest("088"))
assert.isTrue(IsTest("089"))
assert.isTrue(IsTest("095"))
assert.isTrue(IsTest("100"))
assert.isFalse(IsTest("101"))
assert.isTrue(IsTest("10B")) // <--- business rule change

Il test unitario mostra che "10B" deve essere trattato come un ramo di test. L'utente @ gnasher729 sopra afferma che le regole aziendali sono cambiate ed è quello che mostra l'ultima affermazione sopra. Ad un certo punto quell'asserzione avrebbe dovuto passare a un isFalse, ma ciò non è accaduto. I test unitari vengono eseguiti in fase di sviluppo e di costruzione, ma successivamente in nessun momento.


Qual è la lezione qui? Il codice ha bisogno di un modo per segnalare che ha ricevuto input imprevisti. Ecco un modo alternativo per scrivere questo codice che sottolinea che si aspetta che il prefisso sia un numero:

// Alternative A
bool TryGetIsTest(string strPrefix, out bool isTest) {
    int iPrefix;
    if(int.TryParse(strPrefix, out iPrefix)) {
        isTest = iPrefix >= 89 && iPrefix <= 100;
        return true;
    }
    isTest = true; //this is just some value that won't be read
    return false;
}

Per coloro che non conoscono C #, il valore restituito indica se il codice è stato in grado di analizzare un prefisso dalla stringa specificata. Se il valore restituito è true, il codice chiamante può utilizzare la variabile isTest out per verificare se il prefisso del ramo è un prefisso di test. Se il valore restituito è falso, il codice chiamante dovrebbe segnalare che il prefisso specificato non è previsto e che la variabile isTest out è insignificante e deve essere ignorata.

Se sei d'accordo con le eccezioni, puoi farlo invece:

// Alternative B
bool IsTest(string strPrefix) {
    int iPrefix = int.Parse(strPrefix);
    return iPrefix >= 89 && iPrefix <= 100;
}

Questa alternativa è più semplice. In questo caso, il codice chiamante deve intercettare l'eccezione. In entrambi i casi, il codice dovrebbe avere un modo per segnalare al chiamante che non si aspettava uno strPrefix che non potesse essere convertito in un numero intero. In questo modo il codice fallisce rapidamente e la banca può trovare rapidamente il problema senza l'imbarazzo della SEC.


1

Così tante risposte e nemmeno una citazione di Dijkstra:

I test mostrano la presenza, non l'assenza di bug.

Pertanto, dipende. Se il codice è stato testato correttamente, molto probabilmente questo errore non esisterebbe.


-1

Penso che un test unitario qui avrebbe garantito che il problema non esistesse in primo luogo.

Considera, hai scritto la bool IsTestData(string branchCode)funzione.

Il primo test unit che scrivi dovrebbe essere per stringa nulla e vuota. Quindi per stringhe di lunghezza errate quindi per stringhe non intere.

Per superare tutti questi test dovrai aggiungere il controllo dei parametri alla funzione.

Anche se poi testerai solo dati "buoni" 001 -> 999 non pensando alla possibilità di 10A, il controllo dei parametri ti costringerà a riscrivere la funzione quando inizi a usare i caratteri alfanumerici per evitare le eccezioni che genererà


1
Ciò non avrebbe aiutato: la funzione non è stata modificata e il test non inizierà a fallire dati gli stessi dati di test. Qualcuno avrebbe dovuto pensare di cambiare il test per farlo fallire, ma se ci avessero pensato, probabilmente avrebbero pensato di cambiare anche la funzione.
Hulk,

(O forse mi manca qualcosa, dato che non sono sicuro di cosa intendi per "controllo dei parametri")
Hulk,

La funzione sarebbe costretta a lanciare un'eccezione per le stringhe non intere in ordine per superare il test unitario del caso limite. Quindi il codice di produzione avrebbe un errore se avessi iniziato a usare i codici delle filiali alfanumerici senza una programmazione specifica per loro
Ewan,

Ma la funzione non avrebbe usato qualche funzione IsValidBranchCodeper eseguire questo controllo? E questa funzione sarebbe probabilmente stata cambiata senza la necessità di modificare il IsTestData? Pertanto, se si stanno solo testando "dati validi", il test non avrebbe aiutato. Il test del caso limite avrebbe dovuto includere un codice di filiale ora valido (e non semplicemente alcuni ancora non validi) per iniziare a fallire.
Hulk,

1
Se il controllo è in IsValidCode, in modo che la funzione passi senza il suo controllo esplicito, quindi sì è possibile perderlo, ma poi avremmo un set aggiuntivo di ancora più test, finti validatori ecc. Ancora più possibilità per specifici "questi sono numeri di prova "
Ewan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.