Skip to content

[讨论] 如何确保单元测试用例名字的唯一性 #10681

Closed

Description

@unicornx

现在 unit testcase 的名字的命名规则如下, 参考 https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/utest/utest

Image

但随着目前 testcases 会从 examples/utest/testcases 下移出到各自所属模块的目录下,这个规则需要改变。现提出来欢迎大家讨论。确定下来后我提个 pr 一起改掉。

建议修改为:测试用例名称确保(唯一性)。完整名称由两部分组成:

模块前缀 + 测试功能, 中间以 ”." 连接。

模块前缀使用测试用例相对源码仓库根目录的相对路径,以 “.” 进行连接的命名格式。
测试功能自己定义即可,确保在同一个模块前缀下唯一。

以 dfs 为例,

  • 模块前缀为:"components.dfs"
  • API 测试(components/dfs/utest/tc_dfs_api.c),功能名称为 "fs_dfs_api_tc"

所以 components/dfs/utest/tc_dfs_api.c 中的写法如下:

UTEST_TC_EXPORT(testcase, "components.dfs.fs_dfs_api_tc", utest_tc_init, utest_tc_cleanup, 10);

另外,对于 src 目录下的模块,由于 src 这个目录名字比较含糊,为了和 components 相对,建议用 core 替换,表示 src 下的代码都是内核 core 代码,用来和 components 下的区分

所以 src/klibc/utest/TC_rt_memcmp.c 下的可以改写为:

UTEST_TC_EXPORT(utest_do_tc, "core.klibc.rt_memcmp", RT_NULL, RT_NULL, 1000);

附件是搜索 UTEST_TC_EXPORT 的结果:

UTEST_TC_EXPORT.txt

