`make check` または `make test` の実装 質問する

`make check` または `make test` の実装 質問する

Make を使用して簡単な回帰テスト フレームワークを実装するにはどうすればよいですか? (GNU Make を使用しています。)

私の現在の makefile は次のようになります (簡単にするために編集されています)。

OBJS = jscheme.o utility.o model.o read.o eval.o print.o

%.o : %.c jscheme.h
    gcc -c -o $@ $<

jscheme : $(OBJS)
    gcc -o $@ $(OBJS)

.PHONY : clean

clean :
    -rm -f jscheme $(OBJS)

回帰テストのセットが欲しいのですが、例えばexpr.in「良い」 式をテストし、unrecognized.in「悪い」 式をテストします。expr.cmp& はunrecognized.cmpそれぞれの期待される出力です。 手動テストは次のようになります。

$ jscheme < expr.in > expr.out 2>&1
$ jscheme < unrecognized.in > unrecognized.out 2>&1
$ diff -q expr.out expr.cmp # identical
$ diff -q unrecognized.out unrecognized.cmp
Files unrecognized.out and unrecognized.cmp differ

私は次のような一連のルールを makefile に追加しようと考えました:

TESTS = expr.test unrecognized.test

.PHONY test $(TESTS)

test : $(TESTS)

%.test : jscheme %.in %.cmp
    jscheme < [something.in] > [something.out] 2>&1
    diff -q [something.out] [something.cmp]

質問:
• [something] プレースホルダーには何を入力すればよいですか? • 送信元のメッセージを「テストに失敗しました」というメッセージに
置き換える方法はありますか?diffexpr

ベストアンサー1

質問に述べられているように、あなたのオリジナルのアプローチは最善です。各テストは、予想される入力と出力のペアの形式になっています。Make はこれらを反復処理してテストを実行する能力が非常に高いため、シェルforループを使用する必要はありません。実際、これを行うと、テストを並列実行する機会が失われ、一時ファイル (必要ありません) をクリーンアップするための余分な作業が発生します。

解決策は次のとおりです(紀元前例:

SHELL := /bin/bash

all-tests := $(addsuffix .test, $(basename $(wildcard *.test-in)))

.PHONY : test all %.test

BC := /usr/bin/bc

test : $(all-tests)

%.test : %.test-in %.test-cmp $(BC)
    @$(BC) <$< 2>&1 | diff -q $(word 2, $?) - >/dev/null || \
    (echo "Test $@ failed" && exit 1)

all : test 
    @echo "Success, all tests passed."

このソリューションは、当初の質問に直接答えます。

  • 探しているプレースホルダーは$<、それぞれ$(word 2, $?)前提条件とに対応している と%.test-inです%.test-cmp。@reinierpost のコメントとは反対に、一時ファイルは必要ありません。
  • diff メッセージは非表示になり、 を使用して置き換えられますecho
  • make -k個々のテストが失敗するか成功するかに関係なく、すべてのテストを実行するには、makefile を呼び出す必要があります。
  • make -k allすべてのテストが成功した場合にのみ実行されます。

all-tests変数を定義する際に、ファイル命名規則(*.test-in)とGNU makeを利用することで、各テストを手動で列挙することを避けています。ファイル名の関数ボーナスとして、変数の長さが数万のテストにすぐに対応できるソリューションであることを意味します。無制限GNU makeでは、これはオペレーティングシステムにぶつかると落ちてしまうシェルベースのソリューションよりも優れています。コマンドライン制限

おすすめ記事