Qem使用指南: 指导如何一步步使用qemu
Qemu仿真应用之模拟事件篇: 指导如何模拟触发事件告警
Qemu仿真应用之新增板块篇:指导如何替换板卡
现在,跟各位朋友一起来学习如何将qemu用于冒烟测试
Qemu冒烟测试
常见的冒烟测试都是运行在流水线上,但其实冒烟测试也可以运行在本地。在这里,我将会从如何在流水线上搭建qemu冒烟测试和在本地搭建qemu冒烟测试两个维度进行
冒烟测试框架
openUBMC冒烟测试是基于Robot Framework为基底,采用北向接口(cli、web、redfish和ipmi)来调用和测试openUBMC组件。
测试框架的搭建和用例编写可以参考qemu组件仓的/test/docs,也欢迎各位一起来搭建和完善测试框架和用例
Robot Framework简介
Robot Framework 是一个开源的自动化测试框架,主要用于验收测试和自动化流程。它采用关键字驱动和数据驱动的方式,使得测试用例易于编写和维护,适合功能测试、API测试、UI 测试 等场景。
Robot Framework的特点
- 关键字驱动:测试用例由可复用的关键字组成,降低编码门槛
- 易于扩展:支持 Python、Java 等语言编写自定义库
- 跨平台:支持 Windows、Linux、macOS
- 丰富的库生态:提供 Selenium、Requests、Appium、SSHLibrary 等扩展库
- 支持数据驱动:可以使用 CSV、Excel、数据库等方式管理测试数据
- 集成报告 & 日志:自动生成 HTML 报告和日志,方便调试和分析
核心语法
- *** Settings ***(配置区) 定义测试套件的全局设置
- *** Variables ***(变量区) 定义全局变量
- *** Test Cases ***(测试用例区) 编写测试用例
- *** Keywords ***(自定义关键字区) 封装可复用的操作
如何快速基于openUBMC的测试框架写一个测试用例
在这里,以一个ipmi测试用例为例,一步步地完成ipmi测试用例编写
*** Settings ***
Documentation 搭建ipmitool工具所需要的命令和变量
Resource ../resource.robot
Library OperatingSystem
Library BuiltIn
*** Keywords ***
Run External Ipmi Command
[Documentation] 使用带外ipmitool工具运行ipmi命令
[Arguments] ${command}
${ipmi_cmd}= Set Variable ipmitool -H ${OPENUBMC_HOST} -U ${OPENUBMC_USERNAME} -P ${OPENUBMC_PASSWORD} -p ${IPMI_PORT} -C ${IPMI_C} -I lanplus ${command}
Log Command Input: ${ipmi_cmd}
${rc} ${output}= Run And Return Rc And Output ${ipmi_cmd}
RETURN ${rc} ${output}
上面是ipmi.robot文件的内容
keywords: 关键字区,每个关键字相当于其他语言的函数
[Documentation]: 描述这个关键字的作用
[Arguments]: 描述关键字函数的入参,即需要的参数
${ipmi_cmd}: 构建ipmi命令,例如: ipmitool -H 127.0.0.1 -U Administrator -P Admin@90000 -p 10623 -C 17 raw 0x06 0x01
Log: 打印日志
Run And Return Rc And Output: robot framework封装的关键字,用于运行命令,命令执行成功返回0,否则返回非0
${rc}: 用于标记命令运行与否:命令执行成功返回0,否则返回非0
${output}: 运行ipmi命令的返回内容
RETURN: 函数输出
*** Settings ***
Documentation 通过ipmi接口测试openUBMC的设备id
Resource ../../test_function/ipmi/ipmi.robot
Library OperatingSystem
Library BuiltIn
Test Tags Ipmi_Device_Id
*** Variables ***
${input} raw 0x06 0x01
${expected_rc} ${0}
${expected_output} 00 00 01
*** Test Cases ***
Get IPMI Device ID
[Documentation] 带认证的IPMI设备ID测试
[Tags] Get_Device_Id
${rc} ${output}= Run External Ipmi Command ${input}
Log Command Output: ${output}
Should Be Equal ${rc} ${expected_rc} msg=${output}
Should Contain ${output} ${expected_output}
一个.robot文件就是一个测试套件,然后
Settings:一般用来描述整个测试套件的依赖项
- Documentation: 主要是用来描述这个测试套件的用途
- Resource: 资源文件,文件类型为.robot或.resource,包括可复用的关键字、变量定义和测试用例
- Library: 测试库,文件类型为.py文件或Java库,提供底层实现的函数/类方法
- Test Tags: 套件级标签,可以和单个测试用例的标签结合起来一起定义某个测试用例
Variables:变量区
一般存放该测试套件所需要的变量,如果很多套件都需要使用某个变量,例如openubmc的账号和密码,建议存放在test_function/resource.robot中,减少参数的使用】
${input}: ipmi命令的输入
${expected_rc}: 是否运行ipmi命令成功的标签,0:表示成功运行,非0:表示运行失败
${expected_output}: 运行ipmi命令成功后的返回值
Test Cases:测试用例区
一个.robot文件就是一个测试套件,一个测试套件可以存放多个测试用例,测试用例区用于存放测试用例的
Get IPMI Device ID:测试用例名称
[Documentation]:用来描述测试用例的名称
[Tags]: 这个测试用例的标签
Run External Ipmi Command:就是ipmi.robot里面的关键字,详细见上面
断言判断(重要):
Should Be Equal:判断${rc}和${expected_rc}是否相同,例如:如果${rc}=0和${expected_rc}=0,则相同
Should Contain:判断输出${output}是否包含${expected_output},如果${output} = db 07 00 00 00 01,${expected_output} = 00 00 01,则包含
更加详细的描述可见:docs/robotframework的测试框架.md和docs/断言判断的种类.md
冒烟测试流程
在qemu组件仓的test/smoke_test中主要存放了冒烟测试的代码:
- qemu/test/smoke_test/execute.py主要用来存放判断qemu是否连接web成功的代码
def try_web_access(port):
url = "https://127.0.0.1:{}/UI/Rest/Login".format(port)
retcode = -1
session = requests.Session()
session.trust_env = False
try:
with warnings.catch_warnings():
warnings.simplefilter(
"ignore", category=requests.packages.urllib3.exceptions.InsecureRequestWarning)
response = session.get(url, timeout=10, proxies={}, verify=False)
retcode = response.status_code
except requests.exceptions.RequestException as e:
pass
return retcode == 200
2.qemu/test/smoke_test/install_dependency.py 用来存放安装robot framework依赖项的代码,若您这边采用其他冒烟测试框架,可以直接替换test/requirements.txt即可
def install_dependency():
# 安装requirements里面的依赖项
try:
subprocess.run(
["pip", "install", "-r", "requirements.txt"],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
print("✅ 依赖安装成功!")
except subprocess.CalledProcessError as e:
print(f"❌ 依赖安装失败!错误信息:\n{e.stderr}")
close_qemu()
sys.exit(1)
- qemu/test/smoke_test/testing.py存放冒烟测试代码
在这里,我们采用两种方式:
- OPENUBMC_HOST=xx.xx.xx.xx SSH_PORT= HTTPS_PORT= robot -A test_lists/QEMU_CI redfish/ ipmi/
这种方式巧妙利用robot framework的标签特性,只需要在test_lists/QEMU_CI的文件中放入需要测试用例的标签,运行的时候会去自动从测试用例文件中筛选对应的测试用例
# 验证cli命令
--include Get_Maca_Status_Via_cli
--include Get_BCU_HW_Info_Via_cli
--include Get_Network_Adapter_Via_cli
--include Get_DeviceLocator_Info_Via_cli
--include Get_BMC_Version_Via_cli
...
- robot -v OPENUBMC_HOST:xx.xx.xx.xx redfish ipmi
这种方式是运行 redfish ipmi这两个测试用例文件夹下所有的测试用例
当然,robot framework测试运行方式是多种多样的,具体可以参考qemu/test/README.md
流水线冒烟测试
整体流程
用于manifest仓冒烟测试的流水线示意图
- 开发者向manifest仓提交pr
- ci门禁会自动将pr和远程的openUBMC的manifest仓合并,生成具有开发者修改的manifest仓
- 基于manifest仓采用bingo build -sc qemu构建出qemu仿真镜像包
- 结合远程qemu二进制工具拉起在manifest仓拉起qemu
- 通过判断web是否连接成功来判断qemu是否启动成功
- 若web连接成功,拉起远程测试代码仓,进行冒烟测试
- 无论是否成功,都会返回测试报告和关闭qemu
核心代码(更详细代码可以参考ci-repos/manifest/scripts/smoke_test.sh):
# 1.prepare env
echo "======start to prepare env======"
cur_path=$(pwd)
chmod +x /root/repo/ci-repos/.common_scripts/common.sh
source /root/repo/ci-repos/.common_scripts/common.sh
prepare_git $1 $2
prepare_conan $3 $4
prepare_bingo
prepare_sdk
# 2. 下载conan缓存
echo "======conan cache====="
prepare_qemu_cache
# 3. 构建仿真镜像包
echo "======Start build bmc simulation mirror package====="
cd $cur_path
bingo build -sc qemu
# 4.运行qemu(后台运行+日志记录)
echo "======Start running qemu===="
running_qemu
# 5.下载测试代码
# 扩展性:未来社区开发者可以替换为自己的自动测试代码仓并在里面执行冒烟测试脚本
echo "======Download test code===="
download_testing_code
# 6.进行冒烟测试
# 冒烟测试脚本是存放在自动测试代码仓的
echo "======Start smoke testing===="
smoke_testing
流水线效果
本地冒烟测试
若需要本地运行冒烟测试,您只需要做两件事:
sh test/smoke_test.sh








