2012-03-05 7 views
9

C#Tigerコンパイラを書きましたが、TigerコードをILに翻訳します。私のコンパイラ(ILを生成する)のユニットテストを書く

私のASTのすべてのノードのセマンティックチェックを実装している間、私はこれのためにたくさんのユニットテストを作成しました。私CheckSemantic方法はこのようになりますので、それは、非常に単純です:

public override void CheckSemantics(Scope scope, IList<Error> errors) { 
... 
} 

をので、私はいくつかのノードのセマンティックチェックのためのいくつかのユニットテストを書きたい場合は、私がしなければならないすべては、ASTを構築しており、コールその方法。そして、私のような何かを行うことができます:

Assert.That(errors.Count == 0); 

または

Assert.That(errors.Count == 1); 
Assert.That(errors[0] is UnexpectedTypeError); 
Assert.That(scope.ExistsType("some_declared_type")); 

が、私はこの瞬間にコード生成を始めている、と私はユニットテストを書くときには良い習慣何ができるか分かりませんその段階のために。

私はILGeneratorクラスを使用しています。私は、次のことについて考えてきました:ファイル内

  • 実行
  • は、そのファイルを実行し、出力を保存することを、私は
  • 保存をテストするサンプルプログラムのコードを生成します
  • アサートに対するそのファイル

しかし、私はそれを行うより良い方法があるのだろうか?

答えて

14

これは、私たちのILジェネレータをテストするためにC#コンパイラチームが行うことです。

また、生成された実行可能ファイルをILDASMで実行し、期待どおりにILが生成されていることを確認し、PEVERIFYを実行して検証可能なコードを生成していることを確認します。 (私たちは意図的に検証できないコードを生成しているような場合ではもちろん除きます。)

+0

それは知っているのは良いことです。そんなやり方でやるよ。私は、たくさんのテストの実行と、ディスク上のファイルの作成、読み込み、および削除のパフォーマンスについてちょっと心配していました。 –

+3

@OscarMederos:パフォーマンスが十分でない場合は、(1)できるだけ遅いものを把握するためにプロファイリングするか、(2)すべてのチェックインでいくつかのテストを実行するようにテスト戦略を変更する、一晩中実行し、週末に実行するものもあります。そうすれば、迅速に問題を発見し、徹底したテストを行うことができます。 –

0

あなたは二つのことやってテストを考えることができます:出力はあなたが知らせる

  • を変更した場合は、知らせる

    何かが変更されたかどうかを判断することは、何かが間違っているかどうかを判断するよりもかなり高速な場合が多いため、テスト。

    同じ実行可能ファイルの既知の良い(または正常な)コピーが作成された後に実行ファイルが変更されていないことをすぐに判断できる場合は、毎回コンパイラによって生成された実行可能ファイルを実行する必要はありません。

    予想される差異(たとえば、埋め込まれた日付を固定値に設定するなど)を排除するために、テストしている出力に対して少量の操作を行う必要がありますが、完了したら変更検出検証は基本的にファイルの比較であるため、テストは簡単に作成できます。出力は最後の正常出力と同じですか?はい:合格、いいえ:失敗。

    コンパイラによって生成された実行可能ファイルを実行してパフォーマンスの問題が発生し、それらのプログラムの出力の変化を検出する場合は、実行可能ファイル自体を比較することでステージを早期に検出するテストを実行することができます。

  • 1

    私はpost-compiler in C#を作成していると私は、突然変異したCILテストするには、このアプローチを使用:temp file

    1. Save the assembly、私はそれで終わりだ後に削除されます。
    2. PEVerify~check the assemblyを使用してください。問題がある場合は、それを既知の場所にコピーしてさらにエラー分析を行います。
    3. アセンブリの内容をテストします。私の場合は、別のAppDomainでほとんどloading the assembly dynamicallyです(私は後で解読できるので)class in thereを実行します(自己検査アセンブリのようなものです:here's a sample implementation)。

    また、this answerに統合テストの規模を調整する方法についていくつかのアイデアを示しました。

    関連する問題