测试开发
kunlun-data文件夹
首次安装Kunlun平台后, 执行 kunlun start
, 平台将自动创建 C:\kunlun-data
文件夹, 用户也可以自行创建此文件夹。
C:\kunlun-data
包含以下文件或文件夹.
db.sqlite3
:数据库文件, 保存测试记录.logs
:测试日志文件夹, 保存测试过程中产生的测试日志, 以及保存一些临时文件.tftpboot
:tftp
服务与ftp
服务的根文件目录.
定制用户界面
Win10用户可以通过以下方式将 测试程序示例
下载到 C:\kunlun-data
文件夹
cd C:\kunlun-data
git clone https://gitee.com/robinwu0607/kunlun_scripts
configs
中包含界面定制代码.demo
中包含演示测试代码.
用于演示的 autotest.py
文件的内容示例如下, 用户可以根据业务需要进行增加、修改或是拷贝:
# 导入接口函数库
from kunlun import lib
# 函数名必须是 main()
def main():
# 从lib.get_configuration()获取根实例kun
# tftp: 为True时将启动tftp服务, 默认为False
# ftp: 为True时将启动ftp服务, 默认为False
kun = lib.get_configuration(tftp=False, ftp=False)
# add_station: 在根实例Kl下增加一个Station工站
# name: 工站的名称
# desc: 工站的描述说明
# recycle: 为True时, Container测试PASS后, 将会自动重新开始测试, 免人工反复点击开始按钮.默认值为False
# image: 工站的封面图片.demo是项目名称, 建议图片的格式为.jpg或是.png
station = kun.add_station(name="PCBA", desc="PCBA功能测试", recycle=False, image=r"demo\bee.jpg", dense=True)
# 设置工站的测试任务所关联的用户代码路径.
# demo是项目名称, sequence是文件, 平台将调用sequence.py下的函数main_sequence()作为入口函数
station.add_sequence("demo.pcba")
station.add_connection(name="UDS", protocol="DUMMY")
# 设置工站的硬件参数, 用户在代码中可以使用lib.get_params("host")获取到参数的值
station.add_params_data(host="192.168.0.1", password="root")
# 用循环的方式连续添加Container工位
for i in range(4):
# add_container: 在工站实例station下增加一个Container工位.
# name: 工位的名称, 工位的名称动态累加
container = station.add_container(name="UUT{:02d}".format(i))
# 设置工位的硬件参数.工位会继承工站的硬件参数, 同时可以覆盖工站的参数, 或是新增专用的参数.
container.add_params_data(ip="192.168.1.{}".format(i), test="hello world")
# 增加一个Connection连接, 连接的协议为DUMMY, 将调用windows的cmd.exe窗口.
container.add_connection(name="UUT", protocol="DUMMY")
# 增加一个Connection连接, 连接的协议为SSH, 目标主机ip为192.168.0.2, 登入用户名为root, 密码为root.
container.add_connection(name="SSH", protocol="SSH", host="192.168.0.2", username="root", password="root", prompt="$")
# 增加一个Connection连接, 连接的协议为TELNET, 目标主机ip为192.168.0.3, 端口为2009.
container.add_connection(name="TNT", protocol="TELNET", host="192.168.0.3", port=2009, username="root", password="root", prompt="$")
# 增加一个Connection连接, 连接的协议为SERIAL, 目标端口为COM1, 波特率为115200.
container.add_connection(name="SER", protocol="SERIAL", serial="COM1", baudrate=115200)
# 增加MEASURE窗口
container.show_measure_panel()
# 在根实例Kl下增加第二个Station工站
station = kun.add_station(name="FCT", desc="FCT测试", recycle=False)
station.add_sequence("demo.fct")
for i in range(4):
container = station.add_container(name="UUT{:02d}".format(i))
container.add_connection(name="UUT", protocol="DUMMY")
# 增加MEASURE窗口
container.show_measure_panel()
# 增加STEP窗口
container.show_step_panel()
# 增加INFO窗口
container.show_info_panel()
需要注意的是:每次对 autotest.py
进行修改, 必须使用 kunlun start
重启服务, 修改后的内容才会生效.
需要再次强调的是, 平台会根据 add_sequence()
中的入参调用对应项目下的 .py
文件的 main_sequence()
函数作为入口函数.
开发者模式与生产模式
在测试主界面, 用户可以自由切换 生产模式
与 开发模式
(默认为 生产模式
), 平台后台将根据选择的模式,
自动处理调用 kunlun_scripts
或是 develop
文件夹下测试代码.
需要强调的是:每次页面刷新后, 测试模式将会默认切换至 生产模式
.
测试服务
平台提供 FTP
与 TFTP
服务.
FTP服务
用户在定制界面时, 若设置 lib.get_configuration(ftp=True)
, 启动平台时, FTP服务也将启动.
FTP的默认文件夹是 C:\kunlun-data\tftpboot
, 用户名密码为: autotest/autotest
.
TFTP服务
用户在定制界面时, 若设置 lib.get_configuration(tftp=True)
, 启动平台时, TFTP服务也将启动.
FTP的默认文件夹是 C:\kunlun-data\tftpboot
.
需要注意的是:
当
lib.get_configuration(ftp=True, tftp=True)
时, FTP服务与TFTP服务将同时启动, 不冲突.FTP服务
使用端口21
,TFTP服务
使用端口69
.
测试代码开发方案
用户的代码存放于 C:\kunlun-data\kunlun_scripts
或是 C:\kunlun-data\develop
下.
给开发者建议:
用户项目下的文件夹与文件, Python代码开发规范参考PEP8规范, PEP8链接为: https://www.python.org/dev/peps/pep-0008/
用户项目下的每一个文件夹, 都包含文件
__init__.py
.用户项目文件夹的名称与实际项目名称保持一致.
使用
git
等版本工具管理测试代码.
基于不同的测试需求与目标, 用户可以采用快速开发方案或是测试序列编排方案.
小型项目快速开发
建议采用快速开发方案的是:
相对独立的项目(较少与其他项目复用代码).
测试命令行小于或等于20条的项目.
快速开发方案的演示代码可以参考 C:\kunlun-data\kunlun_scripts\demo\fct.py
.
以下截取部分代码片段进行说明:
from kunlun import lib
import time
# 获取事件日志接口
log = lib.get_event_logger()
# 定义入口函数, 每个文件只有一个入口函数.
def main_sequence():
log.debug("welcome to main sequence")
container_name = lib.get_container_name()
log.debug(container_name)
ans = lib.ask_question("输入序列号:")
log.debug("ask_question: [%s]", ans)
ans = lib.ask_question("选择产品类型:", options=["12-3456-78", "98-7654-32"])
log.debug("ask_question choose: (%s)", ans)
ans = lib.ask_question("选择产品类型:", options=["12-3456-78", "98-7654-32"], multiple=True)
log.debug("ask_question multiple choose: (%s)", ans)
ans = lib.ask_questions(["输入序列号:", "输入MAC:", "输入编码:"])
log.debug("ask_questions: (%s)", ans)
lib.ud.hello = "good"
uut = lib.conn.UUT
uut.open()
log.debug("run test1: dir")
uut.send("dir\r", expect=">", timeout=10)
time.sleep(1)
log.debug(lib.get_params())
lib.add_test_data(sernum="1234567890", uuttype="DEMO", area="DEMO")
run_test2()
run_test4()
return
def run_test2():
uut = lib.conn.UUT
uut.open()
log.debug("run test2")
uut.send("dir\r", expect=">", timeout=10)
if "UUT01" in lib.get_container_name():
lib.set_step_name("Test Step2")
raise Exception("run test failed")
time.sleep(2)
return
def run_test4():
lib.set_display1("SERNUM: 1234567890")
lib.set_display2("UUTTYPE: 12-3456-78")
log.debug("userdict1: {}".format(lib.ud.hello))
log.debug("userdict2: {}".format(lib.ud))
return
大型项目测试编排
建议采用测试序列编排方案的是:
大型项目的子项目(较多与其他项目复用代码).
持续演进的项目.
需要实施较多测试策略的项目.
测试命令行大于20条的项目.
测试序列编排方案的演示代码可以参考 C:\kunlun-data\kunlun_scripts\demo\pcba.py
.
以下截取部分代码片段供参考:
from kunlun import lib
import time
# 获取事件日志接口
log = lib.get_event_logger()
# 定义入口函数, 每个文件只有一个入口函数.
def main_sequence():
# 增加一个根测试序列sequence, 并设置名称为MAIN SEQ
seq = lib.get_sequence_definition("MAIN SEQ")
# 根序列增加一个step, 并设置此step名称为RUN TEST, 如果测试失败, 则失败项为RUN TEST
seq.add_step(run_test, name="RUN TEST")
# 根序列增加一个step, 并传参数kws给step
seq.add_step(run_test1, name="run test1", kws={"name": "gps test", "value": "cpu test"})
# 根序列增加一个子测试序列, 并设置名称为SUB MAIN SEQ
# in_parallel: 并行测试标识, 为True时, 将与 下一个step/测试序列 并行执行
# 测试循环次数设置为3次
sub_seq = seq.add_sequence("SUB MAIN SEQ", in_parallel=True, cycle_count=1)
# 子序列增加一个step
sub_seq.add_step(run_test2, name="run test2-1")
# 子序列增加一个step
sub_seq.add_step(run_test2, name="run test2-2")
# 根序列增加一个step
# 测试循环时间为30秒
seq.add_step(run_test3, name="RUN TEST3", cycle_time=1)
# 根序列增加一个step.
seq.add_step(run_test4, name="run TEST4")
# 返回根序列
return seq
def run_test():
log.debug("welcome to main sequence")
container_name = lib.get_container_name()
log.debug(container_name)
ans = lib.ask_question("输入序列号:")
log.debug("ask_question: [%s]", ans)
ans = lib.ask_question("选择产品类型:", options=["12-3456-78", "98-7654-32"])
log.debug("ask_question choose: (%s)", ans)
ans = lib.ask_question("选择产品类型:", options=["12-3456-78", "98-7654-32"], multiple=True)
log.debug("ask_question multiple choose: (%s)", ans)
ans = lib.ask_questions(["输入序列号:", "输入MAC:", "输入编码:"])
log.debug("ask_questions: (%s)", ans)
lib.ud.hello = "good"
return
def run_test1(name="name", value="value"):
log.debug("name: {}".format(name))
log.debug("value: {}".format(value))
uut = lib.conn.UUT
uut.open()
log.debug("run test1: dir")
uut.send("dir\r", expect=">", timeout=10)
time.sleep(1)
# log.debug(lib.get_json_params("Sheet1", "param1"))
# log.debug(lib.get_json_params("Sheet1", "param*"))
# log.debug(lib.get_json_params("Sheet1", "*_test"))
# log.debug(lib.get_json_params("Sheet1", "*"))
log.debug(lib.get_params())
return
def run_test2():
uut = lib.conn.UUT
log.debug("run test2")
uut.send("dir\r", expect=">", timeout=10)
if "fail" in uut.buf:
raise Exception("run test failed")
time.sleep(2)
return
def run_test3():
log.debug("run test3")
time.sleep(2)
return
def run_test4():
lib.set_display1("SERNUM: 1234567890")
lib.set_display2("UUTTYPE: 12-3456-78")
lib.add_test_data(sernum="1234567890", uuttype="DEMO", area="DEMO")
log.debug("userdict1: {}".format(lib.ud.hello))
log.debug("userdict2: {}".format(lib.ud))
return
需要说明的是: lib.get_sequence_definition()
中可以承载较多的测试策略, 用户可以将精力投入到测试业务代码本身, 聚焦更有价值的部分, 测试策略交给平台处理.
需要注意的是: 入口函数 main_sequence()
必须 return
根测试序列 seq
给到平台, 否则平台将无法执行测试序列.
导入其他pip依赖包
直接使用 pip install
安装对应依赖包即可.
命令行kunlun run
使用命令行执行测试用例, 方便在测试程序发布前, 快速单独验证测试代码, 及时发现代码问题:
Usage: kunlun run [prodcut] [case] [--param] [--key value] [--develop] [--help]
kunlun run --help
可以查看帮助信息.
kunlun run [prodcut] [case] --param --key value
可以注入参数到测试用例。
kunlun run [prodcut] [case] --develop
可以调用开发模式下的测试用例。
以项目 demo
为例, 首先需要在项目下创建文件夹 testcase
, 得到 demo/testcase/
.
demo
代码中可用的示例:
kunlun run demo test_demo
TestCase的写法:
class类结构.
class类结构式测试用例
在 demo/testcase/
文件夹下创建 .py
文件, 文件中创建 class TestCase(lib.TestCase)
类, 需要继承 lib.TestCase
.
运行中, 平台会调用 setup()
, 再调用 run()
, 无论结果是PASS还是FAIL, 最后调用 teardown()
, 测试用例如下:
from kunlun import lib
import time
# 获取事件日志接口
log = lib.get_event_logger()
class TestCase(lib.TestCase):
"""This is the Test Case document."""
uut = None
def __init__(self) -> None:
super().__init__()
def setup(self):
log.info("it is setup")
# add temp connection for use.
lib.add_connection(name="SSH",
protocol="SSH",
host="172.28.247.192",
username="lenovo",
password="lenovo",
prompt="$")
self.uut = lib.conn.SSH
self.uut.open()
def teardown(self):
log.info("it is teardown")
self.uut.close()
def run(self):
log.info("run demo cli")
for i in range(3):
self.uut.send("pwd\r", expect=[">", "$"], timeout=30)
time.sleep(2)
需要说明的是, 方法 setup()
, run()
与 teardown()
都不能定义入参.
图形化编程 Graphical Programming
尝试引入图形化编程来简化测试开发, 当前图形化编程只能完成简易的测试开发, 后续再慢慢完善.
通过点击菜单进入对应图形化编程界面.
用户可以在以下地址下载测试程序示例.
https://gitee.com/robinwu0607/kunlun_scripts
Configs Editor
Configs Editor用来定制测试界面, 文件保存在 configs
中.
TestCase Editor
TestCase Editor用来开发测试用例, 文件保存在 demo/testcase
中。
Sequence Editor
Sequence Editor用来开发测试序列, 文件保存在 demo/sequence
中。