...

关于TDL测试描述语言的设计草稿

TDL(Tests Description Language )
基于JSON的测试描述语言, 用于描述测试用例、测试套件、测试报告等相关实体及属性

设计初衷

  • 为不同的程序语言(Python、Java、Golang等)提供一种通用的测试用例等对象的序列化参考格式
  • 为基于文件系统的测试框架(Test Framework)到基于关系型数据库的测试平台(Test Platform)提供一种标准的中间格式
  • 相对于Robot Framework及BDD的格式,使用更通用JSON格式,易于序列化和反序列化及平台支持和实现跨编程语言

参考格式

  • Root Framework
  • Httprunner
  • Jenkins pipline
  • BDD (Behave、Cucumber )
  • QTAF (腾讯开源测试框架)

测试用例描述

  • name: 用例名称(string格式)- 必填
  • description: 用例描述(string格式)
  • priority: 优先级(integer格式)
  • tags: 用例标签列表(array格式)
  • timeout: 超时时间,单位秒(interger / float格式)
  • setups:测试准备操作(array of object格式)
  • teardowns: 测试清理操作(array of object格式)
  • steps: 测试步骤(array of object 格式)
  • _id: 用例唯一ID(隐藏属性,计算生成)
  • _path: 用例文件路径(可以单独一个文件)

对于基于关系行数据库的,_id字段也可以是一个数字(字符串形式),对于基于Mongodb等的,_id也可以时一个uuid,对于测试框架,_id可以是一个包.模块.方法的路径

测试步骤描述

  • method: 引用的操作关键字,格式为 库.方法
  • args: 支持number, string, array和object格式,object格式按关键字参数形式传给对应method,其他按位置参数形式传递(array拆成多个参数传递)
  • store: 存储变量到上下文中(object格式)
  • excepted: 步骤期望结果(array or object格式)

示例

示例1-接口自动化测试

