Che cos'è il test dell'unità black box?


11

Di recente ho avuto il mio esame finale per un corso di ingegneria del software per il mio programma di master e una delle domande sull'esame era la seguente:

Unit Testing is considered:
a. White-box Testing
b. Black-box Testing
c. Either

Nei miei 7 anni di esperienza nello sviluppo di software, i test unitari hanno sempre adottato un approccio white box. Il tester ha sempre avuto piena conoscenza dell'implementazione dell'unità durante la scrittura dei test. I test sulla scatola nera sono sempre arrivati ​​più tardi nelle forme di test di integrazione, sistema e accettazione.

Tuttavia, la risposta corretta all'esame (secondo il professore) è che i test unitari possono essere test su scatola bianca o nera.

Ho fatto alcune ricerche, e sembra che molti casi "test di unità della scatola nera" siano usati per descrivere un approccio test-first in cui i test unitari sono scritti prima che il codice sia. Tuttavia, a mio avviso, si tratta ancora di test in scatola bianca. Sebbene l'implementazione non esista ancora, chiunque stia scrivendo il test in genere ha una buona idea di come verrà implementato il codice sorgente.

Qualcuno può spiegarmi come funziona il test delle unità della scatola nera (se è veramente una cosa) e in che modo differisce dai test delle unità della scatola bianca?


4
in che modo il professore ha chiarito questo aspetto quando glielo hai chiesto? (vedi anche Perché le domande di intervista rendono scarse le domande su Software Engineering.SE? )
moscerino del

"chi sta scrivendo il test ha generalmente una buona idea di come il test sta per essere implementato" - non è sul fatto che si sa come è implementato il test, ma se si sa (bianco) o meno (nero) come la cosa stai testando è implementato.
Jesper,

@Jesper mi dispiace. Volevo dire "come verrà implementato il codice sorgente". L'ho risolto nella domanda.
backcab il

2
While the implementation does not yet exist, whoever is writing the test generally has a pretty good idea about how the source code is going to be implemented.- Sì, ma il test stesso no. Test in white box significa testare qualcosa di interno al metodo o alla classe, come il valore di una variabile. Ciò non significa che chi scrive il test sappia come appare il codice in prova.
Robert Harvey,

1
Correlato, potrebbe essere visto come un duplicato: TDD utilizza formalmente i test in scatola nera per integrare i test unitari
Doc Brown,

Risposte:


20

Il tuo professore ha ragione: il test unitario può essere sia black-box che white-box. La differenza è minore di ciò che il tester sa, ma di più su come generare casi di test.

Con il test della scatola nera, guardi solo l'interfaccia e (se esiste) le specifiche per un componente. Quando una funzione ha una firma int foo(int a, int b), posso immediatamente generare alcuni casi di test semplicemente testando numeri interi interessanti: zero, uno, meno uno, numeri a più cifre, INT_MAX, INT_MAX - 1 e così via. I test della scatola nera sono eccezionali perché sono indipendenti dall'implementazione. Ma potrebbero anche mancare casi importanti.

Con un test in white box, guardo l'implementazione, cioè il codice sorgente e da ciò provochi casi di test. Ad esempio, potrei voler ottenere una copertura del percorso del 100% per una funzione. Scelgo quindi i valori di input in modo che vengano presi tutti i percorsi. I test in white box sono fantastici perché possono esercitare in modo esaustivo un pezzo di codice, con molta più sicurezza rispetto ai test in black box. Ma potrebbero solo testare i dettagli dell'implementazione, non in realtà un comportamento importante. In alcuni casi, sono chiaramente una perdita di tempo.

Poiché un test in white box è derivato dall'implementazione, può essere scritto solo in seguito. Un test in black box deriva dal design / interfaccia / specifica e può quindi essere scritto prima o dopo l'implementazione. TDD non è né chiaramente scatola nera né scatola bianca. Poiché tutto il comportamento viene prima espresso da un test e quindi viene implementato il codice minimo per quel comportamento, TDD si traduce in casi di test simili a quelli di un white box. Ma quando osserviamo il flusso di informazioni, i test TDD non derivano dal codice sorgente, ma da requisiti esterni. Pertanto, TDD è più simile a una scatola nera.


3
"Poiché un test in white box è derivato dall'implementazione, può essere scritto solo in seguito" - beh, se ho intenzione di scrivere un test fallito in stile TDD per la nuova nuova funzione che mi piacerebbe aggiungere alla mia funzione o classe esistente , Guardo prima all'implementazione attuale per scoprire cosa non è supportato finora, quindi posso progettare un test più significativo - inizialmente fallito -. Lo chiamo un approccio whitebox test-first, non un test scritto in seguito. (Tuttavia, +1 da me).
Doc Brown,

