hibase32-cj单元测试实战:仓颉@Test、@Expect与@AssertThrows测试宏完整教程
【免费下载链接】hibase32-cjBase32(RFC 4648)编码/解码库项目地址: https://gitcode.com/Cangjie-TPC/hibase32-cj
hibase32-cj 是一个用仓颉(Cangjie)语言实现的 Base32(RFC 4648)编码/解码库,支持 UTF-8 中文等多字节字符。本文以该项目自带的测试文件为样本,带你一次学会仓颉单元测试的三大核心测试宏:@Test、@Expect 与 @AssertThrows,并掌握批量断言与异常断言的完整写法。🧪
一、项目结构速览与测试运行方法
hibase32-cj 的项目结构非常简洁,与单元测试相关的文件只有 3 个:
| 文件 | 说明 |
|---|---|
| src/base32.cj | 核心代码:encode、decodeAsString、decodeAsBytes 等 Base32 编解码函数 |
| src/test/base32_test.cj | 单元测试文件,本文全部示例都来自这里 |
| cjpm.toml | 仓颉包管理器(cjpm)的工程配置 |
拿到代码后,一条命令即可运行全部测试:
git clone https://gitcode.com/Cangjie-TPC/hibase32-cj cd hibase32-cj cjpm testcjpm test会自动扫描src/test/目录下所有带@Test标注的函数并逐个执行,全部通过即说明库的功能符合预期。✅
二、仓颉单元测试三大测试宏速览
三个宏都来自标准库std.unittest.testmacro.*,对应 base32_test.cj 开头的导入:
| 测试宏 | 用途 | 最小示例 |
|---|---|---|
@Test | 把一个函数标记为测试用例 | @Test func testAscii() { ... } |
@Expect | 断言「实际值 == 期望值」 | @Expect(encode("Hello"), "JBSWY3DP") |
@AssertThrows | 断言某表达式抛出指定类型异常 | @AssertThrowsException) |
一句话记忆:@Test 负责「跑」,@Expect 负责「对答案」,@AssertThrows 负责「验错」。
三、@Test + @Expect:第一个完整的仓颉测试用例
看 testAscii 的实现:
@Test func testAscii() { for (i in 0..strs.size) { @Expect(encode(strs[i]), base32Strs[i]) } }两个要点:
- 参数顺序:
@Expect(实际值, 期望值),顺序反了虽然也能编译,但失败时会很难读; - 批量断言技巧:待测数据预先放进
strs和base32Strs两个数组(测试数据定义),覆盖空串、单字符、长文本等 8 组场景,循环里逐组断言,比逐条手写用例省心得多。
同样的写法还出现在 testDecode(解码方向)和 testUint8Arryay(字节数组输入)中,可见「数据表 + 循环 + @Expect」是仓颉单元测试最常用的套路。
四、UTF-8 中文场景:Rune 处理与编码断言
hibase32-cj 特意支持 UTF-8 中文编码,对应 testUtf8 与 testUtf8Decode:"中文"应编码为"4S4K3ZUWQ4======",解码后再变回原文。
这背后依赖仓颉的 Rune 字符类型(表示 Unicode 标量值中的单个字符):
因此测试数据里不仅放了中文,还放了带重音的aécio和补充平面字符𠜎,用 @Expect 断言编码结果,确保多字节字符不被截断或错码。
五、异常场景测试:@AssertThrows 让「该报错的必须报错」
对非法输入,正确行为不是「能跑通」,而是「必须抛错」——这正是@AssertThrows异常类型的用武之地。项目中有两处实战:
// 解码出非 UTF-8 字节 → 必须抛异常 @AssertThrowsException) // 含非法字符(如 "1 ======")→ 必须抛异常 @AssertThrowsException)分别见 testUtf8Exception 与 testInvaildString。真实运行中抛出的异常堆栈如下:
注意堆栈最上层正是测试文件中的断言行——异常确实被抛出、且被@AssertThrows成功捕获,所以该用例计为通过。这就是「负向测试」:断言错误行为本身,就是质量保障。
六、边界值清单:辅助函数同样要测
库内部自实现的小工具函数(如模拟 JS>>>的 unsignedRightShift、合法性检查 testVaildBase32)也要单独覆盖:
- testUnsignedRightShift:18 组 @Expect,覆盖正数、0、负数、移位位数为 0、移位位数大于 32 等边界;
- testVaildBase32:小写字母、
!、*等非法字符必须判 false,空串必须判 true。
七、总结:仓颉单元测试编写清单 📋
- 测试文件放在
src/test/目录; - 函数前加
@Test,即成为一个可运行的测试用例; - 值断言用
@Expect(实际值, 期望值),配合「数据表 + 循环」做批量断言; - 异常断言用
@AssertThrowsException,为非法输入兜底; cjpm test一键运行,全绿再提交。
对照 src/test/base32_test.cj 通读一遍,你就能在自己的仓颉项目里复刻这套完整的 Base32 编码测试模式了。
【免费下载链接】hibase32-cjBase32(RFC 4648)编码/解码库项目地址: https://gitcode.com/Cangjie-TPC/hibase32-cj
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考