CAPL 测试模块:有界等待与超时检查
只验证一个明确的承诺
本例的承诺是:开始等待后 500 ms 内,观察到 CAN1 上 ID 0x200 的接收数据帧,至少两个字节,首字节为 0xAA。它验证的是周期心跳的可用性和最小载荷约定,不验证门锁动作、请求响应因果关系或每次发送间隔。
发送端可使用周期定时器教程。建立支持 Test Feature Set 的 CAPL 测试模块,并限制为单 CAN 通道配置,避免其他通道同 ID 的事件提前解除等待。下面代码包含一个 testcase 和入口 MainTest;不要放入普通仿真节点当作定时器程序。请先核实许可、模块类型、通道上下文和已安装版本 API。
有界等待必须检查返回值
| TestWaitForMessage 返回值 | 含义 | 本例处理 |
|---|---|---|
| 1 | 匹配消息事件发生 | 读取触发本次等待的帧,再检查内容 |
| 0 | 超时 | 记录未在期限内观察到事件 |
| -2 | 约束违规导致恢复执行 | 单独记录中断原因,不归为普通超时 |
| -1 或其他异常值 | 错误或功能不可用等 | 记录返回码,不继续读取旧数据 |
等待参数是毫秒。参考资料说明,传入 0 表示不进行超时控制;这里必须使用有界的 500。收到消息后,用 TestGetWaitEventMsgData 获取刚刚解除等待的消息。该函数返回 0 才表示读取成功;不要把这两个 API 的成功返回值混用。
示例测试模块
源代码已对照可用参考资料,尚未在 CANoe 中编译或执行。本例的通过步骤只代表被观察帧满足这里列出的条件。
testcase TC_HeartbeatAvailability()
{
long waitResult;
long dataResult;
message CAN1.0x200 observed;
TestCaseTitle("HB-01", "Observe a valid heartbeat within 500 ms");
TestStep("1", "Wait for ID 0x200 in the single-channel test setup");
waitResult = TestWaitForMessage(0x200, 500);
if (waitResult == 0)
{
TestStepFail("2", "Timeout: no matching message observed within 500 ms");
return;
}
if (waitResult == -2)
{
TestStepFail("2", "Wait interrupted by a constraint violation");
return;
}
if (waitResult != 1)
{
TestStepFail("2", "Wait failed or is unavailable: result=%d", waitResult);
return;
}
dataResult = TestGetWaitEventMsgData(observed);
if (dataResult != 0)
{
TestStepFail("3", "Could not retrieve the triggering frame: result=%d", dataResult);
return;
}
if (observed.CAN != 1 || observed.DIR != Rx || observed.RTR != 0)
{
TestStepFail("3", "Unexpected channel, direction or frame type");
return;
}
if (observed.DLC < 2)
{
TestStepFail("3", "Heartbeat payload is shorter than two bytes");
return;
}
if (observed.byte(0) != 0xAA)
{
TestStepFail("4", "Wrong marker: expected 0xAA, got 0x%02X", observed.byte(0));
return;
}
TestStepPass("4", "Observed a two-byte heartbeat with marker 0xAA");
}
void MainTest()
{
TC_HeartbeatAvailability();
}
先检查数据获取结果、通道、方向、帧类型和 DLC,再读载荷,可以避免把缓存旧值或长度不足的帧当成正确响应。这里没有使用另一个 on message 处理函数中的全局 doorStatus,因此不依赖两个处理路径之间的数据更新时间。
同时验证失败路径
下面是一份待执行矩阵,不是通过报告。每次运行前只保留本场景的受控发送源,并重置测试环境。
| 场景 | 操作 | 应检查的结果 |
|---|---|---|
| 正常心跳 | 运行两字节 AA 心跳发送节点 | 最终内容检查步骤通过 |
| 无心跳 | 发送节点按 x 停止,等已提交流量结束,再启动用例 | 500 ms 后走超时分支 |
| 长度不足 | 独立发送源用相同 ID 发送 DLC 1 | 长度检查失败,不能读第二字节 |
| 标记错误 | DLC 2,首字节改为 AB | 内容检查失败,报文到达本身不能让测试通过 |
| 配置错误 | 核实模块支持或约束触发情况 | 按实际返回码记录,不能伪造为超时 |
如果错误帧先到、正确帧稍后到,本例会在第一帧处失败。若需求允许重试,应另外定义一个总截止时间;不要每次循环都重新等待完整的 500 ms,否则总等待时间会超过承诺。
接收可用性不等于功能正确
一条心跳可能与刚发送的命令无关。真正的请求响应测试需要明确的关联字段、状态转换或请求序号,还要处理旧响应和无关周期消息。不要在 output 调用后直接写“发送成功”,也不要仅因 TestWaitForMessage 返回 1 就判定门锁已经锁上。
周期稳定性请用时间戳教程和间隔工具检查。单次 500 ms 等待不能替代多帧周期统计。
记录执行版本、测试台架、源文件、配置、期望值与完整测试报告,再谈实测结果。API 依据为获授权参考资料中的 TestWaitForMessage、TestGetWaitEventMsgData 和 TestStep;可对照 Vector Test Feature Set 教程,该链接可能需要登录。本站未以官方示例的运行结果替代本例验证。