实验代码框架讲解
项目结构
.
├── exercises //所有习题都在此文件夹下
├── LICENSE
├── Makefile
├── README.en.md
├── README.md
└── test //所有测例都在此文件夹下
- exercises:这个文件夹包含了所有的习题代码。每个习题可以作为一个子文件夹,其中包含习题的源代码、数据文件和任何相关的资源。
- LICENSE:项目的许可证文件,定义了项目的使用、修改和分发的法律条款。
- Makefile:一个自动化构建脚本,用于编译、测试和清理项目。通过运行
make
命令,可以执行 Makefile 中定义的任务。 - test:这个文件夹包含了所有的测试用例。每个测试用例可以作为一个子文件夹或文件,用于验证习题代码的正确性。
Makefile 内容
实验框架的 Makefile:
# Makefile for C language exercise project
# Define the directory where the exercise files are stored
EXERCISE_DIR = ./exercises
# Define the test directory
TEST_DIR = ./test
# Define the build directory
BUILD_DIR = ./build
# Ensure the test and build directories exist
$(shell mkdir -p $(TEST_DIR) $(BUILD_DIR))
# Define the list of exercises
EXERCISES = $(wildcard $(EXERCISE_DIR)/*.c)
# Define the list of executables
EXECUTABLES = $(patsubst $(EXERCISE_DIR)/%.c, $(BUILD_DIR)/%, $(EXERCISES))
# Define compiler and linker flags
CC = gcc
CFLAGS = -Wall -Wextra -std=c99
LDFLAGS = -lm
# Default target: build all executables
all: $(EXECUTABLES) clean
# Build rule for each executable
$(BUILD_DIR)/%: $(EXERCISE_DIR)/%.c
$(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
# Clean rule to remove all executables and object files
clean:
rm -f $(EXECUTABLES) $(BUILD_DIR)/*.o
# Generate test cases rule
generate-test-cases: $(EXECUTABLES)
@for exe in $(EXECUTABLES); do \
./$$exe > $(TEST_DIR)/$$(basename $$exe).out; \
done
@$(MAKE) clean
# Test rule to compare output with expected results
test-output: $(EXECUTABLES)
@for exe in $(EXECUTABLES); do \
exercise_name=$$(basename $$exe); \
expected=$$(cat $(TEST_DIR)/$${exercise_name}.out); \
actual=$$($$exe); \
if [ "$$expected" = "$$actual" ]; then \
echo "Test for $${exercise_name} passed."; \
else \
echo "Test for $${exercise_name} failed."; \
echo "Expected:"; echo "$$expected"; \
echo "Actual:"; echo "$$actual"; \
fi; \
done
@$(MAKE) clean
# New target to save test results and count pass rate in JSON format
save-test-results: $(EXECUTABLES)
@total=0; \
passed=0; \
> $(BUILD_DIR)/test_results.json; \
for exe in $(EXECUTABLES); do \
exercise_name=$$(basename $$exe); \
expected=$$(cat $(TEST_DIR)/$${exercise_name}.out); \
actual=$$($$exe); \
total=$$((total+1)); \
if [ "$$expected" = "$$actual" ]; then \
passed=$$((passed+1)); \
fi; \
done; \
echo "{\"channel\": \"gitee\",\"courseId\": 1558,\"ext\": \"aaa\",\"name\": \"\",\"score\": $$passed,\"totalScore\": 5}" > $(BUILD_DIR)/test_results.json
@$(MAKE) clean
.PHONY: all clean generate-test-cases test-output save-test-results
- 目录定义:
EXERCISE_DIR
:存放练习文件的目录。TEST_DIR
:存放测试文件的目录。BUILD_DIR
:存放构建产物的目录。
- 文件和目录操作:
mkdir -p $(TEST_DIR) $(BUILD_DIR)
:确保测试和构建目录存在。
- 编译和链接:
CC = gcc
:定义编译器为gcc。CFLAGS = -Wall -Wextra -std=c99
:编译选项,包括警告和C99标准。LDFLAGS = -lm
:链接选项,链接数学库。
- 构建规则:
$(BUILD_DIR)/%: $(EXERCISE_DIR)/%.c
:为每个练习文件生成对应的执行文件。
- 清理规则:
clean
:删除所有执行文件和构建目录下的对象文件。
- 测试规则:
generate-test-cases
:生成测试用例。test-output
:运行测试并比较输出结果。save-test-results
:保存测试结果和通过率到JSON文件。
使用 makefile 进行实验
在实验过程中,Makefile提供了自动化构建和测试的便利。以下是如何使用这个Makefile进行实验的步骤:
-
编译所有练习:
make
这个命令会编译所有练习文件,并在
BUILD_DIR
目录下生成对应的执行文件。 -
生成测试用例:
make generate-test-cases
这个命令会运行所有执行文件,并将输出保存为测试用例。
-
运行测试:
make test-output
这个命令会比较每个执行文件的输出与预期结果,并显示测试结果。
-
保存测试结果:
make save-test-results
这个命令会计算测试的通过率,并将结果保存到
test_results.json
文件中。 -
清理:
make clean
这个命令会删除所有构建产物和对象文件,保持环境整洁。