Mi sto allenando per testare le unità (in particolare con il Test-driven design o Red-Green-Refactor) mentre scrivevo un parser di discesa ricorsivo per un semplice linguaggio specifico del dominio. Nel tentativo di testare unitamente un metodo che accetta i token e gli output di un albero della sintassi, ho scoperto che il mocking dell'input è eccessivamente complesso. Avevo pensato che il mio progetto iniziale per l'interfaccia pubblica fosse testabile; è questo problema nella progettazione dell'interfaccia pubblica, o inerente ai test di trasformazione dei dati di alto livello?
Il mio test è stato semplificato per mostrare l'interfaccia di base ...
[TestFixture]
public class ParserTests
{
[TestFixture]
public class Parser_ParseTests
{
...
[Test]
public void Parser_Parse_IfTokenSourceIsNullThrowException()
{
Parser parser = new Parser ();
TokenSource tokens = null;
Action action = () => parser.Parse(tokens);
Assert.Throws<System.NullReferenceException>(() => action.Invoke ());
}
...
}
}
Ovviamente, i test con cui ho un problema sono quelli che necessitano di TokenSource che riempi con un gran numero di token.
Il mio primo pensiero è che forse il mio test copre troppo. Forse dovrei solo prendere in giro e verificare che i token siano richiesti dalla sorgente token e lasciare il testing delle trasformazioni token alle classi dipendenti. Ciò lascerebbe comunque una lacuna nella descrizione dei miei test dello scopo di questa interfaccia e la rende dipendente da altri test per convalidarlo.
Potrebbe anche darsi che il mio codice non sia verificabile, ma sto faticando a vedere un altro modo per strutturarlo. So che voglio un'interfaccia che trasformi un input in un Syntax Tree e che dividerò il processo in Tokenisation (di una stringa di origine) e analizzerò i Token. Forse non dovrebbe esserci un livello di astrazione che conosca l'analisi dei token ma non la tokenizzazione?
Per cercare di ottenere idee ho esaminato i test unitari di Fitnesse, che conoscevo avevano una buona copertura e devono trasformare set di dati complessi (codice Wiki in HTML). Non sono sicuro che segua le buone pratiche che dovrei emulare però. Ad esempio, BaseWikiPage sembra utilizzare un numero di oggetti dall'effettivo progetto ( WikiPageUtil
, PathParser
ecc.) per produrre dati di test.
Questa è una buona pratica? Il mio problema principale è che mi richiede di scrivere codice relativo alle astrazioni di livello inferiore come i token che non ero ancora pronto per progettare. Inoltre, il codice Test richiede che io scriva prima il codice funzionale, il che significa scrivere prima altri test Unit, implicitamente facendo dipendere questo test da quelli. Fondamentalmente, mi impedisce di scrivere questo test.
Mi piacerebbe conoscere sia la soluzione del mondo reale per questo tipo di test sia la soluzione ideale. O la mia intera comprensione dello scopo di questi test rende la domanda irrilevante?