311 lines
16 KiB
Plaintext
311 lines
16 KiB
Plaintext
** 此文件指导添加测试用例 **
|
||
|
||
目录:
|
||
1. 简介
|
||
2. 添加源码/脚本(可选)
|
||
3. 注册新用例(必选)
|
||
4. 添加量产默认配置(可选)
|
||
5. 注销旧用例
|
||
6. 测试用例API
|
||
|
||
============================分割线===========================
|
||
|
||
1. 简介
|
||
----------------------------------------------
|
||
1. 测试用例按功能分类,分别为demo/base/spec/stress,新测试用例务必在对应分类中添加
|
||
2. tinatest/testcase目录存放所有测试用例,一个测试用例一个单独文件夹,
|
||
且对应测试用例的配置路径存放,例如:
|
||
测试用例为 /stress/rw/rw-auto , 则测试用例源码目录路径为 tinatest/testcase/stress/rw/rw-auto .
|
||
3. 通过测试用例目录下的 private.conf 文件配置测试用例路径和默认配置值.
|
||
通过 tools/add_testcase.sh 和 tools/del_testcase.sh 脚本注册和注销测试用例.
|
||
4. 注册测试用例后,需要进入menuconfig中选择测试用例,然后在tinatest根目录或者其子目录执行 'mm -B' 来
|
||
重新编译测试用例,在编译过程中会根据menuconfig的配置生成新的tinatest.json.
|
||
|
||
新测试用例有如下5个相关文件:
|
||
(1) tinatest/testcase/<class>/<testcase>/private.conf
|
||
创建用例属性配置文件,包括用例路径,调用测试用例命令,默认配置等.
|
||
|
||
(2) tinatest/testcase/<class>/list
|
||
添加新用例到用例列表
|
||
|
||
(3) tinatest/config/<class>/Config-<testcase>.in
|
||
创建新用例的menuconfig配置文件
|
||
|
||
(4) tinatest/config/<class>/Config.in
|
||
添加用例配置文件到menuconfig的配置列表
|
||
|
||
(5) tinatest/Depends.mk
|
||
添加用例依赖,当测试用例有依赖时才会修改
|
||
|
||
用 tools/add_testcase.sh 自动注册测试用例,只需自行编写第1个文件(private.conf),
|
||
且知道其他文件的作用, 以便提交代码时,验证5个相关的文件,然后把此5个相关文件的修改一并提交.
|
||
|
||
|
||
2. 添加源码/脚本(可选)
|
||
----------------------------------------------
|
||
(1) 为什么此步骤可选?
|
||
例如:
|
||
"reboot" : {
|
||
"enable" : false,
|
||
"command" : "echo \"Going to reboot\"; reboot -f",
|
||
"may_reboot" : true,
|
||
"run_times" : 1000
|
||
},
|
||
"CPU" : {
|
||
"run_alone" : true,
|
||
"command" : "stress --cpu 5 --timeout 1m"
|
||
}
|
||
--------------
|
||
a. reboot节点并不需要任何脚本,仅仅是依据"reboot -f"命令即可实现
|
||
b. CPU节点调用的是外部的应用,因此并不需要额外添加脚本/源码,一句shell命令就足够了
|
||
|
||
(2) 如何添加源码/脚本?
|
||
tinatest/testcase目录存放所有测试用例,一个测试用例一个单独文件夹,且对应测试用例的配置路径存放,
|
||
例如:
|
||
新用例为 /stress/rw/rw-auto , 则测试用例源码目录路径为 tinatest/testcase/stress/rw/rw-auto
|
||
|
||
(3) 编译源码
|
||
编译源码的操作分两种情况:
|
||
(a)源码目录无Makefile
|
||
(b)源码目录有Makefile
|
||
--------------
|
||
(a)源码目录无Makefile
|
||
把源码目录的每个 c/cpp 文件逐个编译链接为对应执行文件.例如 demo-c.c 编译为 demo-c
|
||
把源码目录的所有 sh 文件拷贝安装
|
||
(b)源码目录有Makefile
|
||
执行源码目录的Makefile来编译测试用例.
|
||
编写Makefile时需要注意:
|
||
*) 上级Makefile只会调用源码Makefile的 all 目标,因此必须存在 all 目标
|
||
*) 编译出来的可执行文件/脚本必须拷贝安装到变量 PREFIX 指定的路径
|
||
例如: cp $(TARGET) $(PREFIX)
|
||
*) 传递的其他变量: CC/CXX/ARCH/AR/CFLAGS/LDFLAGS
|
||
|
||
3. 注册新用例(必选)
|
||
----------------------------------------------
|
||
(1) 自动添加(推荐):
|
||
(a) 添加新用例属性配置文件
|
||
配置文件保存路径: tinatest/testcase/<class>/<testcase>/private.conf
|
||
--------------
|
||
执行 tinatest/tools/add_testcase.sh 不带任何参数即可获取下面的说明
|
||
--------------
|
||
|
||
记录新用例的路径以及默认配置值,一行一条键值对,格式为:
|
||
<配置项>[:类型] = <配置值>
|
||
[配置项]: 包含PATH/ENABLE/INFO/LIMIT/DEPENDS和测试用例的所有配置项(例如:command,run_times,run_alone等)
|
||
其中:
|
||
PATH: 测试用例在配置树中的绝对路径(字符串)
|
||
ENABLE: 默认是否使能此用例(bool)
|
||
INFO: 默认是否使能所有的 局部信息 配置项(bool)
|
||
LIMIT: 默认是否使能所有的 局部限制 配置项(bool)
|
||
DEPENDS: 测试用例依赖的第三方应用包(string)
|
||
格式: +TINATEST_<测试用例路径>_ENABLE:<依赖的软件包>
|
||
例如 /stress/rw/rw-auto 依赖 rwcheck 软件包, 则 DEPENDS="+TINATEST_STRESS_RW_RW_AUTO_ENABLE:rwcheck"
|
||
[大写字母为特定配置项][无指定类型的小写字母为用例属性项][指定类型的小写字母为私有配置项]
|
||
[类型]: (私有配置项才需要)为mjson支持的数据类型,包括:int/double/true/false/string/array
|
||
[配置值]: 支持字符串/字符串数组/整数/浮点数/bool(见示例)
|
||
其中:
|
||
1) 字符串必须用双引号括起来
|
||
2) 字符串数组以字符串形式表示,字符串之间以空格间隔
|
||
4) 字符串内若双引号\转义字符等,需要有双重转义, 例如: command = "echo \\\"test\\\"" 表示echo "test"
|
||
4) 每一行开头不能有空格/Tab等
|
||
|
||
示例如下:
|
||
|PATH = /demo/demo-c
|
||
|ENABLE = false
|
||
|INFO = true
|
||
|command = "demo-c"
|
||
|run_times = 10
|
||
|run_alone = false
|
||
|workers:int = 2
|
||
|words:string = "test"
|
||
|right:bool = true
|
||
|str_array:array = "one two three"
|
||
|
||
(b) 执行自动创建脚本 (tinatest/tools/add_testcase.sh)
|
||
Usage: add_testcase.sh <配置文件1> [配置文件2] ...
|
||
示例:
|
||
./tools/add_testcase.sh testcase/stress/io/private.conf
|
||
|
||
Note: 当无参数时,显示帮助说明
|
||
示例:
|
||
./tools/add_testcase.sh
|
||
|
||
(2) 手动添加(不推荐):
|
||
以手动添加新用例base-demo为例,配置文件节点路径为: /base/base-demo
|
||
(a) 文件1: tinatest/testcase/base/list <<== 添加用例到convert_json.sh的处理列表
|
||
在tinatest/testcase/base/list中添加一行:/base/base-demo
|
||
注意的是,要单独一行,且为配置树的绝对路径
|
||
(b) tinatest/testcase/<class>/<testcase>/private.conf <<== 创建用例属性配置文件
|
||
见 (1) 自动添加 -> (a) 添加用例属性配置文件
|
||
(c) tinatest/config/<class>/Config-<testcase>.in <<== 创建新的menuconfig用例配置文件
|
||
(c.1) 拷贝用例配置文件模板(注意新配置模板文件名格式)
|
||
$ cd tinatest/config && cp demo/Config-demo-c.in base/Config-base-demo.in
|
||
(c.2) 修改配置模板的菜单名
|
||
把Config-base-demo.in第一行的menu 'demo-c'改为menu 'base-demo'
|
||
(c.3) 修改配置模板的配置项名(注意替换名,新用例为/base/base-demo,则替换为_BASE_BASE_DEMO_
|
||
$ sed -i 's/_DEMO_DEMO_C_/_BASE_BASE_DEMO_/g' Config-base-demo.in
|
||
(d.4) 定制默认配置值,把各个配置项的'default'改为新用例的对应配置值即可
|
||
例如: 新用例command的默认值为"echo base-demo",则把command配置项的配置默认值修改为:
|
||
config TINATEST_BASE_DEMO_COMMAND
|
||
string "command"
|
||
default "echo base-demo"
|
||
(d) tinatest/config/<class>/Config.in <<== 添加用例配置文件到menuconfig的配置列表
|
||
添加到文件 tinatest/config/base/Config.in
|
||
例如:
|
||
config TINATEST_BASE
|
||
bool "Enable"
|
||
|
||
if TINATEST_BASE
|
||
source Config-base-demo.in <<< 添加此行
|
||
endif
|
||
(e) tinatest/Depends.mk <<== 添加用例依赖
|
||
当测试用例依赖第三方应用时才需要的操作,在指定文件中按指定格式添加行
|
||
格式: +[menuconfig中指定测试用例使能配置项:]依赖名
|
||
例如: 新应用 /stress/readwrite 依赖其他应用: rwcheck
|
||
+TINATEST_STRESS_READWRITE_ENABLE:rwcheck
|
||
(当menuconfig中使能了/stress/readwrite测试用例才依赖rwcheck)
|
||
(TINATEST_STRESS_READWRITE_ENABLE: 参考3. 添加menuconfig的可视化配置)
|
||
|
||
此5个文件修改完成后即可在menuconfig中看到新的用例配置,以及自动生成tinatest.json配置文件
|
||
|
||
4. 添加量产默认配置(可选)
|
||
----------------------------------------------
|
||
(1) 为什么可选?
|
||
一般情况下,通过配置menucofnig即可自动生成配置文件,但为了节省客户配置tinatest的麻烦,
|
||
特提供一份默认的配置文件tinatest/src/config/tinatest.json.此配置文件只使能量产需要的
|
||
base(基础功能测试)用例,作为客户量产的默认功能测试配置,因此非客户量产需要的测试用例不
|
||
建议添加到默认tinatest.json中.
|
||
|
||
(2) 如何添加?
|
||
eg. /stress/IO/newdemo
|
||
| "/" : {
|
||
| "stress" : {
|
||
| "enable" : true, (使能控制,默认true,影响此节点及树叉下的所有子节点)
|
||
| "reboot" : {
|
||
| .... (/stress/reboot)
|
||
| },
|
||
| "IO" : {
|
||
| "newdemo" : { (添加新测试用例节点)
|
||
| "command" : "newdemo.sh" (shell调用测试用例的命令)
|
||
| }
|
||
| }
|
||
| }
|
||
| }
|
||
Note: 新测试用例节点必须有"command"项,为shell调用测试用例的命令,
|
||
其他的高级配置参考Config.txt
|
||
|
||
5. 注销旧用例
|
||
----------------------------------------------
|
||
(1) 注销用例使用脚本路径如下:
|
||
tinatest/tools/del_testcase.sh
|
||
(2) 使用场景
|
||
*) 需要修改用例属性(修改private.conf,不包括源码/脚本),
|
||
在修改private.conf前先注销,修改后再重新注册,避免残留
|
||
*) 删除无用测试用例
|
||
(3) 使用方法
|
||
与 < 3. 注册新用例 - (1) 自动添加 > 一致.
|
||
|
||
6. 测试用例API
|
||
----------------------------------------------
|
||
(一) 获取配置文件的配置值
|
||
例子见 testcase/demo/demo-c testcase/demo/demo-sh
|
||
|
||
(1) C语言API: (头文件: #include "mjson.h")
|
||
__________________ __________________
|
||
|struct mjson_value mjson_fetch(const char *keypath); |
|
||
| int mjson_fetch_int(const char *keypath); |
|
||
| int mjson_fetch_boolean(const char *keypath);|
|
||
| double mjson_fetch_double(const char *keypath); |
|
||
| char * mjson_fetch_string(const char *keypath); |
|
||
| char ** mjson_fetch_array(const char *keypath); |
|
||
------------------ ------------------
|
||
(a) 接口: struct mjson_value mjson_fetch(const char *keypath);
|
||
参数: 配置项在配置树上的绝对路径
|
||
返回: 失败则 mjson_value.type = mjson_type_error
|
||
功能: 获取任意类型配置项的值,务必检查mjson_value.type,
|
||
当为mjson_type_error时,此结构体无效,使用会导致段错误
|
||
(b) 接口: int mjson_fetch_int(const char *keypath);
|
||
参数: 配置项在配置树上的绝对路径
|
||
返回: 成功返回相应的值,失败返回-1
|
||
功能: 获取int型配置项的值
|
||
(c) 接口: int mjson_fetch_boolean(const char *keypath);
|
||
参数: 配置项在配置树上的绝对路径
|
||
返回: 成功返回true|false(1|0),失败返回-1
|
||
功能: 获取bool型配置项的值
|
||
(d) 接口: double mjson_fetch_double(const char *keypath);
|
||
参数: 配置项在配置树上的绝对路径
|
||
返回: 成功返回相应的值,失败返回-1
|
||
功能: 获取double型配置项的值
|
||
(e) 接口: char * mjson_fetch_string(const char *keypath);
|
||
参数: 配置项在配置树上的绝对路径
|
||
返回: 成功返回相应的字符串指针,失败返回NULL
|
||
功能: 获取字符串型配置项的值,务必检查返回,否则引发段错误
|
||
指针内存不需要(不能)释放
|
||
(f) 接口: char ** mjson_fetch_array(const char *keypath);
|
||
参数: 配置项在配置树上的绝对路径
|
||
返回: 成功返回相应的二维字符串指针,失败返回NULL
|
||
功能: 获取字符串数组型配置项的值,务必检查返回,否则引发段错误
|
||
第一个字符串为有效字符串个数(不算第一个字符串),
|
||
字符串示例: array={"3", "one", "two", "three"}
|
||
可用atoi(array[0])函数获取有效字符串个数
|
||
指针内存不需要(不能)释放
|
||
|
||
(2) Shell脚本API: (直接使用,无需包含任何文件)
|
||
__________________ __________________
|
||
| mjson_fetch <keypath1> [keypath2 ...] |
|
||
------------------ ------------------
|
||
(a) 例如:
|
||
$ mjson_fetch /demo/demo-c/run_times
|
||
3 <<== 返回
|
||
$ mjson_fetch /demo/demo-sh/command
|
||
demo-sh <<== 返回
|
||
|
||
(二) 获取系统相关信息
|
||
例子见 testcase/demo/demo-c testcase/demo/demo-sh
|
||
|
||
(1) C语言API: (头文件: #include "sysinfo.h")
|
||
__________________ __________________
|
||
| char *get_kernel_version(void); |
|
||
| char *get_target(void); |
|
||
| char *get_platform(void); |
|
||
| char *get_boot_media(void); |
|
||
------------------ ------------------
|
||
(a) 接口: char *get_kernel_version(void);
|
||
功能: 获取内核版本字符串,务必检查返回是否为NULL
|
||
指针内存由测试用例释放
|
||
返回示例: 3.10.65
|
||
(b) 接口: char *get_target(void);
|
||
功能: 获取方案代号,务必检查返回是否为NULL
|
||
指针内存由测试用例释放
|
||
返回示例: azalea-m2ultra
|
||
(c) 接口: char *get_platform(void);
|
||
功能: 获取平台编号,务必检查返回是否为NULL
|
||
指针内存由测试用例释放
|
||
返回示例: R40
|
||
(d) 接口: char *get_boot_media(void);
|
||
功能: 获取引导系统的存储设备,务必检查返回是否为NULL
|
||
指针内存由测试用例释放
|
||
返回: emmc|sdcard|nand|nor-flash
|
||
其中,sdcard代表是卡启动
|
||
|
||
(2) Shell脚本API: (直接使用,无需包含任何文件)
|
||
__________________ __________________
|
||
| get_kernel_version |
|
||
| get_target |
|
||
| get_platform |
|
||
| get_boot_media |
|
||
------------------ ------------------
|
||
(a) 接口: get_kernel_version
|
||
功能: 获取内核版本字符串,务必检查返回是否为NULL
|
||
返回示例: 3.10.65
|
||
(b) 接口: get_target
|
||
功能: 获取方案代号,务必检查返回是否为NULL
|
||
返回示例: azalea-m2ultra
|
||
(c) 接口: get_platform
|
||
功能: 获取平台编号,务必检查返回是否为NULL
|
||
返回示例: R40
|
||
(d) 接口: get_boot_media
|
||
功能: 获取引导系统的存储设备,务必检查返回是否为NULL
|
||
返回: emmc|sdcard|nand|nor-flash
|
||
其中,sdcard代表是卡启动
|