大家好!最近在研究实时系统的建模与测试工具 Uppaal,刚好以经典的 “onoff 模型”(可以理解为模拟灯的开关控制)为例,完整走了一遍测试用例生成的流程。从模型配置到用例验证,每一步都踩得很实,今天就把这个过程整理出来,分享给刚接触 Uppaal 的小伙伴们~
1. 第一步:打开 onoff 模型,认识核心模板
首先要做的就是在 Uppaal 中加载目标模型文件 —— 找到 “onoff/onoff.xml” 并打开,此时会看到模型包含两个核心模板:System(被测系统) 和 User(用户交互)。
- System 模板:代表我们要测试的设备(比如灯),只有两个状态 ——On(开启)和 Off(关闭),通过 “on?” 和 “off?” 两个通道实现状态切换;
- User 模板:模拟用户的操作,会随机触发 “开启” 或 “关闭” 指令,与 System 交互
-


2. 第二步:配置测试基础 —— 变量声明与代码框架
要让 Uppaal 能生成符合需求的测试用例,需要先做两项关键配置:声明控制变量、定义代码前后缀。
2.1 声明测试控制变量
在模型中添加两个 int 类型变量,作用很明确:
int _reach_=0;:告诉工具 “测试需要覆盖哪些范围”,用于控制覆盖目标;int _single_=0;:告诉工具 “测试用例要怎么分步执行”,对应单步测试逻辑。
-
2.2 定义测试代码的 “前后缀框架”
Uppaal 生成测试用例时,会把 “核心测试步骤”(比如触发开关的指令)嵌入到预先写好的前缀代码(TEST_PREFIX) 和后缀代码(TEST_POSTFIX) 中,最终形成完整可运行的文件。如下图就是UPPAL自动生成的前缀和后缀代码。
-

3. 第三步:绑定测试逻辑 —— 为 “边” 和 “位置” 设测试代码
模型的 “边”(状态切换路径)和 “位置”(状态节点)是测试逻辑的核心载体,需要给它们绑定具体的测试代码,让测试用例知道 “走这条边要做什么”“到这个状态要检查什么”。
3.1 为 “边” 设置触发代码
- 双击 System 模板中标记 “on?” 的边(Off→On 的切换路径),在 Test Code 中输入
set_on();—— 意味着只要测试用例走这条边,就会调用应用程序的set_on()方法(开启设备);
- 同理,双击标记 “off?” 的边(On→Off 的切换路径),输入
set_off();—— 对应调用set_off()方法(关闭设备)。3.2 为 “位置” 设置检查代码
“位置” 的测试代码分两种场景:进入位置(On enter) 和离开位置(On exit),我主要用了 “进入检查”:
- 选中 System 模板的 “On” 位置,打开 Edit Location,在 On enter 中输入
expect_on();—— 当测试轨迹到达 “On” 状态时,会执行expect_on()方法,验证设备是否真的开启; - 初始状态 “Off” 同理(后续代码中会看到
expect_off()的检查逻辑)。
4. 第四步:生成测试用例 —— 选模式、看覆盖度
配置完所有逻辑,就到了最关键的 “生成测试用例” 环节,步骤很清晰:
- 启用 Test Cases 选项卡:在 Uppaal 顶部菜单栏找到 “Test Cases”,进入测试用例生成界面;

- 选择搜索模式与参数:我选的是 “自动深度搜索(depth-first reachability)”—— 这种模式会优先把一条路径走透,避免遗漏;同时设置 “Depth=20”(最大步骤数为 20);

- 点击 Add 生成:生成后能看到 “Trace coverage: 4/4”—— 这表示 4 条边(Off→On、On→Off、User 的两个交互边)都被覆盖了,还有 “Locations: 3/3=100%”(所有状态都覆盖);
- 查看轨迹细节:切换到 “Symbolic Simulator”,能看到测试轨迹其实是 “循环交替执行开 / 关操作”(符合 User 随机触发的逻辑),右下角监控区会实时显示操作流程。

-
第五步:保存测试用例文件
生成满意的测试用例后,记得保存到指定文件夹:
- 在 “Save Test Cases” 弹窗中,选择路径为 “uppaal64-4.1.26-2\demo\testcases\onoff”(可以自定义);
- 保存后会自动生成一个名为
testcase0.code的文件,这就是我们需要的测试用例代码文件。
6. 第六步:运行测试 —— 验证用例有效性
最后一步就是运行测试,验证用例是否能正常工作,以及是否能发现错误。
6.1 先看测试用例代码结构
打开
testcase0.code,能看到清晰的三段式结构:- 第 1-6 行:前缀代码(对应之前写的 TEST_PREFIX);
- 第 8 行开始:核心测试步骤,比如第一步是
expect_off();(因为初始状态是 Off,先验证初始状态),接着是set_on();(开启)、expect_on();(验证开启)、set_off();(关闭)等; - 最后几行:后缀代码(对应 TEST_POSTFIX)。

-
6.2 运行 bat 文件测试
我准备了两个批处理文件:
test.bat(正常配置)和testMutant.bat(故意设置错误的配置): - 运行
test.bat:cmd 中显示 “已复制 1 个文件”,无任何错误输出 —— 说明测试用例正常执行,设备交互符合预期;
- 运行
testMutant.bat:直接报错 “Exception in thread "main" java.lang.AssertionError”,错误定位在app.App.expect_on(App.java:17)—— 这证明测试用例能成功发现配置错误,功能有效!总结
这次用 Uppaal 做 onoff 模型的测试用例,从模型理解到最终验证,整个流程其实很顺畅。核心是抓住 “模板 - 变量 - 代码绑定 - 生成 - 验证” 这几个环节,尤其是 “覆盖度” 和 “错误检测” 的验证,能直观看到测试用例的有效性。
如果是刚接触 Uppaal 的同学,建议从这种简单的两模板模型入手,熟悉每个配置项的作用后,再去挑战复杂系统~ 有疑问的话欢迎在评论区交流呀!

被折叠的 条评论
为什么被折叠?



