-
总体说明
自动化测试项目 auto-test-icc2 中支持使用 Excel 文件管理测试用例和测试数据,通过代码实现测试逻辑,从而实现高效的自动化测试。
以下是项目的关键特点:
- Excel 驱动测试用例:每个 Excel 文件代表一个测试套件(Case Suite),包含一批测试用例和测试数据。
-
结构化设计:每个 Excel 文件必须遵循以下结构规则:
- 测试用例:只能有一个名为 测试用例 的工作表,用于存放具体的测试步骤和验证逻辑。
- 测试数据:可以包含多个测试数据工作表,名称可以自定义,但不能命名为 **测试用例**。
-
测试用例结构
在自动化测试项目auto-test-icc2 中,tests 目录是存放所有测试相关文件的核心目录。为了保持项目结构的清晰和可维护性,按照一定的规范来组织 tests 目录及其子目录的内容。目录excelcases下存放excel测试用例
以下是分层结构和命名规范的详细说明:
tests/
├── excelcases/ # Excel 驱动的测试用例
│ ├── administrator/ # 管理员相关的测试用例
│ │ ├── test_admin_dz_tenant.xlsx # 租户管理相关测试用例
│ │ └── test_admin_dz_employee.xlsx # 员工管理相关测试用例
│ ├── CTI/ # CTI 相关的测试用例
│ │ ├── test_XXX_resource.xlsx # 资源管理相关测试用例
│ │ └── test_XXX_management.xlsx # 管理相关测试用例
│ └── ... # 其他子系统测试用例
├── pytestcases/ # Pytest 测试用例
│ ├── administrator/ # 管理员相关的测试用例
│ │ ├── test_service_admin.py # 管理服务相关测试用例
│ │ └── test_service_risk.py # 风险服务相关测试用例
│ ├── CTI/ # CTI 相关的测试用例
│ │ ├── test_service_control.py # 控制服务相关测试用例
│ │ └── test_service_management.py # 管理服务相关测试用例
│ └── ... # 其他子系统测试用例
└── test_*.py # 单独的测试文件,可选
-
Excel文件结构
-
Excel文件结构
-
子目录命名
按子系统或模块划分:子目录的命名应反映测试用例所属的子系统或模块。例如:
- Administrator:管理员相关功能。
- CTI:CTI(呼叫中心)相关功能。
- OAH:OAH相关功能。
说明:
- 命名应尽量简洁、清晰,避免冗长。
- 在同一个子目录下可以有多个Excel
-
Excel 文件命名
格式:test_<功能模块>_<测试场景>.xlsx
<功能模块>:测试用例所属的功能模块或子系统。
<测试场景>:具体的测试场景或功能点。
示例:
test_admin_dz_tenant_media.xlsx:管理员 - 得助-租户-媒体管理相关测试用例。
test_admin_dz_employee_management.xlsx:管理员 - 得助-员工-管理相关测试用例。
test_oah_api_tenant_edit.xlsx:OAH - 租户api-编辑相关测试用例。
-
测试用例编写
-
测试用例编写
-
字段定义
|
1
|
字段名
|
含义
|
说明
|
|---|---|---|---|
|
2
|
用例唯一标识
|
可以从灵风系统用例编号,同一用例的多个步骤共用同一个 ID,仅第一步填写
|
|
|
3
|
LFCaseID
|
灵风系统用例编号
|
用于与灵风系统中的用例进行关联,确保唯一性。 如果没有, 可不填
|
|
4
|
ScenarioDescription
|
场景描述
|
描述测试用例的业务场景或功能点,便于理解用例目的
|
|
5
|
步骤序号
|
用于控制执行顺序
|
|
|
6
|
Description
|
步骤描述
|
描述当前步骤的具体操作或验证内容
|
|
7
|
|
如 api、ui、kafka、db、linux 等,或者业务层模块oahapi,seatUI,可从 测试数据表覆盖
|
|
|
5
|
操作名称
|
模块中执行的操作(如 send_request、click、query)
|
|
|
9
|
标签
|
仅在第一步填写,用于筛选执行(如 SmokeTest, RegressionTest)
|
|
|
10
|
参数集标识
|
对应测试数据表中的参数组集合
|
|
|
11
|
参数
|
如果Action只有一个参数,可以直接配置在Params中。和ParamsSetID 二选一
|
|
|
12
|
Priority
|
优先级
|
用于标识测试用例的重要程度,如 P0、P1、P2 等
|
-
例子
测试用例表,文件名可自定义。
示例表名为TestCase:
|
1
|
TestCaseID
|
LFCaseID
|
ScenarioDescription
|
Step
|
Description
|
Module
|
Action
|
Tag
|
Params
|
ParamsSetID
|
Priority
|
|---|---|---|---|---|---|---|---|---|---|---|---|
|
2
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
API_编辑租户基础配置
|
1
|
设置变量
|
data_process
|
data_process
|
regression, api,oah
|
|
oah_body
|
p1
|
|
3
|
|
|
|
2
|
get sign
|
oah_api
|
generate_sign
|
|
|
oah_sign
|
|
|
4
|
|
|
|
3
|
basicConfig edit
|
oah_api
|
send_request
|
|
|
oah_request
|
p1
|
|
5
|
|
|
|
4
|
validate 200
|
value_validation
|
validate_data
|
|
{ "field_name": "status_code", "actual_value": "@response.json:data.code", "operator": "equal", "expect_value": "200" }
|
|
|
|
6
|
|
|
|
5
|
validate msg
|
value_validation
|
validate_data
|
|
{ "field_name": "msg", "actual_value": "@response.json:data.msg", "operator": "equal", "expect_value": "操作成功" }
|
|
|
🔸说明:
- TestCaseID 与 Tag 仅在第一个 Step 填写:每个测试用例的
TestCaseID和Tag只在第一个步骤中填写,后续步骤不需要重复填写。 - Module、Action 将由框架提供,需要使用框架使用手册中提供的模块和功能
- 若测试数据表中定义了 Module、Action,则覆盖测试用例表中对应字段。(后续补充例子)
- 不同 Step 使用不同的 ParamsSetID,以便更好地管理和区分不同的参数集。
- 不同测试用例的
TestCaseID不同,不同参数的的ParamsSetID 不同。
-
测试数据编写
-
测试数据编写
-
字段定义
|
1
|
2
|
参数集标识
|
与测试用例表中的ParamsSetID 对应
|
|
|
3
|
参数编号
|
用于区分同组参数
|
||
|
4
|
参数名
|
例如 body、url、params
|
||
|
5
|
参数值
|
可支持动态变量、上下文变量引用
|
||
|
6
|
数据分组
|
用于多组数据驱动
|
||
|
7
|
关联的测试用例ID
|
用于跨表映射
|
说明:
• TestCaseID 与 测试用例中的ID对应
• 如果调用框架提供的方法,参数名请正确使用框架提供的参数名
• DataGroup 相同表示同一组测试数据
• ParamID 如果为M1,表示该参数是一个模块名, 将于yml 文件中的模块名对应。如果为A1,表示该参数是一个方法名,将使用框架提供的模块中实现的方法。如果为PX,表示该参数是模块中提供的方法需要的参数。
• ParamsSetID 相同的参数是测试数据中同一个step的参数
-
例子
测试用例表,文件名可自定义。
case1 示例(有 2 组 DataGroup,即同一个测试用例有两组测试数据)
|
oah_body
|
P1
|
params
|
{ "operation": "set_variable", "params": { "tenantId": "TE17831554453625869", "explicitIvrStatus": "false", "explicitIvrMode": 1, "encryptionType": 3, "secretKey": "123456", "cipherPrefix": "enc1_", "initializationVector": "789123" }, "saveAsVariable": "body" }
|
1
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_sign
|
P1
|
body
|
@body.string:value
|
1
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_sign
|
P2
|
saveAsVariable
|
sign
|
1
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_request
|
P1
|
API
|
/au/api/ops/oah/tenant/info/basicConfig/edit
|
1
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_request
|
P2
|
method
|
POST
|
1
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_request
|
P3
|
body
|
@body.string:value
|
1
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_request
|
P4
|
header
|
{ "Content-Type": "application/json", "oah-app-id": "DZ-Tr9ilnE8", "oah-sign": "@sign.string:value", "oah-sign-type": "ASK", "oah-timestamp": "1761113092294" }
|
1
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_request
|
P5
|
saveAsVariable
|
response
|
1
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_body
|
P1
|
params
|
{ "operation": "set_variable", "params": { "tenantId": "TE14327467543869", "explicitIvrStatus": "false", "explicitIvrMode": 1, "encryptionType": 3, "secretKey": "43246", "cipherPrefix": "enc1_", "initializationVector": "43255" }, "saveAsVariable": "body" }
|
2
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_sign
|
P1
|
body
|
@body.string:value
|
2
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_sign
|
P2
|
saveAsVariable
|
sign
|
2
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_request
|
P1
|
API
|
/au/api/ops/oah/tenant/info/basicConfig/edit
|
2
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_request
|
P2
|
method
|
POST
|
2
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_request
|
P3
|
body
|
@body.string:value
|
2
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_request
|
P4
|
header
|
{ "Content-Type": "application/json", "oah-app-id": "fsafdjksf", "oah-sign": "@sign.string:value", "oah-sign-type": "ASK", "oah-timestamp": "43244" }
|
2
|
TC_OAH_API_Tenant_Base_Config_Edit
|
|
oah_request
|
P5
|
saveAsVariable
|
response
|
2
|
TC_OAH_API_Tenant_Base_Config_Edit
|
浙公网安备 33010602011771号