4

Se stai intraprendendo uno sviluppo guidato dai test, in teoria tutti i tuoi test unitari dovrebbero essere black-box. Questo è il tuo "approccio test-first". Scrivi il contratto (interfaccia), scrivi i test per quel contratto e quindi il contratto viene adempiuto dall'implementazione. Il test quindi non sa nulla e non dovrebbe sapere nulla dell'implementazione.

Dopo tutto, quando scrivi un test, cosa stai testando? Metodi / funzioni pubblici.

Se dovessi scrivere l'interfaccia per una classe, quindi scrivere i test, e poi verrai colpito da un autobus, il tipo che scrive la classe mentre sei in ospedale dovrebbe essere in grado di farlo dalla tua interfaccia, giusto? Non avrebbe dovuto buttarlo via e scrivere la sua interfaccia e i suoi test.

Il punto in cui questo va in pezzi è quando devi deridere qualcosa da cui dipende l'implementazione, ma se ti trovi nella situazione in cui stai deridendo qualcosa che non viene mai esposto pubblicamente, allora hai fatto un errore e devi guarda Dependency Injection et al . Pertanto, direi che il test unitario in scatola bianca, non nero, dovrebbe essere l'eccezione.

Considera "Test sul water - Test Behavior Not Implementation" , in cui l'implementazione di una classe viene modificata ma i test dovrebbero essere ancora validi.

Tuttavia, se devi assicurarti che la copertura del tuo codice sia attiva (ovvero assicurati che tutti i percorsi condizionali siano testati all'interno dell'implementazione), allora avresti assolutamente bisogno di test unitari in white box, perché l'unico modo in cui puoi sapere quali sono i tuoi i percorsi sono guardando i percorsi nell'implementazione.


2
If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right?-- Non esattamente. La maggior parte dei contratti API specifica solo le firme dei metodi, non la semantica o il comportamento.
Robert Harvey,

Hai ragione; Ho dato per scontato che la tua interfaccia includesse le specifiche da cui è stata scritta, non letteralmente solo il testo di MyClassInterface.
AdamJS,

@RobertHarvey è vero che la maggior parte delle interfacce non descrivono esplicitamente la semantica o il comportamento, ma penso che sia generalmente lì implicitamente. Se non fosse presente, il codice che richiede una certa semantica non sarebbe in grado di dipendere dall'astrazione. E non c'è nulla che fermi le interfacce, inclusi i dettagli della semantica e del comportamento come commenti / docblocs. Ad esempio, vedi github.com/php-fig/http-message/blob/master/src/…
bdsl

3

Direi che tutti i test unitari ben scritti sono intrinsecamente "scatola nera". Sicuramente potrei avere in mente un'implementazione quando scrivo il test, ma quell'implementazione può cambiare quando refactoring. Quindi il test dovrebbe usare solo API pubbliche durante il test per testare la funzionalità, non l'implementazione. Non si preoccupa dei dettagli di implementazione, quindi il suo test black box.

Se scrivo test che accedono ad aspetti interni o privati ​​dell'unità in prova, allora sto testando i dettagli dell'implementazione: sono test white box. Ma sto anche scrivendo test fragili che possono facilmente rompersi quando l'implementazione viene modificata. Quindi, tali test su scatola bianca sono una cattiva idea e dovrebbero essere evitati.

Conclusione: se esegui un test in white box con test unitari, hai dei test costruiti male. Solo back box test con quei test unitari. Il tuo professore ha ragione: può essere uno dei due. Ma solo se fatto male.


1

Stavo solo scrivendo test unitari che eseguivano test black-box. Cioè, sto testando metodi pubblici in una classe e implicando la logica di test dei risultati nei metodi privati ​​che chiamano.

Lo faccio modificando gli input per il metodo pubblico in fase di test unitario e testando gli output previsti determinati o mutati dalla logica nei metodi privati ​​di supporto, la cui implementazione, i miei "test unitari" non devono sapere nulla.

Quindi, non c'è nulla che ti impedisca di eseguire i test della scatola nera sui test unitari e i test si interromperanno se qualcuno sbaglia con l'implementazione della logica di supporto nascosta. In effetti, questo sembra un approccio superiore, più efficiente, rispetto alle unità white box che testano tutto in una classe per il gusto di farlo. Sono con il professore.

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.