一个用于测试 SysY 编译器的自动化测试框架,支持多线程并行测试、GUI 界面、多语言编译器(Java/C/C++)。
- Python 3.8+
- JDK 8+(用于运行 Mars 模拟器)
- g++(用于生成期望输出)
- (GUI)Tkinter(多数 Python 发行版自带;若无 GUI/无 Tk 可使用命令行模式)
python3 -m pip install pyyaml httpxYourCodesFolder/
└── SysYTest/ # 本测试框架
├── zips/ # 你的编译器源码 zip(可多个)
│ ├── A.zip
│ └── B.zip
├── config.yaml
├── main.py
├── src/ # 框架代码(CLI/GUI/Runner/Discovery)
└── testcases/ # 测试用例库(可多层嵌套;叶子目录为一个用例目录)
不带参数默认启动 GUI:
python3 main.py指定 --project 参数可以在命令行环境下直接编译+测试,适合 CI/CD 或无 GUI 环境:
python3 main.py --project zips/如需只测试部分 zip,可多次指定 --compiler(zip 文件名去扩展名,或完整 zip 文件名):
python3 main.py --project zips/ --compiler A --compiler B.zip运行时会实时打印 PASS/FAIL 结果和进度,失败时显示实际/期望输出对比。
常用参数:
--match <子串>- 只运行用例名包含该子串的用例(可多次指定)--show-cycle- 显示运行周期数(需 Mars 支持)--show-time- 显示编译耗时
运行 python3 main.py --help 查看完整参数列表。
git pull origin main# 首次:添加上游仓库
git remote add upstream https://github.com/原仓库/SysYTest.git
# 获取上游更新
git fetch upstream
# 合并到你的本地分支
git checkout main
git merge upstream/main
# 推送到你的 Fork
git push origin main欢迎提交你的测试用例!
-
Fork 本仓库
点击 GitHub 页面右上角的 Fork 按钮
-
克隆你的 Fork
git clone https://github.com/你的用户名/SysYTest.git cd SysYTest -
创建新分支
git checkout -b add-testcases-你的昵称
-
添加测试用例
在
testcases/下创建你的测试库文件夹,添加用例目录(支持任意深度嵌套;叶子目录直接包含testfile.txt即会被识别为一个用例):testcases/你的测试库名/ └── testcase1/ ├── testfile.txt # 源代码 ├── in.txt # 输入(可选) └── ans.txt # 期望输出(可选) -
提交更改
git add testcases/你的测试库名/ git commit -m "添加测试用例:你的测试库名" git push origin add-testcases-你的昵称 -
创建 Pull Request
- 打开你的 Fork 仓库页面
- 点击 "Compare & pull request"
- 填写 PR 描述,说明你的测试用例覆盖了哪些场景
- 点击 "Create pull request"
将你的测试用例文件夹打包发送到:YumoJiang@buaa.edu.cn
编辑 config.yaml 配置测试框架:
# zip_dir:编译器源码压缩包目录(相对于本框架目录)
compiler_project_dir: "zips/"
# 工具路径(留空使用环境变量)
tools:
jdk_home: "" # JDK安装目录,如 "C:/Program Files/Java/jdk-17"
gcc_path: "" # g++路径
cmake_path: "" # cmake 路径(C/C++ 项目可选)
# 并行测试
parallel:
max_workers: 8 # 并行线程数在你的 zip 包顶层放置 config.json:
{
"programming language": "java",
"object code": "mips"
}支持的语言:java、c、cpp
- zip 包顶层必须包含
config.json java:入口为Compiler.java的main方法;提交时请将Compiler.java放在 zip 顶层(不要再嵌套一层src/目录)cpp:若使用 CMake,zip 顶层包含CMakeLists.txt,且需project(Compiler)以确保输出可执行文件名为Compiler;不要提交构建产物/临时文件c/cpp:若不使用 CMake,默认按 C++17 用g++编译 zip 中的.c/.cpp/.h- macOS 压缩可能带
__MACOSX/、.DS_Store等额外文件,请删除后再提交
- 启动程序后,在「测试运行」标签页选择
zip_dir(如zips/) - 在「编译器实例(zip)」列表中多选需要测试的编译器(不选则默认全部)
- 点击「编译选中」编译所选编译器实例
- 在左侧选择测试库,右侧会显示该库的测试用例
- 点击「运行全部」运行所有测试,或选择特定用例运行
当测试失败时,输出日志会显示:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✗ 测试库名/某个用例
状态: FAILED
原因: 输出不匹配
行数: 实际 5 | 期望 5
差异: 1 处
┌ 第 3 行
│ 实际: 42
└ 期望: 24
找到对应的测试文件进行调试:
-
根据日志中的路径
测试库名/某个用例,找到文件:testcases/测试库名/某个用例目录/ # 用例目录(例如 testcase3/ 或 A/) ├── testfile.txt # 源代码 └── in.txt # 输入(可选) -
将该用例目录下的
testfile.txt内容复制到你编译器项目的testfile.txt -
将
in.txt的内容作为 Mars 模拟器的输入(若存在) -
运行你的编译器和 Mars 进行调试
- 切换到「用例编写」标签页
- 选择或新建一个测试库
- 在左侧编写 SysY 源代码
- 在右侧编写输入数据(每行一个整数)
- 点击「保存」或「保存并继续」
本框架支持使用 AI 自动生成符合 SysY 文法的测试用例。
配置步骤:
- 切换到「AI 生成」标签页
- 配置 API:
- Base URL:API 地址(默认
https://api.anthropic.com,支持兼容 API) - Model:模型名称(如
claude-sonnet-4-20250514) - API Key:你的 API 密钥
- Base URL:API 地址(默认
- 点击「保存配置」
使用方法:
- 先在「测试运行」标签页编译你的编译器
- 在输入框描述你想要的测试用例,例如:
- "生成一个测试递归函数的用例"
- "生成一个测试数组边界的用例"
- "生成一个包含复杂 for 循环嵌套的用例"
- AI 会自动:
- 生成 SysY 源代码
- 调用你的编译器检查语法错误
- 如果有错误,自动修改代码
- 编译通过后询问是否保存
安装额外依赖:
python3 -m pip install httpx测试用例从 testcases/ 下发现:任意深度嵌套目录中,直接包含 testfile.txt 的叶子目录会被识别为一个用例目录(case directory)。
testcases/
└── 01_language_basics/
├── testcase1/
│ ├── testfile.txt
│ ├── in.txt
│ └── ans.txt
└── getint_for_matrix/
└── testcase1/
├── testfile.txt
├── in.txt
└── ans.txt
单个用例目录常见文件:
testfile.txt: SysY 源码(必需)in.txt: 输入(可选;按行提供整数)ans.txt: 期望输出(可选)compile_only/compile_only.txt/.compile_only: 仅编译检查(可选)
- 编译:将你的编译器编译为可执行文件(JAR/EXE)
- 运行编译器:用你的编译器将 SysY 源码编译为 MIPS 汇编
- 运行 Mars:用 Mars 模拟器执行 MIPS 代码,获取实际输出
- 获取期望输出:优先使用用例目录内的
ans.txt(若提供);否则可用 g++ 编译运行同一份源码生成参考输出 - 对比:比较实际输出和期望输出
确保已安装 JDK 并添加到 PATH,或在 config.yaml 中配置 jdk_home。
确保已安装 MinGW 或其他 GCC 工具链并添加到 PATH,或在 config.yaml 中配置 gcc_path(如果配置到 config.yaml 后仍然报错,请考虑将其 bin 目录添加到环境变量,例如 "C:\Program Files\mingw64\bin\")。
调整 config.yaml 中的 parallel.max_workers 增加并行线程数(注意不要超过 CPU 核心数太多)。
在 GUI 中选择测试库后,在右侧用例列表中按住 Ctrl 多选,然后点击「运行选中」。
在命令行中可使用 --match 过滤(可多次指定):
python3 main.py --project zips/ --match loop --match recursion如需只测试部分编译器 zip,可多次指定 --compiler:
python3 main.py --project zips/ --compiler A --compiler B.zip可能是死循环,也可能是优化不够导致的 TLE,后者可以在 config.yaml 中增加 Mars 执行超时时间。
这是 Windows Defender(或火绒等杀毒软件)在扫描新生成的 exe 文件。解决方法:
-
推荐:将
.tmp目录添加到杀毒软件的排除列表 -
临时方案:测试期间暂时关闭实时防护