Questo è un estratto dall'eBook Testing Unit Affinity, di Marc Clifton, gentilmente fornito da Syncfusion.
Il test unitario ha anche valore per altri scopi.
Uno dei vantaggi collaterali dei test unitari è che crea una grande base di codice che esemplifica come utilizzare il codice. Ad esempio, il codice che abbiamo visto prima:
[Test] public void FilenameParsingTest () Dictionaryoptions = CommandLineParser.Parse ("- f foobar"); Assert.That (options.Count == 1, "Count expected to be 1"); Assert.That (options.ContainsKey ("- f"), "Expected option '-f'"); Assert.That (opzioni ["- f"] == "foobar");
documenta un caso d'uso valido previsto per il parser della riga di comando. Prendi in considerazione anche la scrittura di test unitari, non solo per il tuo codice, ma anche per fornire esempi di librerie di terze parti. (Vedi gli esempi successivi e le cose interessanti rivelate sulla struttura di Rectangle.)
Il test della scatola nera presuppone che non si sappia nulla dei componenti interni della classe o del servizio e si sta verificando il suo comportamento rigorosamente dalle interfacce esposte pubblicamente. Questo è spesso necessario quando non si dispone del codice disponibile. Ad esempio, quando si lavora con una società di gestione dei record, ci è stato richiesto di utilizzare un servizio Web fornito da un'agenzia governativa per aggiornare i record. Scrivendo unit test per il servizio web, siamo stati in grado di dimostrare che la documentazione fornita non ha comportato il comportamento previsto del servizio web.
È possibile utilizzare questa tecnica anche quando si lavora con codice fornito da diversi reparti. Ad esempio, il gruppo di database potrebbe avere il proprio test dell'unità della scatola bianca; tuttavia, dovresti anche verificare che dal punto di vista della scatola nera, i trigger e i vincoli siano stati programmati correttamente controllando il risultato delle transazioni dalla funzionalità che è esposta a te.
Il test delle unità può essere un modo semplice per mettere insieme alcuni test riguardanti le nostre ipotesi su un'API. Prendiamo il System.Drawing.Rectangle
strutturare e testare alcune supposizioni apparentemente ragionevoli sull'implementazione.
Ci sono due Rettangolo
costruttori: uno avendo Punto
e Taglia
parametri, l'altro con parametri x, y, larghezza e altezza. La documentazione non indica se la dimensione (larghezza o altezza) deve essere positiva, quindi scriviamo un test per verificare che possiamo costruire un rettangolo con larghezza o altezza negativa:
[TestMethod] public void RectangleNegativeSizeConstructorTest () Rectangle r = new Rectangle (0, 0, -4, -6);
Tutto quello che stiamo facendo qui in questo test sta verificando che non vengono generate eccezioni quando costruiamo il rettangolo, e in effetti, questo è il caso:
Test del costruttore di rettangoliOra proviamo le nostre ipotesi su certe proprietà. Le proprietà Superiore
, Sinistra
, Parte inferiore
, e Destra
sono descritti come (vedi
http://msdn.microsoft.com/en-us/library/system.drawing.rectangle.aspx):
Top: ottiene la coordinata y del bordo superiore di questa struttura Rectangle.
Sinistra: Ottiene la coordinata x del bordo sinistro di questa struttura Rettangolo.
In basso: ottiene la coordinata y che è la somma dei valori delle proprietà Y e Height di questa struttura Rectangle.
Destra: ottiene la coordinata x che è la somma dei valori delle proprietà X e Larghezza di questa struttura Rettangolo.
Quindi, con il rettangolo precedente, con larghezza e altezza negative e quindi con coordinate [(-4, -6), (0, 0)], faremo le seguenti ipotesi:
[TestMethod] public void TestLeft () Rectangle r = new Rectangle (0, 0, -4, -6); Assert.IsTrue (r.Left == -4, "Left previsto == -4 ma era" + r.Left); [TestMethod] public void TestTop () Rectangle r = new Rectangle (0, 0, -4, -6); Assert.IsTrue (r.Top == 0, "Top atteso == 0 ma era" + r.Top); [TestMethod] public void TestRight () Rectangle r = new Rectangle (0, 0, -4, -6); Assert.IsTrue (r.Right == 0, "Diritto previsto == 0 ma era" + r.Right); [TestMethod] public void TestBottom () Rectangle r = new Rectangle (0, 0, -4, -6); Assert.IsTrue (r.Bottom == -6, "Inferiore previsto == -6 ma era" + r.Bottom);
Tuttavia, questo non è il caso:
Test delle ipotesi sulle proprietà del rettangoloIn effetti, la determinazione di top e bottom appare totalmente arbitraria, poiché ho eseguito test esattamente sulle stesse dimensioni del rettangolo e ho osservato risultati diversi nel Superiore
e Parte inferiore
valori di proprietà.
La documentazione MSDN afferma che il Rectangle.Intersect
metodo:
Pertanto, possiamo costruire un semplice test:
[TestMethod] public void TestIntersection () Rectangle r1 = new Rectangle (0, 0, 10, 10); Rectangle r2 = new Rectangle (10, 10, 5, 5); Assert.IsFalse (r1.IntersectsWith (r2), "Previsto R1 e R2 non intersecano."); Assert.IsTrue (Rectangle.Intersect (r1, r2) == Rectangle.Empty, "Previsto un rettangolo di intersezione vuoto.");
con il risultato:
Test delle nostre ipotesi sul metodo di restituzioneQuesto ci informa che le nostre aspettative, basate sulla documentazione, non sono corrette.
Il test delle unità è uno strumento importante nel processo di test. Sebbene i test di integrazione e usabilità siano spesso più incentrati sul cliente (reporting, traguardi, verifica dei requisiti di alto livello), il test unitario è la prima linea di difesa per un programmatore, il suo team e i team manager. Se usato con giudizio (ricorda, non stai mirando a creare migliaia di belle luci verdi), può essere un modo economico per verificare la correttezza computazionale del codice e per ricreare i bug e verificare che siano stati corretti.
Tuttavia, le buone pratiche di test unitario richiedono un approccio disciplinato, un impegno per il tempo e gli sforzi richiesti per implementare e mantenere i test, e, dal punto di vista di un programmatore, richiede anche buone pratiche di programmazione e spesso impone decisioni architetturali. Quest'ultimo può volare di fronte a vincoli "just get it done" (che possono essere abbastanza legittimi), e potrebbe avere un impatto negativo sulle prestazioni. Sul lato positivo, le pratiche di programmazione e le architetture che i test unitari impongono all'utilizzatore sono spesso di grande beneficio per l'intero processo di sviluppo dell'applicazione, riducendo così i costi e migliorando la manutenibilità, non perché il codice è testato unitamente, ma perché il codice è scritto meglio così che può essere unità testata.