Wdrożenie `make check " lub " make test`
Jak zaimplementować prosty framework testu regresji za pomocą Make? (Używam GNU Make, jeśli to ma znaczenie.)
Mój obecny makefile wygląda mniej więcej tak (edytowany dla uproszczenia):
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)
Chciałbym mieć zestaw testów regresyjnych, np., expr.in
testowanie wyrażenia "dobrego" & unrecognized.in
testowanie wyrażenia "złego", z expr.cmp
& unrecognized.cmp
jako oczekiwany wynik dla każdego. Testy manualne wyglądałyby tak:
$ 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
Pomyślałem, aby dodać zestaw zasad do makefile wygląda tak:
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]
Moje pytania: * Co umieścić w [coś] placeholders?
• Czy istnieje sposób na zastąpienie wiadomości z
diff
Komunikatem "Test expr
nie powiódł się"? 4 answers
Twoje oryginalne podejście, jak wspomniano w pytaniu, jest najlepsze. Każdy z Twoich testów ma formę pary oczekiwanych wejść i wyjść. Make jest całkiem zdolny do iteracji i uruchamiania testów; nie ma potrzeby używania pętli Powłoki for
. W rzeczywistości w ten sposób tracisz możliwość równoległego uruchamiania testów i tworzenia dodatkowej pracy dla siebie, aby oczyścić pliki tymczasowe (które nie są potrzebne).
Oto rozwiązanie (używając bc jako przykład):
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."
Rozwiązanie bezpośrednio odpowiada na twoje oryginalne pytania:
- symbole zastępcze, których szukasz, to
$<
i$(word 2, $?)
, odpowiadające odpowiednio wymogom wstępnym%.test-in
i%.test-cmp
. W przeciwieństwie do komentarza @ reinierpost pliki tymczasowe nie są potrzebne. - wiadomość diff jest ukryta i zastąpiona przez
echo
. - plik makefile powinien być wywoływany z
make -k
, aby uruchomić wszystkie testy niezależnie od tego, czy pojedynczy test się nie powiedzie lub / align = "left" / -
make -k all
będzie działać tylko wtedy, gdy wszystkie testy się powiodą.
Unikamy ręcznego wyliczania każdego testu podczas definiowania zmiennej all-tests
, wykorzystując konwencję nazewnictwa plików (*.test-in
) i funkcje GNU make dla nazw plików. Jako bonus oznacza to, że rozwiązanie skaluje się do dziesiątek tysięcy testów po wyjęciu z pudełka, ponieważ długość zmiennych jest nieograniczona W GNU make. Jest to lepsze niż rozwiązanie oparte na powłoce, które spadnie po trafieniu system operacyjny limit linii poleceń .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-09 17:53:23
Tworzy skrypt runnera testowego, który pobiera nazwę testu i wyprowadza z niego dane wejściowe, wyjściowe i smaple:
#!/bin/bash
set -e
jscheme < $1.in > $1.out 2>&1
diff -q $1.out $1.cmp
Wtedy w twoim Makefile
:
TESTS := expr unrecognised
.PHONY: test
test:
for test in $(TESTS); do bash test-runner.sh $$test || exit 1; done
Możesz również spróbować zaimplementować coś w rodzaju automake
'S simple test framework .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-13 20:51:47
To z czym skończyłem wygląda tak:
TESTS = whitespace list boolean character \
literal fixnum string symbol quote
.PHONY: clean test
test: $(JSCHEME)
for t in $(TESTS); do \
$(JSCHEME) < test/$$t.ss > test/$$t.out 2>&1; \
diff test/$$t.out test/$$t.cmp > /dev/null || \
echo Test $$t failed >&2; \
done
Jest oparty na pomyśle Jacka Kelly ' ego, z dołączoną wskazówką Jonathana Lefflera.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-10 22:37:52
Odpowiem na twoje pytanie o diff. Można zrobić:
diff file1 file2 > /dev/null || echo Test blah blah failed >&2
Chociaż możesz chcieć użyć cmp zamiast diff.
Z innej uwagi, może okazać się pomocne, aby przejść do przodu i wziąć zanurz i użyj automake. Twój Makefile.am (w całości) będzie wyglądać tak:
bin_PROGRAMS = jscheme jscheme_SOURCES = jscheme.c utility.c model.c read.c eval.c print.c jscheme.h TESTS = test-script
I otrzymasz za darmo mnóstwo naprawdę ładnych celów, w tym całkiem w pełni funkcjonalny framework testowy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-08 12:53:20