Activity

  1. unicornx commented on Sep 10, 2025

    @unicornx
    ContributorAuthor

    @Rbb666 @kurisaW 欢迎 comment

  2. Rbb666 commented on Sep 10, 2025

    @Rbb666
    Member

    个人感觉:测试用例目录.测试用例名称 这样命名会清晰一点

    RTT 文档中心也有相关的描述:

    Image

    比如:

    • components/dfs/utest/tc_dfs_api.c 的写法:components.dfs.tc_dfs_api
    • src/klibc/utest/tc_rt_memcmp.c 的写法:src.klibc.tc_rt_memcmp
  3. unicornx commented on Sep 10, 2025

    @unicornx
    ContributorAuthor

    个人感觉:测试用例目录.测试用例名称 这样命名会清晰一点

    我感觉你说的这个和我提的其实差不多啊,区别仅仅在于

    • 你说的 “测试用例目录” 其实就是我说的 “模块前缀”,我提的 “模块前缀” 的格式就是基于路径名,把 “/” 换成 “.”。和你的想法是一回事。具体可以看我的举例子。可能我没说清楚,以后可以补充。另外,我对 src 这个希望作为一个特列,因为我觉得 src 这个目录名字不好看而已,当然如果不做特别要求,src 我也没意见。(说实在的我觉得原来代码目录里这个 src 真心是个不好的名字)
    • 你说的“测试用例名称” 从你举的例子来看似乎和文件名绑定了,而我的建议的第二部分 “测试功能” 其实对于这个要求更松一些,只要确保在同一个 “模块前缀” 范围内唯一即可,从现有的代码来看,大家其实都没有实现文件名和测试用例名一致,我觉得没有必要强制要求一致,否则改起来改动太大。
  4. kurisaW commented on Sep 11, 2025

    @kurisaW
    Member

    确实感觉现在的测试用例命名不够规范,最好是能一眼看出这个测试用例的用途。

    下面是个人观点:比较赞同像 kernel.klibc.rt_memcmp写法(即 category.module.module_test,分三级来定义),其实测试用例重点针对的还是组件还有内核这两大块,不一定要使用 src/component(依据目录名来定),例如lwip可以命名:net.lwip.lwip_loopback;

    然后就是实际测试用例存放的目录需不需要考虑进一步细分,比如 kernel mem,这么这里其实如果只给一个测试用例文件并且做命名的话,整体看起来会非常庞大(因为需要考虑的测试覆盖范围肯定不仅单一几个),下面是一个AI生成的测试项说明:

    ### **RTOS 内存管理测试用例列表**
    
    #### **一、 核心功能测试**
    1.  内存分配与释放基础功能测试
    2.  不同大小内存块(从最小到最大)的分配测试
    3.  内存分配对齐(Alignment)验证测试
    4.  重复释放(Double-Free)错误检测测试
    5.  空指针(NULL)分配与释放处理测试
    6.  内存池(Memory Pool)分配与回收测试
    7.  堆空间耗尽后的分配失败处理测试
    
    #### **二、 性能与实时性测试**
    8.  最坏情况下的内存分配耗时测试(WCET)
    9.  内存分配/释放操作的平均时间消耗测试
    10. 多任务并发分配/释放内存时的性能测试
    11. 内存碎片化对分配性能和成功率的影响测试
    
    #### **三、 稳定性与压力测试**
    12. 长时间运行下的内存泄漏(Memory Leak)检测测试
    13. 高频率随机大小内存分配/释放压力测试
    14. 多任务竞争环境下的内存操作稳定性测试(竞态条件测试)
    15. 内存池枯竭(Exhaustion)场景下的系统行为测试
    
    #### **四、 多任务与并发测试**
    16. 任务优先级继承与内存分配互斥锁测试
    17. 在中断服务程序(ISR)中分配/释放内存的测试
    18. 多个任务同时访问同一内存池的并发安全性测试
    
    #### **五、 边界与异常测试**
    19. 分配大小为0的内存请求处理测试
    20. 分配超过堆/池最大限制的内存请求测试
    21. 对已释放或未分配的内存进行写操作测试(野指针)
    22. 内存分配失败后系统的错误恢复机制测试
    
    #### **六、 碎片化处理测试**
    23. 内存碎片化程度评估与监控测试
    24. 动态内存分配算法(如TLSF)的抗碎片化能力测试
    25. 内存压缩或碎片整理功能(如支持)的有效性测试
    
    #### **七、 统计信息与诊断测试**
    26. 内存使用率统计信息的准确性测试
    27. 当前空闲内存块数量与大小统计功能测试
    28. 堆栈溢出检测机制(如MPU/MMU支持)测试

    建议可以额外增设一级,也就是依据上面三级定义的模式,类似:

    |---utest
        |---category
            |---module
                |---module_tc.c
  5. unicornx commented on Sep 11, 2025

    @unicornx
    ContributorAuthor

    下面是个人观点:比较赞同像 kernel.klibc.rt_memcmp写法(即 category.module.module_test,分三级来定义),其实测试用例重点针对的还是组件还有内核这两大块,不一定要使用 src/component(依据目录名来定),例如lwip可以命名:net.lwip.lwip_loopback;

    之所以用目录来定义 “模块前缀”, 主要是考虑目前并没有一个地方定义(标准化) cateory 和 module 这些关键字。如果要重起炉灶也是一个费时费力的事情,考虑到目前内核源码树中的目录安排应该已经是前人的经验总结,直接用目录来确保 testcase 的 “模块前缀” 的唯一性其实是一个不错的选择。

    而我提出用 “core” 代替 “src”,只是因为我觉得 “src” 这个目录名字其实定义得不好而已。我不建议用 “kerenl” 是因为我觉得 “kernel” 包括了 “core” 和 “components” 两部分,不知大家是否同意我这个想法。

    建议可以额外增设一级,也就是依据上面三级定义的模式,类似:

    |---utest
    |---category
    |---module
    |---module_tc.c

    增设一级还是两级其实同样的问题就是谁来制定,谁来标准化?为了节省人力以及尽可能复用现有资源,正如上面我已经说过,还不如利用现有目录安排。(其实原来的 utest 的 name 命名原则也是这个意思,只不过那时是相对于 examples/utest/testcases. 而现在是相对于 RTT 源码根目录,原因我一开始就解释过了。)

  6. Rbb666 commented on Sep 11, 2025

    @Rbb666
    Member

    下面是个人观点:比较赞同像 kernel.klibc.rt_memcmp写法(即 category.module.module_test,分三级来定义),其实测试用例重点针对的还是组件还有内核这两大块,不一定要使用 src/component(依据目录名来定),例如lwip可以命名:net.lwip.lwip_loopback;

    之所以用目录来定义 “模块前缀”, 主要是考虑目前并没有一个地方定义(标准化) cateory 和 module 这些关键字。如果要重起炉灶也是一个费时费力的事情,考虑到目前内核源码树中的目录安排应该已经是前人的经验总结,直接用目录来确保 testcase 的 “模块前缀” 的唯一性其实是一个不错的选择。

    而我提出用 core 代替 src,只是因为我觉得 “src” 这个目录名字其实定义得不好而已。我不建议用 kerenl 是因为我觉得 kernel 包括了 core 和 components 两部分。

    建议可以额外增设一级,也就是依据上面三级定义的模式,类似:
    |---utest
    |---category
    |---module
    |---module_tc.c

    增设一级还是两级其实同样的问题就是谁来制定,谁来标准化?为了节省人力以及尽可能复用现有资源,正如上面我已经说过,还不如利用现有目录安排。(其实原来的 utest 的 name 命名原则也是这个意思,只不过那时是相对于 examples/utest/testcases. 而现在是相对于 RTT 源码根目录,原因我一开始就解释过了。)

    我这边是赞同这个命名方式的,也没必要去修改之前的规则,src重命名core我也没问题。
    命名按照三级定义的模式会好一些,比较清晰一些。

  7. kurisaW commented on Sep 11, 2025

    @kurisaW
    Member

    我建议是需要推动规范化和标准化的,不能反复拉扯非标准问题,现在不弄以后其实还是会有这种顾虑,那接下来就是针对具体代码情况去推动这里的规范定义了,可以先起个草案一起审核下

  8. Rbb666 commented on Sep 11, 2025

    @Rbb666
    Member

    针对此issue进行简单总结:

    @unicornx @kurisaW

    举例:

    1. 针对像:components/legacy/usb 下面如果新增测试用例 components/legacy/usb/utest/test.c
      命名需要是:components.legacy.usb.test

    2. 如果更深的路径,比如:components/a/b/c/d/utest/test.c
      命名需要是:components.a.b.c.d.xxx

    最后一个字段可以不和文件一致,可以体现测试内容即可

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions