13

私は Brainfuck 用のインタープリターの作成を実験してきました。作成と実行は非常に簡単ですが、それに対してテストを実行できるようにしたいと考えています。実装が適切であることを確認するために、考えられるすべての命令の組み合わせをテストするために、どれだけ多くのテストを作成する必要があるか、私にはわかりません。

明らかに、Brainfuck の命令セットは小さいですが、命令が追加されると、テスト コードが指数関数的に大きくなると思わずにはいられません。とにかく、典型的なテストよりもそうです。

さて、私はコンパイラーとインタープリターを書くという点であなたが得ることができるのと同じくらい初心者なので、私の仮定はかなり間違っている可能性があります.

基本的に、このようなもののテストはどこから始めますか?

4

6 に答える 6

11

コンパイラのテストは、他の種類のアプリのテストとは少し異なります。コンパイラがプログラムのさまざまなアセンブリ コード バージョンを生成しても、それらがすべて正しいことを行う限り問題ないからです。ただし、インタープリターをテストするだけであれば、他のテキストベースのアプリケーションとほとんど同じです。以下は Unix 中心のビューです。

  1. 回帰テスト スイートを作成する必要があります。各テストには
    • あなたが解釈するソースコード、例えばtest001.bf
    • 解釈するプログラムへの標準入力、たとえばtest001.0
    • インタープリターが標準出力で生成することを期待するもの、たとえばtest001.1
    • インタープリターが標準エラーで生成することを期待するもの、たとえばtest001.2 (インタープリターのエラーメッセージをテストしたいので標準エラーを気にします)
  2. 次のようなことを行う「テスト実行」スクリプトが必要になります。

    function fail {
      echo "Unexpected differences on $1:"
      diff $2 $3
      exit 1
    }
    
    for testname
    do
      tmp1=$(tempfile)
      tmp2=$(tempfile)
      brainfuck $testname.bf < $testname.0 > $tmp1 2> $tmp2
      [ cmp -s $testname.1 $tmp1 ] || fail "stdout" $testname.1 $tmp1
      [ cmp -s $testname.2 $tmp2 ] || fail "stderr" $testname.2 $tmp2
    done
    
  3. 次のようなことを行う「テストの作成」スクリプトがあると便利です。

    brainfuck $testname.bf < $testname.0 > $testname.1 2> $testname.2
    

    インタープリターがそのケースで機能することを完全に確信している場合にのみ、これを実行します。

  4. テスト スイートをソース管理下に置きます。

  5. 空であると予想されるファイルを除外できるように、テスト スクリプトを装飾すると便利です。

  6. 何かが変わるたびに、すべてのテストを再実行します。また、cron ジョブを介して毎晩再実行することもあるでしょう。

  7. 最後に、十分な数のテストを追加して、コンパイラのソース コードの十分なテスト カバレッジを取得する必要があります。カバレッジ ツールの品質はさまざまですが、GNU Gcovは適切なカバレッジ ツールです。

通訳頑張ってください!愛情を込めて作成されたが、十分に文書化されていないテスト インフラストラクチャを見たい場合は、 Quick C-- コンパイラtest2のディレクトリを参照してください。

于 2009-03-28T00:55:38.437 に答える
2

コンパイラのテストに関して「特別な」ことは何もないと思います。ある意味では、一部のプログラムをテストするよりもほとんど簡単です。コンパイラにはそのような基本的な高レベルの要約があるためです。ソースを渡すと、(おそらく)コンパイルされたコードと(おそらく)一連の診断メッセージが返されます。

他の複雑なソフトウェアエンティティと同様に、多くのコードパスがありますが、すべて非常にデータ指向(テキスト入力、テキスト入力、バイト出力)であるため、テストを作成するのは簡単です。

于 2009-03-28T00:12:17.497 に答える
2

私はコンパイラのテストに関する記事を書きましたが、その最初の結論 (出版のために少しトーンダウンしました) は次 のとおりでした。 既存のソリューションについてすべて知っていて、それらを無視する正当な理由がある場合を除き、既存のツールを調べることから始める必要があります。開始するのに最も簡単な場所はGnu C Tortureですが、これは Deja Gnu に基づいていることに注意してください。これには問題があります。(Hello World の例に関する重大なバグ レポートをメーリング リストに投稿 することをメンテナに許可してもらうまでに、6 回の試みが必要でした。)

ツールを調査するための出発点として、以下を参照することをお勧めします。

  1. ソフトウェア: 実践と経験2007 年 4 月. (ペイウェア、一般公開されていない --- http://pobox.com/~flash/Practical_Testing_of_C99.pdfで無料のプレプリント。

  2. http://en.wikipedia.org/wiki/Compiler_correctness#Testing (大部分は私が書いたものです。)

  3. コンパイラ テストの参考文献(見逃した更新があれば教えてください。)

于 2009-04-09T18:54:56.620 に答える
1

brainfuckの場合、それをテストするのはbrainfuckスクリプトで行うべきだと思います。ただし、次のことをテストします。

1:すべてのセルが0に初期化されていますか

2:現在最初のセルを指しているときにデータポインタをデクリメントするとどうなりますか?ラップしますか?無効なメモリを指していますか?

3:最後のセルを指しているときにデータポインタをインクリメントするとどうなりますか?ラップしますか?無効なメモリを指していますか

4:出力は正しく機能しますか

5:入力は正しく機能しますか

6:[]のものは正しく機能しますか

7:バイトを255回以上インクリメントした場合、適切に0にラップされた場合、または整数またはその他の値として誤って処理された場合はどうなりますか。

より多くのテストも可能ですが、これはおそらく私が始めるところです。私は数年前にBFコンパイラを作成しましたが、それにはいくつかの追加テストがありました。特に、ブロック内に多くのコードを含めることで、[]のものを徹底的にテストしました。これは、初期バージョンのコードジェネレーターで問題が発生したためです(jxxを使用するx86では、ブロックが128バイト以上を生成するときに問題が発生しました。コード、無効なx86 asmになります)。

于 2009-03-28T00:21:25.960 に答える
-1

いくつかの既に作成されたアプリでテストできます。

于 2009-03-28T00:11:48.403 に答える
-3

秘密は次のとおりです。

  • 懸念事項を分離する
  • デメテルの法則を守る
  • 依存関係を注入する

まあ、テストが難しいソフトウェアは、開発者が 1985 年のようにそれを書いたことを示しています。申し訳ありませんが、ここで提示した 3 つの原則を利用すると、行番号の BASIC でさえユニット テスト可能になります (依存関係を挿入することは可能です)。 BASIC、「goto variable」ができるからです。

于 2010-07-08T05:52:46.497 に答える