Skip to content

Commit 08f6829

Browse files
committed
集成测试教程
1 parent ed02e82 commit 08f6829

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

docs/tutorials/10-appendix-2-develop.md

+58-2
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,68 @@ TEST_CASE("testing lexer") {
112112
113113
当然,如果每次测试都需要手动进行编译,那就太不方便了。合理的做法是为集成测试编写自动化脚本。接下来我们介绍一下 tolangc 中的集成测试脚本。
114114
115-
### (1)测试样例规定
115+
### (1)测试样例与测试程序
116116
117+
我们规定一个测试样例由源文件、输入文件和输出文件三部分组成。源文件使用 `.tol` 后缀,输入文件使用 `.input` 后缀,输出文件使用 `.output` 后缀。三个文件需要位于同一目录中。输出文件中包含程序对给定的输入应当返回的输出。由于 llvm、mips 或 pcode 对浮点数的显示有所不同,所以在评测正确性时我们统一将结果转换为浮点数再进行比较。
117118
119+
我们用 python 编写评测脚本 `./script/test.py`。该脚本有如下参数:
118120
119-
### (2)
121+
1. 测试阶段:选择对 llvm、mips 或 pcode 的输出结果进行测试
122+
2. 样例文件:选择指定的样例文件进行测试,需要给出 `*.tol` 源文件的路径
123+
3. 样例目录:选择指定目录中的样例文件进行测试,需要给出测试样例所在的目录
120124
125+
```console
126+
$ python ./scripts/test.py -h
127+
usage: test.py [-h] -s {llvm,mips,pcode} [-d DIR] [-f FILE]
121128
129+
Integration test script for tolangc
130+
131+
options:
132+
-h, --help show this help message and exit
133+
-s {llvm,mips,pcode}, --stage {llvm,mips,pcode}
134+
stage to test
135+
-d DIR, --dir DIR directory of test cases
136+
-f FILE, --file FILE test case to run
137+
```
138+
139+
### (2)集成测试过程
140+
141+
集成测试的主体逻辑由 python 写成。首先,我们根据命令行参数获取进行测试的阶段和测试样例。之后对于每一个评测阶段,我们进行如下操作:
142+
143+
1. 按照测试阶段编译 tolangc
144+
2. 使用各测试样例对编译得到的 tolangc 进行测试
145+
146+
而对于第二步,我们遵循了和单元测试一致的结构,即**构造****操作****检验**。我们可以查看脚本中的 `general_test` 函数。该函数传入的 `preprocess_fn``run_fn``compare_fn` 分别代表了这三个阶段。
147+
148+
```py
149+
def general_test(test_files: list[pathlib.Path], preprocess_fn, run_fn, compare_fn):
150+
for test_file in test_files:
151+
# ...
152+
153+
preprocess_result = preprocess_fn(test_file)
154+
run_result = run_fn(
155+
preprocess_result, input_file if input_file.exists() else None
156+
)
157+
is_success = compare_fn(run_result, output_file)
158+
159+
# ...
160+
```
161+
162+
对于编译操作和运行操作,由于需要进行大量的命令行操作,所以我们选择使用 shell 脚本编写,并通过 python 的 `subprocess.run` 方法进行调用。
163+
164+
```py
165+
def build(backend: Literal["llvm", "pcode"]):
166+
# ...
167+
subprocess.run(
168+
["bash", "./scripts/build.sh", backend],
169+
stdout=subprocess.DEVNULL,
170+
check=True,
171+
env=dict(os.environ) | {"BUILD_DIR": TEST_CACHE_DIR / "build" / backend},
172+
)
173+
# ...
174+
```
175+
176+
最后,我们将评测的结果存储在 `TestStat` 中,并在测试结束后输出。
122177

123178
## 三、流水线
179+

0 commit comments

Comments
 (0)