Come si può TDD per un bug che può essere testato solo dopo che è stato corretto?


13

Ecco un esempio: la mia applicazione web contiene elementi trascinabili. Quando si trascina un elemento, il browser produce una "immagine fantasma". Voglio rimuovere "l'immagine fantasma" durante il trascinamento e scrivo un test per questo comportamento.

Il mio problema è che inizialmente non ho idea di come risolvere questo bug e l'unico modo in cui posso scrivere un test è dopo averlo risolto.

In una semplice funzione come let sum = (a, b) => a - b, è possibile scrivere un test sul perché sum(1, 2)non è uguale 3prima di scrivere qualsiasi codice.

Nel caso che sto descrivendo, non posso testare, perché non so quale sia la verifica (non so quale dovrebbe essere l'asserzione).

Una soluzione al problema descritto è:

let dataTransfer = e.dataTransfer
let canvas = document.createElement('canvas');
canvas.style.opacity = '0';
canvas.style.position = 'absolute';
canvas.style.top = '-1000px';
dataTransfer.effectAllowed = 'none';

document.body.appendChild(canvas);
dataTransfer.setDragImage(canvas, 0, 0);

Non avrei saputo che questa era la soluzione. Non avrei nemmeno potuto scrivere il test dopo aver trovato la soluzione online, perché l'unico modo in cui avrei potuto sapere se funzionava davvero, era aggiungere questo codice nella mia base di codice e verificare con il browser se avesse avuto l'effetto desiderato. Il test doveva essere scritto dopo il codice, che va contro TDD.

Quale sarebbe l'approccio TDD a questo problema? Scrivere il test prima del codice è obbligatorio o facoltativo?


2
Fai la tua ricerca allora. Trova una soluzione ... quindi scrivi il tuo test, correzione e refactor. I test non hanno lo scopo di (solo) verificare il corretto funzionamento del codice, ma di rendere la soluzione completa a prova di futuro. Inizialmente crei il test per fallire, quindi, quale proprietà testerai? Questo è un modo per iniziare.
Juan Carlos Eduardo Romaina Ac,

@Kilian Foth: vedo le tue buone intenzioni cambiando il titolo della domanda, ma la modifica delle parti invalide della mia risposta. Inoltre, il tuo nuovo titolo IMHO non si adattava bene al corpo della domanda. Quindi ho fatto un rollback, senza offesa.
Doc Brown,

Risposte:


26

Quando ti ho capito correttamente, non puoi nemmeno scrivere un test automatico affidabile per il tuo esempio di "immagine fantasma" dopo aver trovato una soluzione, poiché l'unico modo per verificare il comportamento corretto è guardare lo schermo e controllare se non ci sono immagini fantasma più. Questo mi dà l'impressione che il titolo originale abbia posto la domanda sbagliata. La vera domanda dovrebbe essere

  • come testare automaticamente un determinato comportamento di un'interfaccia utente grafica?

E la risposta è: per diversi tipi di problemi con l'interfaccia utente, non è così . Certo, si può provare ad automatizzare l'interfaccia utente mostrando il problema in qualche modo, e provare a implementare qualcosa di simile a un confronto di schermate, ma questo è spesso soggetto a errori, fragile e non economico.

Soprattutto la progettazione dell'interfaccia utente "test driving" o i miglioramenti dell'interfaccia utente mediante test automatici scritti in anticipo sono letteralmente impossibili. "Guidate" la progettazione dell'interfaccia utente apportando un miglioramento, mostrate il risultato a un essere umano (voi stessi, alcuni tester o un utente) e chiedete feedback.

Quindi accetta il fatto che TDD non è un proiettile d'argento, e per qualche tipo di problemi i test manuali hanno più senso dei test automatizzati. Se hai un processo di test sistematico, magari con alcuni tester dedicati, la cosa migliore che puoi fare è aggiungere il caso al loro piano di test.


In generale, il test dell'interfaccia utente non è banale; è possibile bloccare, ad esempio, l'hash di un'immagine generata, è possibile simulare / automatizzare, è possibile registrare macro, è possibile utilizzare una soluzione proprietaria, è possibile utilizzare i test manuali, dipende dalla situazione e da quanto è necessario il test automatico dell'interfaccia utente per il proprio progetto.
esoterik,

1
@esoterik: sì, e tutte queste tecniche automatizzate sono soggette a errori e fragili, come ho già scritto. L'unico approccio non fragile che conosco è il test manuale.
Doc Brown,

3
Grazie per aver risposto. Penso che tu abbia ragione, spero erroneamente di trovare un proiettile d'argento in TDD. Non sembra esserci un modo efficace per testare ciò che voglio testare: il confronto delle schermate e tutto quanto sopra non sembrano fornire un ROI sufficiente. Il confronto delle schermate in particolare sembra richiedere molto tempo e, come hai detto, soggetto a errori.
maximedupre,

1
@maximedupre: trovato questo annuncio per uno strumento che cerca di risolvere il problema, ma l'articolo sembra essere in accordo con la mia risposta in generale.
Doc Brown,

5

Quale sarebbe l'approccio TDD a questo problema? Scrivere il test prima del codice è obbligatorio o facoltativo?

Un modo è applicare un analogo di una soluzione a spike .

James Shore lo descrisse in questo modo:

Eseguiamo piccoli esperimenti isolati quando abbiamo bisogno di ulteriori informazioni.

L'idea di base è che metti giù gli strumenti di progettazione mentre stai capendo cosa sta succedendo. Una volta che hai i cuscinetti, raccogli nuovamente gli strumenti di progettazione.

Il trucco: riportate le conoscenze della vostra indagine nella vostra base di codice di produzione, ma non portate il codice . Invece, lo ricrea quando si utilizzano le tecniche di progettazione disciplinate.

Cavalli per i corsi.

MODIFICARE:

Come si può automatizzare un test se il difetto può essere visto solo da un occhio umano?

Vorrei suggerire un'ortografia leggermente diversa: "Come è possibile automatizzare un test se automatizzare il test non è conveniente?"

La risposta, ovviamente, è "non lo fai". Invece, cerca di separare l'implementazione in due parti: una grande parte in cui i test sono convenienti e una parte più piccola che è troppo semplice per essere interrotta.

Esistono due modi per costruire un progetto software: un modo è renderlo così semplice che ovviamente non ci sono carenze: CAR Hoare

Quindi, quando lavoriamo con codice di terze parti, avremo una shell di codice molto sottile che funge da proxy per la libreria di terze parti. Nel test, sostituiamo quella shell con un "test double", che verifica il protocollo , senza preoccuparsi che produca gli effetti desiderati.

Per testare l'integrazione dei nostri codici con il vero codice di terze parti, facciamo affidamento su altre tecniche (verifica visiva, chiamate al supporto tecnico, ottimismo ....)

Può essere utile conservare alcuni artefatti dimostrativi, in modo da poter verificare che i tuoi presupposti siano ancora validi quando aggiorni la libreria di terze parti.


Adoro quello che James Shore ha da dire. Attualmente sto seguendo lo screencast www.letscodejavascript.com e sto imparando molto. Leggerò i link che mi hai indicato.
maximedupre,

Hai ragione, ho letto di più su TDD e picchi. In realtà devi sapere come appare il codice che stai provando a controllare prima di provare a testarlo. TDD non può insegnarti nulla che non conosci già, ma può potenzialmente mostrarti alcune cose che devi imparare, parafrasando James Shore. In tale nota, vorrei proporre un passaggio aggiuntivo nel TDD: Spike, Test, Fail, Pass, Refactor.
maximedupre

0

Solo in una prospettiva diversa, i test sull'interfaccia utente / sulla GUI possono essere eseguiti in qualche modo meglio rispetto ai test di accettazione (test centrati sul flusso di lavoro aziendale / aziendale).

Per il web, penso che framework come il webdriver al selenio abbiano il potenziale per avvicinarsi al test corretto, ma il sovraccarico per iniziare potrebbe essere un po 'troppo, ed è uno spostamento nel flusso visto con TDD rispetto ai soli test unitari .

La parte che potrebbe aiutare specificamente con la tua situazione è qualcosa chiamata Page Object Model ( https://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html ). Ciò consente di ottenere una mappatura esplicita della GUI di runtime su alcuni codici, nominando metodi / eventi / membri della classe.

Le principali argomentazioni contrarie sarebbero le spese generali e che queste spese generali potrebbero essere viste alla fine del ciclo di sviluppo. Il sovraccarico è che i test richiedono un wrapper che sembrerebbe creare un lavoro duplicato.

Andando avanti, dipenderà dal costo / beneficio del team e del business, quindi potrebbe essere un argomento utile da discutere per determinare aspettative e opinioni.


Recentemente stavo provando e2e / test funzionali (con webdriver al selenio) in TDD di recente, ma l'overhead è decisamente troppo grande come hai detto. Non puoi essere uno sviluppatore efficiente e fare TDD con i test e2e. Stavo usando POM, ma l'unico vantaggio che mi ha dato è stata un'architettura migliorata nella mia base di codice di test.
maximedupre,

Sì, penso che un'opzione più praticabile che ho visto da diverse società a diversi team sarebbe quella di incorporare un processo SQA più manuale, in cui un membro del team / team è designato per eseguire solo test manuali dall'IU. I test hanno principalmente schermate e documentazione dettagliata. Per lo meno, qualcosa del genere produrrebbe alcune prove di test per un'applicazione.
eparham7861,

0

Che aspetto ha un'immagine fantasma? Se hai creato un'interfaccia utente fittizia di un colore noto, dove metti il ​​tuo componente trascinabile? Ci sarebbe un colore specifico presente se ci fosse un'immagine fantasma.

Quindi il test potrebbe verificare l'assenza del colore dell'immagine fantasma.

Tale test sarebbe ragionevole e durevole.


Fattibile - si. Durevole: dipende. Il solo cambiamento del colore / tema dell'interfaccia utente potrebbe interrompere il / i test / i, il che non mi sembra troppo duraturo.
Sean Burton,

1
Non metteresti alla prova l'intera UI. Dovresti creare un'interfaccia utente fittizia per il componente drag-n-drop.
Esben Skov Pedersen,

Non sono sicuro di come realizzare ciò che stai suggerendo. Un'immagine fantasma nel mio caso sarebbe una replica semi-opaca dell'elemento che viene trascinato. L'immagine fantasma segue sempre il cursore mentre si verifica il trascinamento della selezione.
maximedupre,

Sì. Dovresti automatizzare il trascinamento. Non sarebbe un test unitario ma piuttosto un test e2e.
Esben Skov Pedersen,
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.