首页 > 解决方案 > 使用 makefile 进行自动化测试

问题描述

我对makefile非常陌生,只是花了一整天的时间试图弄清楚如何自动化我的测试。对于这个项目,我有一个程序 main.c,它接受输入和输出文件作为参数。输入文件的格式为“test-{filler}.txt”,因此示例文件可以是“test-invalid-opcode.txt”。输出文件的格式为“out-{filler}.txt”,因此格式为“out-invalid-opcode.txt”。然后我想将输出与保存在“正确-{filler}.txt”中的正确输出进行比较,所以这将是“正确-无效-opcode.txt”。因此,每个测试都会有输入、输出和正确输出。我想检查输出和正确输出是否有任何差异,我希望它在每个带有前缀“test-”的测试文件上运行。我阅读了很多makefile规范和很多不同的例子,但我真的很困惑如何处理这个问题。任何帮助将非常感激。

这是我必须运行一项测试的内容:

CC=gcc
CFLAGS=-o

main.o: main.c
    $(CC) $(CFLAGS) main.o $<

.PHONY: test
test: main.o test-provided.txt test-out.cs
    ./program test-provided.txt test-out.txt
    diff -q test-out.txt out-provided.txt

我希望自动测试的布局类似于

.PHONY: autotest
autotest: program
    $(foreach <file with "test-" prefix> run:
        main.o <test-name> <out-name>
        diff -q <correct-name> <out-name>

但我真的迷失了如何去实现它。

谢谢,对不起,我无法发布更多代码。我尝试了很多不同的东西,但它们都没有足够接近以至于值得发布。

编辑以显示工作的最终版本:

program: main.c
$(CC) $(CFLAGS) $a $<

TEST_INPUTS := $(wildcard test-*.txt)
.PHONY: autotest $(TEST_INPUTS)

autotest: $(TEST_INPUTS)

$(TEST_INPUTS): test-%.txt: program
    echo '' > out-$*.txt
    ./$< $@ out-$*.txt
    diff -q correct-$*.txt out-$*.txt

标签: makefile

解决方案


一般来说,使用 make 循环并不是很“make-ish”。makefile 是一种基本上基于迭代和递归的完整语言,因此尝试在配方中进行“额外”迭代通常是多余的。

如果您需要对某些内容进行迭代,尤其是当该内容是文件时,您应该尝试通过利用其目标/先决条件组织来使用 make。上面你给出了一个算法:

$(foreach <file with "test-" prefix> run:
    main.o <test-name> <out-name>
    diff -q <correct-name> <out-name>

这非常适合 make 的默认行为。要将其转换为生成文件,您编写一个调用循环的单次迭代的规则,然后使用先决条件为您想要的文件运行它。像这样的东西:

TEST_INPUTS := $(wildcard test-*.txt)
.PHONY: autotest $(TEST_INPUTS)

autotest: $(TEST_INPUTS)

$(TEST_INPUTS): test-%.txt: program
        $< $@ test-out.txt
        diff -q test-out.txt out-$*.txt

这不仅更像make,而且还有其他优点:例如,您可以运行make test-provided.txt并且它将只运行一个测试而不是所有测试。

您必须在此处使用静态模式规则而不是普通模式规则,因为.PHONY目标不能与模式规则一起使用。


推荐阅读