{
  "name": "test_api_demo",
  "description": "test description",
  "priority": 1,
  "tags": ["http", "api-test"],
  "timeout": 100,
  "setups": [
    {"method": "Http.Get", "args": {"url": "/get","params":  {"a": 1, "b": 2, "c": 3}}}
  ],
  "teardowns": [
     {"method": "Http.Get", "args": {"url": "/get","params":  {"a": 1, "b": 2, "c": 3}}}
  ],
  "steps": [
    {"method": "Http.Get", "args": {"url": "/get","params":  {"a": 1, "b": 2, "c": 3}}},
    {"method": "Http.Post", "args": {"url": "/post", "json":  {"name": "Kevin"}}},
    {"method": "Http.Get", "args": {"url": "/get", "params":  {"a": 1, "b": 2, "c": 3}}, 
      "store": {"url": "$.url"}, "excepted": [{"AssertEqual": ["$url", "/get"]}]
  ]
}

示例2-UI自动化测试

{
  "name": "test_web_ui_demo",
  "description": "test description",
  "steps": [
    {"method": "Page.Open", "args": ["https://www.baidu.com/"]},
    {"method": "Page.InputTo", "args": ["id","kw", "helloworld"], "store": {"value1": "//[@id=\"kw\"]/@value"}},
    {"method": "Page.Click", "args": ["id","su"]}
  ]
}

示例3-SSH操作

{
  "name": "test_ssh_demo",
  "description": "test description",
  "steps": [
    {"method": "SSH.Execute", "args": "echo hello"},
    {"method": "SSH.GET", "args": ["/path/a.txt", "/local_path/a.txt"]}
  ]
}

示例4-MySQL操作

{
  "name": "test_mysql_demo",
  "description": "test description",
  "steps": [
    {"method": "MySQL.Query", "args": "SELECT * FROM `users`"},
    {"method": "MySQL.Execute", "args": "INSERT INTO `users` (\"name\") VALUES(\"KEVIN\")"}
  ]
}

测试套件描述

  • name: 测试套件名称(string格式)- 必填
  • description:测试套件描述(string格式)
  • priority: 套件下用例默认优先级(integer格式)
  • tags: 套件下用例默认标签列表(array格式)
  • timeout: 套件下用用例默认超时时间,单位秒(interger / float格式)
  • setups:套件下用例默认测试准备操作-每个用例执行(array of object格式)
  • teardowns: 套件下用例默认测试清理操作-每个用例执行一次(array of object格式)
  • setups-suite:套件级测试准备操作(array of object格式)
  • teardowns-suite: 套件级测试清理操作(array of object格式)
  • tests: 测试用例列表,可以通过id引用,也可以直接描述完整的测试用例 (array of object格式)
  • filter: 过滤器(object格式)
  • _id: 套件唯一ID(隐藏属性,计算生成)
  • _path: 套件文件路径

测试套件的两种形式

  • 基于编写的
  • 基于筛选或导入的

示例数据1-基于编写的

{
  "name": "testsuite_01",
  "description": "testsuite description",
  "tags": ["ui-test"],
  "priority": 1,
  "tests": [
    {
	  "name": "test_web_ui_demo",
	  "description": "test description",
	  "steps": [
		{"method": "Page.Open", "args": ["https://www.baidu.com/"]},
		{"method": "Page.InputTo", "args": ["id","kw", "helloworld"], "store": {"value1": "//[@id=\"kw\"]/@value"}},
		{"method": "Page.Click", "args": ["id","su"]}
	  ]
	}
  ]
}

示例数据2-导入目录及过滤

{
  "name": "testsuite_01",
  "tests": [{"path": "./testcases"}],
  "filter": {
    "priorities": [],
    "status": [],
    "owner": [],
    "include_tags": [],
    "exclude_tags": [],
    "exclude_names": []
  },
}

示例数据3-逐个导入(用例列表)

{
  "name": "testsuite_01",
  "tests": [
      {"path": "./testcases/function/test_a.json"},
      {"path": "./testcases/function/test_c.json[A]"},
      {"path": "./testcases/function/test_b.json[A,B,C]"},
    ],
}

一个.json可能包含多个用例(测试套件),可以通过[]来筛选要导入的具体用例,不指定时导入套件所有用例

套件嵌套 # todo

示例数据3-基于ID导入

{
  "name": "testsuite_01",
  "tests": [
      {"id": "testcases.function.test_a"},
      {"id": "testcases.function.test_c.A"},
      {"id": "testcases/=.function/test_b"}
    ],
}

基于编写的用例,套件中可以为下面的用例制定默认的priority、timeout、tags等属性,及setup、teardown方法
关于默认属性和属性优先级

对与基于编写的测试套件和测试用例都提供了priority、timeout、tags、setup、teardown等属性,优先级规则如下:

  • priority、timeout:套件有-用例也有时,用例覆盖套件属性设置
  • tags:套件有-用例有时,融合所有的标签
  • setup、teardown:套件有-用例有事,融合操作,setup方法套件默认设置先执行,teardown套件默认设置后执行

测试报告描述

  • title: 测试报告标题(string格式)- 必填
  • description: 测试报告描述(string格式)
  • summary:报告该要信息(object格式)
  • details: 用例详细执行信息(array格式)
  • _id: 报告唯一ID(隐藏属性,计算生成)
  • _path: 报告文件路径

示例格式-待完善

{
  "title": "test_report",
  "summary": {
    "start_at": "2015-02-03 12:00:00.000",
    "end_at": "2015-02-03 12:01:00.00",
    "total": 12
  },
  "details": [
    {}
  ]
  
}

qtaf json report格式

{
  "version": "1.0",
  "summary": {
    "tool": "QTA",
    "title": "\u8c03\u8bd5\u6d4b\u8bd5",
    "environment": {
      "hostname": "SUPERHINHAN-MB1",
      "os": "posix.uname_result(sysname='Darwin', nodename='SUPERHINHAN-MB1', release='22.4.0', version='Darwin Kernel Version 22.4.0: Mon Mar  6 21:00:17 PST 2023; root:xnu-8796.101.5~3/RELEASE_X86_64', machine='x86_64')",
      "qtaf_version": "v5.6.3",
      "python_version": "3.9.6[darwin]"
    },
    "start_time": "2023-07-13 18:35:22",
    "testcase_total_run": 1,
    "testcase_total_count": 1,
    "testcase_passed": 1,
    "succeed": true,
    "end_time": "2023-07-13 18:35:22"
  },
  "logs": [],
  "filtered_tests": [],
  "load_errors": [],
  "passed_tests": {
    "TestA": {
      "description": "\u6d4b\u8bd5\u7528\u4f8b\u63cf\u8ff0",
      "owner": "superhin",
      "priority": "High",
      "status": "Ready",
      "timeout": 10,
      "failed_info": "",
      "start_time": "2023-07-13 18:35:22",
      "end_time": "2023-07-13 18:35:22",
      "records": [
        "TestA_20230713_183522394.json"
      ]
    }
  },
  "failed_tests": {}

关于代码实现

  • 关键字名称规范:大驼峰命名法(兼容Golang的Public函数)

内置关键字方法

  • Print
  • Log

内置断言方法

  • AssertEqual
  • AssertTrue
  • AssertFalse
  • AssertNone
  • AssertNotNone

关于关键字库的实现

基于Python的实现示例

import tdl  # todo 
import requests

@tdl.library
class Http:
    def Get(url, **kwargs):
        pass

基于Java的实现示例

基于Golang的实现示例

关于自定义描述关键字

例如我们想使用verify代替excepted,用register代替store,用testcases代替tests

export TDL_KEY_EXCEPTED=verify
export TDL_KEY_STORE=register
export TDL_KEY_TESTS=testcases

待解决问题

参考

posted @ 2023-06-18 00:31  韩志超  阅读(156)  评论(0编辑  收藏  举报