Come utilizzare BDD per testare un compilatore?

8

Il mio team sta scrivendo un compilatore per un linguaggio specifico del dominio (DSL) che sarà integrato in un IDE. Al momento, ci concentriamo sulla fase di analisi del compilatore. Noi siamo non utilizzando qualsiasi generatore di parser esistente (come ANTLR) perché abbiamo bisogno di prestazioni in tempo reale e di informazioni di errore / avvertimento / messaggio altamente dettagliate. Abbiamo

  1. classi, ognuna delle quali rappresenta un nodo nell'albero di sintassi concreto per la lingua, nonché
  2. classi che fungono da annotazioni per ogni nodo (ad esempio, per errori e informazioni aggiuntive), nonché
  3. classi interne che creano e manipolano l'albero di sintassi concreto (cioè lexer, parser, cache per le stringhe, visitatori della sintassi).

Stiamo cercando di decidere una strategia globale per organizzare i nostri test. La nostra azienda sta spingendo lo sviluppo orientato al comportamento (BDD) e il design basato sul dominio (DDD). Sebbene stiamo costruendo una DSL per il dominio della nostra azienda, il dominio del compilatore è un linguaggio di programmazione.

Siamo ancora in fase di costruzione del compilatore e abbiamo già alcuni test. Puntiamo ad avere una copertura informativa del 100%.

Al momento disponiamo di test in cui inseriamo il codice sorgente nel tree builder della sintassi e quindi eseguiamo una verifica su ogni proprietà di ogni nodo dell'albero di sintassi risultante per assicurarci che le informazioni attese (numero di riga, errore pertinente (s ), token figlio / genitore, larghezza del token, tipo di token, ecc.). Ora, dato che ogni nodo è una sua classe, e alcune annotazioni e errori collegati a un nodo sono classi separate, questo test finisce per riferirsi a molte classi.

Al momento abbiamo test per alcune classi come il lexer in cui possiamo isolare l'input (una stringa) e l'output (una lista di token) da altre classi (ad esempio, le classi per i nodi dell'albero della sintassi) . Questi test sono più granulari.

Ora, i test nel paragrafo immediatamente precedente possono essere messi in corrispondenza con la classe sotto test (ad es. lexer, cache delle stringhe). Tuttavia, i test del secondo paragrafo sopra testano davvero l'intera fase di analisi del compilatore; cioè, ogni test può avere oltre 300 asserzioni per l'albero di sintassi, dato il codice sorgente di input. I test sono per il comportamento della fase di analisi.

Questa è una strategia di test appropriata? Se no, cosa dovremmo fare diversamente? Quale strategia organizzativa dovremmo utilizzare per i nostri test?

    
posta cm007 11.09.2013 - 23:16
fonte

1 risposta

5
  > Is this an appropriate testing strategy?

No , perché il tuo sottodominio è un DSL (un tipo di linguaggio di programmazione) e il tuo compilatore fa parte di un dettaglio di implementazione per il caso d'uso che consente di automatizzare azioni / flussi di lavoro in questo dominio utilizzando il DSL.

Poiché non so come appare il tuo DSL, presumo che tu abbia concetti come loop , condition , statement , variable usando l'esempio

 for(int i=1;i =< 10;i++) {subtask();}

Usando un linguaggio simile a bdd-gherkin potresti scrivere qualcosa come

as a automation user
i want to have a for loop with startvalue, endvalue, loopincrement
so that i can repeat subtasks several times.

given startvalue=1
and endvalue = 10
and loopinclrement = 1
when i execute for(int i=%startvalue%;i =< %endvalue %;i+=%loopinclrement%)
then the subtask should have been executet 10 times.

Questo è un bel po 'di lavoro per dimostrare che il tuo compilatore funziona come previsto.

  > If not, what should we be doing differently? 
  > What organization strategy should we use for our tests?

Creerei un grande archivio di esempi per l'input con l'output corrispondente.

Il test automatizzato eseguirà l'iterazione degli esempi e verificherà che l'output del compilatore corrisponda all'output previsto.

Esempio: se la tua fattura / dsl correlato all'ordine compila in java una voce di repository dovrebbe essere simile a:

 example: loop over orderentries
 dsl-source: foreach orderitem in orders do calculateTaxes(orderitem)
 expected errormessage: none
 expected java output: for(OrderItemType orderitem : orders) 
                          {calculateTaxes(orderitem);}

 example: loop with syntax errors
 dsl-source: foreach orderitem in orders 
 expected errormessage: missing "do"-keyword in line 1
 expected java output: none

Quindi, invece di scrivere molto codice per adattarsi a bdd, devi semplicemente aggiungere esempi di valori di input / output codificati.

    
risposta data 14.09.2013 - 15:37
fonte

Leggi altre domande sui tag