BDDを使用してコンパイラを単体テストする方法


8

私のチームは、IDEに統合されるドメイン固有言語(DSL)のコンパイラを作成しています。現在、私たちはコンパイラーの分析フェーズに集中しています。リアルタイムのパフォーマンスと非常に詳細なエラー/警告/メッセージ情報が必要なため、既存のパーサージェネレーター(ANTLRなど)使用していません。我々は持っています

  1. 各クラスは、言語の具体的な構文ツリーのノードを表します。
  2. 各ノードの注釈として機能するクラス(つまり、エラーや追加情報)、および
  3. 具体的な構文ツリー(つまり、レクサー、パーサー、文字列のキャッシュ、構文ビジター)を構築および操作する内部クラス。

テストを整理するための全体的な戦略を決定しようとしています。当社は、行動主導型開発(BDD)とドメイン主導型設計(DDD)を推進しています。弊社のドメイン用にDSLを構築していますが、コンパイラのドメインはプログラミング言語です。

私たちはまだコンパイラーを構築中であり、すでにいくつかのテストを行っています。100%ステートメントカバレッジを目指しています。

現在、構文ツリービルダーにソースコードを入力し、結果の構文ツリーのすべてのノードの各プロパティで検証を実行して、期待される情報(行番号、関連するエラー、子/親トークン、トークンの幅、トークンのタイプなど)。ここで、各ノードは独自のクラスであり、ノードに添付された特定の注釈とエラーは個別のクラスであるため、このテストは多くのクラスを参照することになります。

現在、入力(文字列)と出力(トークンのリスト)を他のクラス(構文ツリーのノードのクラスなど)から分離できるレクサーなどの特定のクラスのテストがあります。これらのテストはより詳細です。

これで、すぐ上の段落のテストを、テスト中のクラス(レクサー、文字列キャッシュなど)に対応させることができます。ただし、上記の2番目の段落のテストは、コンパイラーの分析フェーズ全体を実際にテストします。つまり、入力ソースコードが与えられている場合、各テストは構文ツリーに対して300以上のアサーションを持つことができます。テストは、分析フェーズの動作のためのものです。

これは適切なテスト戦略ですか?そうでない場合、私たちは何を別の方法で行うべきですか?テストにはどのような組織戦略を使用する必要がありますか?

回答:


5
  > Is this an appropriate testing strategy?

いいえ、サブドメインはDSL(プログラミング言語の一種)であり、コンパイラーは、DSLを使用してこのドメインのアクション/ワークフローを自動化できるユースケースの実装詳細の一部です。

私はあなたのような概念を持っていることを前提と同様にどのようにあなたのDSLのルックスを知らないのでloopconditionstatementvariable例を使用して

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

bdd-gherkinのような言語を使用して、次のようなものを書くことができます

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.

これは、コンパイラが期待どおりに動作することを証明するためのかなりの作業です。

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

対応する出力を持つ入力用のサンプルの大きなリポジトリを作成します。

自動テストでは、例を繰り返し処理して、コンパイラーの出力が期待される出力と一致することを確認します。

例:請求書/注文関連のDSLがJavaにコンパイルされる場合、リポジトリエントリは次のようになります。

 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

したがって、bddに適合するように多くのコードを記述する代わりに、ハードコードされた入力/出力値の例を追加する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.