测试时遇到的两个问题:冗余case和无效case

本文讨论了软件测试过程中遇到的问题,包括测试集冗余和无效测试案例。作者分享了在测试JDBC接口时的经验,强调了高质量测试用例的重要性,而非仅仅追求测试集的数量。
最近测试的时候遇到了两个问题
1.测试集冗余
我在测试JDBC接口的时候,有几个case是测试PreparedStatement在不绑参数的情况下调用execute方法会不会报错,结果肯定是报错了我也能捕捉到,但是这样的测试用例跟我修改代码没关系。
2.无效测试
我之所以写那么多case,真正目的是为了目标测试,验证Bug真的被消除了,而事实上,测试集写好后,一直都是在测修正后的版本,通过了空欢喜,因为无意中测了一次修正前的版本,也是能全部通过,汗!
虽然测试用例越多显得测试越严格,事实上,测试集数量不代表测试集的质量,一些无效的测试用例,没必要拿来混人耳目。
/** * @brief 验证MQTT报文固定报头的合法性 * @param packet_header 固定报头的第一个字节(包含报文类型标志位) * @return 1(合法)或 0(非法) */ int validate_packet_header(uint8_t packet_header) { // 主switch:处理所有明确已知的合法报文头 switch (packet_header) { case 0x10: // CONNECT - 无标志位要求 case 0x20: // CONNACK - 无标志位要求 case 0x30: // PUBLISH - 基础合法形式(QoS=0, DUP=0, RETAIN=0) case 0x40: // PUBACK - 无标志位要求 case 0x50: // PUBREC - 无标志位要求 case 0x62: // PUBREL - 标志位必须为0x02(MQTT v3.1.1要求) case 0x70: // PUBCOMP - 无标志位要求 case 0x82: // SUBSCRIBE - 标志位必须为0x02 case 0x90: // SUBACK - 无标志位要求 case 0xA2: // UNSUBSCRIBE - 标志位必须为0x02 case 0xB0: // UNSUBACK - 无标志位要求 case 0xC0: // PINGREQ - 无标志位要求 case 0xD0: // PINGRESP - 无标志位要求 case 0xE0: // DISCONNECT - 无标志位要求 // case 0xF0: // AUTH(MQTT v5.0) - 当前被注释掉 // 调试信息:明确记录通过主switch验证的报文 printf("[MQTT解析器] 调试:报文头0x%02X通过主switch验证\n", packet_header); return 1; default: // 处理PUBLISH报文的所有变体(类型3) if((packet_header >> 4) == 0x03) { // 调试信息:进入PUBLISH变体处理 printf("[MQTT解析器] 调试:检测到PUBLISH变体报文头0x%02X\n", packet_header); switch (packet_header) { case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F: return 1; default: // 理论上不会执行到这里,因为外层if已经确认是PUBLISH类型 printf("[MQTT解析器] 错误:不可能到达的PUBLISH变体错误 (0x%02X)\n", packet_header); return 0; } } // 处理其他所有非法报文 printf("[MQTT解析器] 错误:无效的报文头:0x%02X (不属于任何已知合法模式)\n", packet_header); return 0; } } 解释这段代码
07-10
<think> 我们正在讨论编程中的分支结构,特别是`case`语句。用户询问关于`case 0``case 1`的含义用法。 根据之前的对话,我们已经知道在`switch`语句中,`case`后面必须跟常量表达式,不能有变量或逻辑运算。 现在用户想理解代码中`case 0``case 1`的含义,我们可以从以下几个方面解释: 1. 在`switch`语句中,`case 0``case 1`通常是两个分支标签,用于匹配`switch`表达式的值。 2. 当`switch`表达式的值等于0,执行`case 0`后面的代码块;等于1,执行`case 1`后面的代码块。 3. 每个`case`分支通常以`break`结束,以避免穿透到下一个分支(除非有意为之)。 我们将给出一些示例代码(如C语言、Java等)来说明用法。 同,我们注意到引用中提到了不同语言中的类似结构(如Shell的case、MySQL的CASE WHEN等),但用户的问题更可能是关于C-like语言中的switch-case。 另外,根据用户提供的引用: 引用[1]提到了VB中的Select Case结构,引用[2]展示了Shell脚本的case,引用[3]提到Java中的switch-case,引用[4]提到MySQL的CASE WHEN。 我们可以适当引用这些内容来说明不同语言中的分支结构。 但是,用户明确要求理解`case 0``case 1`,所以我们重点放在常见的编程语言(如C、C++、Java)上。 回答结构: 1. 解释`case 0``case 1`在switch语句中的基本作用。 2. 给出具体代码示例(C语言或Java)。 3. 说明注意事项(如break的重要性,case穿透等)。 4. 扩展到其他语言(如Shell脚本、SQL)中的类似结构(简要提及)。 5. 生成相关问题。 注意:用户要求使用中文,并且数学表达式用$...$,独立公式用$$...$$。但本问题不涉及数学公式,所以主要使用代码示例。 </think> ### `case 0` `case 1` 分支结构的含义、用法及示例 在多分支选择结构中,`case 0` `case 1` 是常见的分支标签,用于匹配特定值并执行对应代码块。核心原理是:当控制表达式的值等于某个 `case` 标签的值,执行该标签下的语句[^1]。 #### 一、基本语法规则 1. **常量匹配** `case` 后必须是编译常量(整型/字符/枚举),如: ```c switch (value) { case 0: // 匹配 value=0 // 执行代码 break; case 1: // 匹配 value=1 // 执行代码 break; } ``` > 数学表达:若控制变量 $v$ 满足 $v = k$($k$ 为常量),则触发对应分支 2. **穿透机制** 省略 `break` 会继续执行后续分支: ```c switch (value) { case 0: // value=0 执行此处... case 1: // ...并继续执行此处 printf("值小于2"); break; } ``` 3. **默认分支** `default` 处理未匹配的情况: ```java switch (day) { case 0: System.out.println("周日"); break; case 1: System.out.println("周一"); break; default: System.out.println("其他日期"); // 非0/1执行 } ``` #### 二、跨语言示例 1. **C语言**(硬件状态检测) ```c void check_sensor(int status) { switch(status) { case 0: // 正常状态 led_green_on(); break; case 1: // 警告状态 led_yellow_blink(); break; default: // 故障状态 alarm_trigger(); } } ``` 2. **Java**(用户权限控制) ```java String getAccessLevel(int roleCode) { switch(roleCode) { case 0: // 管理员 return "ALL_PERMISSIONS"; case 1: // 普通用户 return "BASIC_PERMISSIONS"; default: // 访客 return "READ_ONLY"; } } ``` 3. **Shell脚本**(命令解析) ```bash read -p "输入操作码: " cmd case $cmd in 0) # 关机 sudo poweroff ;; 1) # 重启 sudo reboot ;; *) # 无效命令 echo "错误代码" ;; esac ``` 4. **SQL**(数据分类) ```sql SELECT product_id, CASE status WHEN 0 THEN '下架' WHEN 1 THEN '在售' ELSE '未知' END AS status_desc FROM products; ``` #### 三、关键设计原则 1. **完整性** 需覆盖所有预期值,使用 `default` 处理边界 2. **可维护性** 避免穿透逻辑(除非刻意设计),如状态机中的连续状态转移 3. **性能优化** 编译器通常将 `switch` 转为跳转表,间复杂度 $O(1)$ 优于 `if-else` 的 $O(n)$[^3] --- ### 相关问题 1. `case` 穿透机制在实际开发中有哪些典型应用场景? 2. 如何避免 `switch-case` 结构中的冗余代码? 3. 在函数式编程中如何替代 `switch-case` 结构? 4. `switch` 语句对浮点数支持的限制是什么?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值