Dovrebbero esserci test unitari per espressioni regolari complesse?


34

Devo scrivere unit test per espressioni regolari complesse nella mia domanda?

  • Da un lato: sono facili da testare perché il formato di input e output è spesso semplice e ben definito, e spesso possono diventare così complessi, quindi i test di questi sono specificamente preziosi.
  • D'altra parte: essi stessi fanno raramente parte dell'interfaccia di alcune unità. Potrebbe essere meglio testare l'interfaccia e farlo in modo da testare implicitamente le regex.

MODIFICARE:

Concordo con Doc Brown che nel suo commento osserva che questo è un caso speciale di test unitari dei componenti interni .

Ma poiché le regex dei componenti interni hanno alcune caratteristiche speciali:

  1. Un regex a linea singola può essere davvero complesso senza essere un modulo separato.
  2. Registra l'input della mappa in uscita senza effetti collaterali e quindi è davvero facile da testare separatamente.

12
"essi stessi fanno raramente parte dell'interfaccia di alcune unità." - se le tue classi hanno un codice interessante sepolto in profondità sotto l'interfaccia, suddividi le tue classi. Questo è un esempio di come pensare a tess può migliorare il design.
Nathan Cooper,

3
La stessa domanda in un modo più generale: quali componenti interni dovrebbero essere testati in unità? Vedi programmers.stackexchange.com/questions/16732/…
Doc Brown,

Sorta correlati, vedi Regex101. Hanno una sezione per scrivere test unitari per il tuo regex. Ad esempio: regex101.com/r/tR3mJ2/2
David dice

3
Disclaimer - questo commento è la mia modesta opinione: 1 prima di tutto credo che le regexps complesse siano pure malvagie - vedi anche blog.codinghorror.com/… 2 il valore reale del test di tali espressioni viene quando le provi su un ampio database di data blog.codinghorror.com/testing-with-the-force 3 Ho la strana sensazione che questi test non siano esattamente test unitari
Boris Treukhov,

Risposte:


101

