如何用Rust原生机制测试get_bit函数的全范围panic场景?
Rust 全范围测试会panic的函数(不依赖第三方 crate)
针对你的问题,Rust 原生提供了两种可行的方案来完成 8 到 255 的全范围测试,无需依赖 rstest 这类第三方库:
方案一:用 std::panic::catch_unwind 捕获 panic
利用标准库的 catch_unwind 函数,可以在循环中逐个测试每个输入,即使某个输入触发 panic,也不会终止整个测试函数,而是捕获 panic 并继续执行后续用例。
示例代码:
fn get_bit(byte: u8, n: u8) -> bool { if n > 7 { panic!("n must be between 0 and 7"); } (byte >> n) & 1 == 1 } #[test] fn test_get_bit_panics_for_all_invalid_indices() { // 遍历 8 到 255 的所有 u8 值 for n in 8..=255 { // 捕获调用 get_bit 时的 panic let panic_result = std::panic::catch_unwind(|| get_bit(0, n)); // 断言该输入确实触发了 panic assert!(panic_result.is_err(), "输入 n={} 未触发预期的 panic", n); } }
原理说明
catch_unwind 会将可能触发 panic 的代码包裹在闭包中执行,返回一个 Result:
- 如果闭包正常执行,返回
Ok(返回值) - 如果闭包触发 panic,返回
Err(捕获的 panic 信息)
通过在循环中对每个输入调用 catch_unwind 并断言结果为 Err,就能确保所有无效输入都触发了 panic,且测试会完整遍历所有用例。
方案二:用宏生成独立测试用例
如果你希望每个无效输入都作为单独的测试项(方便在测试报告中看到具体哪个输入出问题),可以用 Rust 宏批量生成带有 #[should_panic] 属性的测试函数。
示例代码:
fn get_bit(byte: u8, n: u8) -> bool { if n > 7 { panic!("n must be between 0 and 7"); } (byte >> n) & 1 == 1 } // 定义生成测试的宏 macro_rules! generate_panic_tests { ($($n:expr),*) => { $( #[test] #[should_panic(expected = "n must be between 0 and 7")] fn test_get_bit_panics_at_n_$n() { get_bit(0, $n); } )* }; } // 生成 8 到 255 的测试用例 generate_panic_tests!( 8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55, 56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103, 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123, 124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163, 164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203, 204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243, 244,245,246,247,248,249,250,251,252,253,254,255 );
原理说明
宏 generate_panic_tests 会将传入的每个数值展开为一个独立的测试函数,每个函数都带有 #[should_panic] 属性,确保对应的输入触发 panic。数值列表可以借助编辑器批量生成,无需手动逐个输入。
方案对比
- 方案一:代码简洁,测试执行效率更高,适合只需要验证所有输入都触发 panic 的场景。
- 方案二:每个输入对应独立测试项,测试失败时能直接定位到具体的输入值,适合需要精准排查问题的场景。
内容的提问来源于stack exchange,提问作者チーズパン
相关产品推荐
相关产品推荐

