Minha equipe está escrevendo um compilador para uma linguagem específica de domínio (DSL) que será integrada a um IDE. No momento, estamos focados na fase de análise do compilador. Estamos não utilizando qualquer analisador geradores existentes (como ANTLR) porque precisamos de desempenho em tempo real e altamente detalhada de erro / aviso / informação mensagem. Nós temos
- classes, cada uma das quais representa um nó na árvore de sintaxe concreta do idioma, bem como
- classes que atuam como anotações para cada nó (por exemplo, erros e informações adicionais), bem como
- classes internas que constroem e manipulam a árvore de sintaxe concreta (ou seja, lexer, analisador, cache de strings, visitantes de sintaxe).
Estamos tentando decidir uma estratégia geral para organizar nossos testes. Nossa empresa está promovendo o desenvolvimento orientado a comportamento (BDD) e o design orientado a domínio (DDD). Embora estejamos criando uma DSL para o domínio de nossa empresa, o domínio do compilador é uma linguagem de programação.
Ainda estamos no processo de construção do compilador e já temos alguns testes. Nosso objetivo é ter 100% de cobertura de declaração.
Atualmente, temos testes nos quais inserimos o código-fonte no construtor de árvores de sintaxe e, em seguida, executamos uma verificação em cada propriedade de cada nó da árvore de sintaxe resultante para garantir que as informações esperadas (número da linha, erros relevantes, filho) / tokens pai, largura do token, tipo de token, etc.). Agora, como cada nó é sua própria classe e certas anotações e erros anexados a um nó são classes separadas, esse teste acaba fazendo referência a muitas classes.
Atualmente, temos testes para determinadas classes, como o lexer, no qual podemos isolar a entrada (uma string) e a saída (uma lista de tokens) de outras classes (por exemplo, as classes dos nós da árvore da sintaxe). Esses testes são mais granulares.
Agora, os testes no parágrafo imediatamente acima podem ser colocados em correspondência com a classe em teste (por exemplo, lexer, cache de strings). No entanto, os testes do segundo parágrafo acima realmente testam toda a fase de análise do compilador; isto é, cada teste pode ter mais de 300 asserções para a árvore de sintaxe, dado o código-fonte de entrada. Os testes são para o comportamento da fase de análise.
Essa é uma estratégia de teste apropriada? Caso contrário, o que devemos fazer de diferente? Que estratégia de organização devemos usar para nossos testes?