如何在MiniZinc中编写多案例单元测试(无需Python调用)
MiniZinc 多案例单元测试实现方案
你原来的测试代码存在几个关键问题:
- 用反引号包裹测试代码不符合MiniZinc语法规范
- 直接给全局数据变量
total_multip赋值违背了MiniZinc的约束逻辑 - 求解语句中的
objective未定义,原模型的目标是minimize result
下面是无需Python调用、支持多测试案例的纯MiniZinc实现方案:
1. 重构原模型(可选但推荐)
为了方便测试复用,把原模型的核心逻辑封装成谓词。修改unit_tests_program.mzn如下:
% 数据参数 int: total_multip; % 决策变量 var 1..100: a; var 1..100: b; var int: result; % 约束 constraint a * b = total_multip; constraint result = max(a, b); % 封装求解与验证逻辑为谓词,供测试调用 predicate run_test(int input_multip, int expected, out bool passed) = let { int: local_multip = input_multip; var 1..100: x; var 1..100: y; var int: res; } in ( x * y = local_multip /\ res = max(x, y) /\ solve minimize res /\ passed = (res == expected) ); % 保留原模型的求解与输出功能 solve minimize result; output ["result = \(result)"];
2. 编写测试文件
创建test_cases.mzn,包含原模型并定义多个测试案例:
include "unit_tests_program.mzn"; % 测试案例1:输入10,预期结果5 bool test1_passed; run_test(10, 5, test1_passed); output ["Test Case 1: ", if test1_passed then "PASSED" else "FAILED (Expected 5, got " ++ show(result) ++ ")" endif, "\n"]; % 测试案例2:输入16,预期结果4 bool test2_passed; run_test(16, 4, test2_passed); output ["Test Case 2: ", if test2_passed then "PASSED" else "FAILED (Expected 4, got " ++ show(result) ++ ")" endif, "\n"]; % 测试案例3:输入21,预期结果7 bool test3_passed; run_test(21, 7, test3_passed); output ["Test Case 3: ", if test3_passed then "PASSED" else "FAILED (Expected 7, got " ++ show(result) ++ ")" endif, "\n"];
3. 运行测试
直接用MiniZinc解释器运行test_cases.mzn,输出会清晰显示每个测试案例的状态:
Test Case 1: PASSED Test Case 2: PASSED Test Case 3: PASSED
如果某个测试案例不符合预期(比如把案例3的预期值改成8),会输出失败提示:
Test Case 3: FAILED (Expected 8, got 7)
核心逻辑说明
- 用谓词封装求解和验证逻辑,确保每个测试案例独立运行、互不干扰
- 每个测试案例通过调用谓词获取布尔型的测试结果,再输出对应的状态信息
- 全程无需外部脚本,纯MiniZinc代码即可完成多案例批量测试
内容的提问来源于stack exchange,提问作者GabyLP
相关产品推荐
相关产品推荐

