DT用例编写指南
更新时间:2025/10/15
在Gitcode上查看源码

DT用例编写指南

1. 背景

openUBMC的单元测试(UT)与集成测试(ST)在项目规划初期伴随业务代码就开始实施,主要为了保证业务代码的功能正确、高效开发,保证对外资源的可靠性。

2. 开发流程(以IAM模块为例)

  1. 整体业务功能框架搭建
  2. 底层数据操作逻辑开发(UT)
  3. 业务层操作汇总(UT)
  4. 资源树数据管理(ST)
  5. 整体业务功能测试(UT、ST)

3. UT数据准备与清理

**原则:**测试不依赖外部环境(包括默认配置、绝对路径等),初始化工作和清理工作需要充分完成。

建议:

  • 建立临时目录,拷贝外部依赖的文件。
  • 对需要外部输入的配置统一设定参数入口,在配置文件里进行配置。
  • 数据的清理可以在开始前先做一次。

4. UT的Mock

对依赖skynet或者其他模块的功能,可以临时打桩实现。

**示例:**KMC功能的Mock

两种Mock方式可以参考:

lua
local kmc = require 'mc.kmc'
local KmcEnc = kmc.encrypt_data
local KmcDec = kmc.decrypt_data

function TestIam:setUp()
    -- mock kmc
    kmc.encrypt_data = function(domain_id, cipher_alg_id, hmac_alg_id, plaintext)
        return plaintext
    end
    kmc.decrypt_data = function(domain_id, ciphertext)
        return ciphertext
    end
end

function TestIam:tearDown()
    kmc.encrypt_data = KmcEnc
    kmc.decrypt_data = KmcDec
end
lua
-- 自己实现一个kmc_client:hica/apps/security/src/lualib/certificate/infrastructure/kmc_client.lua

function TestCertificate:setupClass()
    -- 其他操作
    self.kmc_client = KmcClient.new(nil, true)
    -- mock KMC
    self.kmc_client.decrypt_cert_key = function(cls, encrypt_string)
        return encrypt_string
    end
    self.kmc_client.encrypt_cert_key = function(cls, plaintext)
        return plaintext
    end
end

5. UT的调试

测试驱动开发提效神器,F5可以直接调试,x86环境下业务功能开发必备。

6. ST资源树与RPC请求

很多功能需要上资源树,UT无法和D-Bus联动,涉及资源树相关的功能需要在ST中进行测试。

相关RPC的操作:

lua
local function get_property(bus, prop_name)
    return bus:call('ibmc.app.Iam', '/bmc/kepler/SessionService',
        'org.freedesktop.DBus.Properties', 'Get', 'ss', 'bmc.mdb.SessionService', prop_name):value()
end

local function set_property(bus, prop_name, value)
    return bus:call('ibmc.app.Iam', '/bmc/kepler/SessionService',
        'org.freedesktop.DBus.Properties', 'Set', 'ssv', 'bmc.mdb.SessionService', prop_name, gvariant.new_uint32(value))
end

因为ST启动了相关服务,底层功能不用Mock可以直接使用,方便联调测试整体功能。

lua
function AccountCases.test_change_account_pwd(bus)
    assert(iam:ChangeAccountPwd(bus, 2, "Administrator", "xxx") ~= nil)
    local ret = iam:Authenticate(bus, "Administrator", "xxx")
    assert(ret.UserId == 2)
    assert(iam:ChangeAccountPwd(bus, 2, "Administrator", "xxx") ~= nil)
end

7. ST调试

添加打印日志,从顶层模块一直打到底层模块,可以灵活测试和调试。

注意:skynet支持console,目前有VSCode插件或其他方式实现skynet服务的调试。如需要可以参考:https://github.com/colinsusie/skynetda

8. 用例耦合与解耦

  1. 业务逻辑内聚:保持业务逻辑的内聚性。
  2. 单个用例的操作不要过于复杂:建议单个用例调用的方法数量不超过5-10个。