Testando il dogmatismo a parte, la vera domanda è se fornisce valore per testare espressioni regolari complesse. Sembra abbastanza chiaro che fornisce valore (indipendentemente dal fatto che la regex sia parte di un'interfaccia pubblica) se la regex è abbastanza complessa, dal momento che ti permette di trovare e riprodurre bug e prevenire contro le regressioni.


25
+1, ma se un'espressione regolare è abbastanza complessa che questo è un problema, allora probabilmente ha senso per spostarlo in un'unità di "wrapper" con metodi appropriati ( isValid, parse, tryParse, o roba del genere, a seconda esattamente come è in uso) in modo, che il codice client non deve sapere che è attualmente implementato usando una regex. L'unità wrapper avrebbe quindi test dettagliati, che - ancora una volta - non avrebbero bisogno di conoscere l'implementazione corrente. Questi test, ovviamente, stanno di fatto testando la regex, ma in modo agnostico.
Ruakh,

1
Un reg ex è un programma, sebbene in un linguaggio specializzato e molto conciso. Pertanto, il testing è appropriato per le espressioni non banali ... E certamente il codice che sta invocando l'espressione dovrebbe essere testato, il che potrebbe implicitamente testare il riservato.
Keshlam,

6
@ruakh Ben detto. Il vantaggio di una classe wrapper per un regex è che puoi sostituirlo ordinatamente con un codice ordinario se diventa necessario. Il codice con input / output complessi dovrebbe sempre avere unit test, perché è notevolmente difficile eseguire il debug senza. Se è necessario fare riferimento alla documentazione per comprendere gli effetti del codice, è necessario disporre di unit test. Se è solo una rapida mappatura 1: 1 come la conversione di tipo, allora non c'è problema. I regex superano quel punto di richiedere documenti molto rapidamente.
Aaron3468,

4
@Lii: Regexes non merita alcun trattamento speciale. Il regex è l'unità in questo caso, quindi testiamo l'unità.
Jacques,

1
@ruakh Stavo per scrivere una risposta in tal senso. Sono d'accordo che l'utilizzo di regex è un dettaglio di implementazione. Ciò che conta è che le cose convalidino quando dovrebbero, e non riescano a convalidare quando dovrebbero. Prova i FooValidatorsuoi input e output, quindi non ti preoccupare di come viene fatto. ++
RubberDuck,

21

Regex può essere uno strumento potente, ma non è uno strumento di cui ti puoi fidare per funzionare ancora se apporti modifiche anche minori a regex complesse.

Quindi crea un sacco di test che documentano i casi che dovrebbe coprire. E crea molti test che documentano i casi in cui dovrebbe fallire, se viene utilizzato per la convalida.

Ogni volta che devi cambiare le tue regex aggiungi i nuovi casi come test, modifica la tua regex e spera per il meglio.

Se fossi in un'organizzazione che in generale non utilizzava i test unitari, scriverei comunque un programma di test che testerebbe qualsiasi regex che useremmo. Lo farei anche nel mio tempo se dovessi, i miei capelli non hanno bisogno di perdere più colore.


3

Le espressioni regolari sono codice insieme al resto dell'applicazione. Dovresti testare che il codice in generale fa quello che ti aspetti che faccia. Questo ha diversi scopi:

  • I test sono documentazione eseguibile. Dimostra chiaramente cosa devi fare per fare il codice. Se viene testato è importante.
  • I futuri manutentori possono essere certi che se lo modificano, i test assicureranno che il comportamento rimanga invariato.

Dato che c'è un ulteriore ostacolo da superare avendo il codice in una lingua diversa incorporata con il resto, molto probabilmente dovresti prestare questa attenzione in più a beneficio della manutenzione.


1

In breve, dovresti testare la tua domanda, punto. Sia che testiate il vostro regex con test automatici che lo eseguono in modo isolato, come parte di una scatola nera più grande o se vi armeggiate con esso manualmente, è secondario al punto che è necessario assicurarsi che funzioni.

Il vantaggio principale dei test unitari è che risparmiano tempo. Ti permettono di provare la cosa tutte le volte che vuoi ora o in qualsiasi momento in futuro. Se c'è qualche motivo per credere che il tuo regex sarà in ogni momento riformulato, ottimizzato, ottenere più vincoli ecc., Allora sì, probabilmente vorrai alcuni test di regressione per esso, o quando lo cambi, dovrai andare attraverso un'ora di riflessione su tutti i casi limite in modo da non averlo rotto. Quello o impari a convivere con la paura del tuo codice e semplicemente non lo cambi mai.


3
Una regola empirica che ho imparato; se avessi bisogno di documenti per scrivere e ispezionare il codice, avrò bisogno di un test unitario. Mi hanno risparmiato molti mal di testa, catturando puntatori null, nessun tipo e output errato. Offrono anche all'utente finale la possibilità di riparare il codice su specifica con il minimo sforzo quando si rompe inevitabilmente.
Aaron3468,

-1

D'altra parte: essi stessi fanno raramente parte dell'interfaccia di alcune unità. Potrebbe essere meglio testare l'interfaccia e farlo in modo da testare implicitamente le regex.

Penso che con questo tu abbia risposto tu stesso. I regex in un'unità sono molto probabilmente un dettaglio di implementazione.

Ciò che vale per il test del tuo SQL probabilmente vale anche per le regex. Quando cambi un pezzo di SQL, probabilmente lo esegui manualmente tramite alcuni client SQL per vedere se produce ciò che ti aspetti. Lo stesso vale per quando cambio un regex, uso alcuni strumenti regex con alcuni input di esempio per vedere se fa quello che mi aspetto.

Ciò che trovo utile è un commento vicino al regex con un campione di testo che dovrebbe corrispondere.


" Quando cambi un pezzo di SQL, probabilmente lo esegui manualmente attraverso un client SQL per vedere se produce ciò che ti aspetti. " Ma questo tipo di risposta risponde alla domanda nell'altro modo ... Se ho bisogno o penso che sia utile testare le regex a mano, quindi dovrei fare un test unitario per quello. Esattamente questo è ciò che rende difficile decidere!
Lii,

Dipende davvero. Quello che desideri per le tue unit test è la possibilità di apportare modifiche. Con quale frequenza cambi una regex specifica? Se la risposta è spesso, allora crea un test per questo.
Christiaan,

8
A parità di altre condizioni, è meglio avere un test automatizzato piuttosto che un "test manuale".
Robert Harvey,

1
Perché non testare un regex usando l'automazione?
Tony Ennis,

1
Fa parte di un metodo e tutto quello che stavo cercando di dire è che non è necessario testare in modo specifico il regex se lo si prova già. Ma se lo fai probabilmente stai meglio estraendo la regex in una funzione separata che testerai isolatamente.
Christiaan,

-5

Se devi chiedere, la risposta è sì.

Supponiamo che arrivi un po 'di FNG e pensi di poter "migliorare" la tua regex. Ora è un FNG, quindi automaticamente un idiota. Esattamente il tipo di persona che non dovrebbe mai toccare il tuo prezioso codice in nessun caso! Ma forse è legato al PHB o qualcosa del genere, quindi non c'è niente che tu possa fare.

Solo che sai che il PHB ti trascinerà a calci e urlando a questo progetto per "forse dare al ragazzo alcune indicazioni su come hai fatto questo casino" quando tutto va male. Quindi scrivi tutti i casi che hai attentamente considerato quando costruisci il tuo bellissimo capolavoro di espressione.

E dal momento che li hai scritti tutti, sei i due terzi del modo di avere una serie di casi di test, poiché - ammettiamolo - i casi di test regex sono facili da eseguire una volta che hai costruito il framework.

Quindi ora hai una serie di condizioni limite, alternative e risultati attesi. E improvvisamente i casi di test sono la documentazione così come promesso in tutti quei post sul blog Agile. Fai notare all'FNG che se il suo "miglioramento" non supera i casi di test esistenti, non è un gran miglioramento, vero? E dove sono i suoi nuovi casi di prova proposti che dimostrano qualche problema con il codice originale, che dal momento che funziona non ha bisogno di essere modificato, mai !!!


3
che cos'è il FNG? Questa non mi sembra una cattiva risposta, ma manca la definizione di FNG (googlin per questo dà solo risultati non correlati, quindi forse questa risposta è stata semplicemente sottovalutata a causa di FNG?)
GameDeveloper

1
Sospetto che Google ti abbia portato nel posto giusto. ;-) ( en.wikipedia.org/wiki/FNG_syndrome )
Austin Hastings

A meno che tu non sia un vero genio della programmazione, ci saranno programmatori più esperti considerando ciò che ti piace guardare il nuovo ragazzo. Potresti considerare di essere più umile.
Thorbjørn Ravn Andersen,
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.