禅道开发的数据制造

为什么开发ZenData

摘要:DevOps时代下面对自动化测试的要求越来越高,但如何能够将自动化测试规模化、工程化是每一个团队都会面临的巨大挑战。在这个挑战中,测试数据的生成、维护、解析又是重中之重。

一、时代背景

最近几年DevOps概念越来越火,各种DevOps平台也如雨后春笋一样涌现。但大家往往把重点放在在工具链的搭建上,而忽略软件研发最重要的本质。工具链搭建是容易的,有各种的开源软件可以满足需求。但工具链搭建起来之后应该怎么应用呢?DevOps是希望可以通过持续集成和持续交付来实现快速的响应,但这里面有一个前提,就是质量必须要保障。如果没有质量,持续集成和交付都是空谈。如何保证质量呢?就必须要上自动化测试。

二、存在问题

自动化测试无论单元测试、接口测试、功能测试都会面临一个挑战,即如何能够做到大规模、工程化的自动化测试。这里面会牵扯到很多方面的技术:测试环境、测试手段、测试资源、测试管理等等,但这里面最最重要的一环是测试数据的管理。

如果测试数据无法做到灵活、大规模的管理,那么自动化测试就始终无法做到规模化,无法起到快速验证、快速集成、快速交付的目的。

三、目前解决方案

目前测试数据是如何来维护的呢?绝大部分的团队还是停留在手工维护阶段。手工造数据,手工维护,成本之高,可想而知。个别有能力的测试人员,会自己写点脚本来生成数据。个别有开发资源的大厂,则自己组建团队来做专门的数据工厂。这些方案都不具备通用性,成本也极其高昂。

四、为什么来开发ZenData

业内研究理论方法的专家老师有很多,但提供落地工具的不多。我们经过讨论之后,觉得来开发一款所有人都可以使用的通用的测试数据生成工具,于是就有了ZenData这样一款测试数据生成工具。

ZenData则通过YAML文件,定义了一种简单的数据类型描述语法。使用者不需要对技术有过多了解,通过定义简单的字段取值列表、前缀后缀等配置,即可实现测试数据维护的目的。简洁、高效、灵活,是做单元测试、接口测试、功能自动化测试、性能测试、压力测试、打桩mock的有力帮手。

ZenData通过简单的range定义实现了区间、步长、随机、引用、重复、SQL查询等方式,通过简单的规则可应对各种变化。ZenData只有一个可执行文件,支持HTTP模式,还可以对数据进行反向解析,可以输出txt、json、xml、sql等多种格式。

ZenData数据生成工具简介

摘要:ZenData使用YAML来作为数据类型配置文件实现了数据的生成和解析。ZenData可以用于手工测试场景下面测试数据的准备,也可以用于自动化测试脚本里面的数据生成和解析。还可以一键生成海量数据用于性能和压力测试。

一、ZenData的实现原理

ZenData使用YAML来作为数据类型配置文件。对于每一种类型的数据来讲,我们都可以将其拆分成若干的字段。比如我们要测试一个用户的订单表,会有订单的id,用户id或者账户名,订单的名称,订单的金额,订单的时间,订单状态等等字段。我们可以针对每一个字段配置其取值的范围。比如订单id,我可以定义为从1到10000,用户id可以是1-100。这样每一个字段都有了一个取值范围列表。当ZenData来生成数据的时候,从每一个字段里面依次取一个值,将其拼接在一起,就形成了一条记录。大家可以想象成每个字段都是一个转盘,按照自己的频率进行旋转,每一次旋转都从中取出一个值,和其他的字段进行组合。

上面说的是最基本的的工作原理,ZenData还提供了步长、随机、循环、引用等多种定义方式,我们会在接下来的手册里面展开讲。

二、ZenData的用途

ZenData主要两大功能:数据生成和数据解析。通过一个配置文件,可以使用ZenData生成您想要的各种数据。同样也可以对某一个数据文件,指定其数据类型定义的配置文件,完成到结构化数据的解析。

ZenData可以用于手工测试场景下面测试数据的准备,也可以用于自动化测试脚本里面的数据生成和解析。还可以一键生成海量数据用于性能和压力测试。

三、ZenData主要的特点

  1. 简单无依赖,只有一个可执行文件,即可满足命令行生成和HTTP接口两种数据生成服务。
  2. 使用配置文件来生成数据,使用人员不需要有开发知识,即可上手应用。
  3. 提供了功能强大的语法,分组、区间、步长、循环、随机、格式化和前后缀等,配置灵活性极强。
  4. 支持从文本文件中读取数据,方便用户对字段取值进行精确控制。
  5. 提供了Excel表格数据的标准SQL查询接口,使用更加灵活。
  6. 使用预制的序列(ranges)、实例(instances)、配置(config)对定义进行复用,以解决复杂数据格式的定义。
  7. 语法支持继承和扩展,为定义文件间的复用提供方便。
  8. 可以反向解析数据,可以对程序的输出进行解析,方便自动化测试脚本进行比对。
  9. 发行包內置了基础业务数据的定义文件(不断完善中)。
  10. 提供了HTTP接口数据生成服务,各种语言都可以方便调用。

如何获得支持

一、关于开源软件技术支持的误读

国内很多朋友认为开源软件的作者理所应当提供免费的技术支持,其实这是一种误解。

开源软件大家可以免费使用,彼此并没有形成购买行为,所以开源软件都会声明没有技术支持的义务。

我们会尽我们所能为大家提供即时的支持,只要你的提问清楚,耐心有礼貌的提问,我们都会尽力帮大家解决问题。

我们也呼吁国内开源软件的用户对开源软件的作者多一些支持,这样才能形成互惠互利的开源环境。

二、提问请不要:

1. 请不要带主观色彩。比如:太难用了,太麻烦了,强烈建议,很急之类的词语。

2. 请不要重复提问。比如你在我们网站问答提问,就不要在QQ群提问。反之亦然。

3. 请不要说无关的话。比如有人在吗?我是小白,我是菜鸟之类的话。有问题直接描述即可。

三、提问请一定:

1. 请一定要看文档:绝大部分的问题都可以在文档中找到。

2. 请一定要上截图:不要自己推测问题,请一定要上截图。

3. 请一定要找到日志:zentao/tmp/log/下面找到php开头的新日志。

4. 问题解决之后请一定给我们一个回馈,以帮助我们积累经验。

5. 如果你有时间, 给我们的技术支持人员一句谢谢 ,我们也会很开心的回应:不客气。

 

快速入门

安装部署

一、Windows下载安装ZenData

  1. https://zd.im/download.html下载ZenData最新版文件;
  2. 解压后进入相应目录,如c:\zd;
  3. 执行zd.exe -h获取使用帮助;
  4. 执行zd.exe -e获取命令示例;
  5. 首次执行时,请根据提示选择工具的语言;
  6. 根据提示执行setx Path命令,将zd.exe加入$PATH环境变量,以便于在任意目录中执行。

二、Linux下面下载安装ZenData

  1. https://zd.im/download.html下载ZenData最新版文件;
  2. 解压后进入相应目录,比如~/zd
  3. 执行./zd -h获取使用帮助;
  4. 执行./zd -e获取命令示例;
  5. 首次执行时,请根据提示选择工具的语言;
  6. ZenData将自动将zd命令加入用户环境变量$PATH,以支持在任意目录中执行。

将ZenData加入$PATH系统环境变量中

一、Windows系统

1. 在命令行输入sysdm.cpl,打开系统属性窗口;
2. 依次点击"高级"标签、"环境变量"按钮,打开环境变量编辑窗口;
3. 在上部"用户变量"列表中,点击"编辑"按钮修改Path变量;若无Path变量,则点击"新建"按钮;

4. 填入或追加zd.exe文件所在的目录绝对路径,Win7中为单行编辑模式,路径间用英文分号隔开;

5. 重新打开命令行窗口,使设置生效。

二、Linux或Mac系统

1. 编辑用户目录下的.bash_profile文件;

2. 在文件末尾添加export PATH=$PATH:<zendata文件所在目录绝对路径>;

3. 执行source ~/.bash_profile使设置生效。

命令行参数说明

以下是ZenData命令行参数的说明:

数据生成相关

  -d  --default    默认的数据格式配置文件。
  -c  --config     当前场景的数据格式配置文件,可以覆盖默认文件里面的设置。
  -o  --output     生成的数据的文件名。可通过扩展名指定输出json|xml|sql|csv|xlsx格式的数据。默认输出原始格式的文本数据。
  -n  --lines      要生成的记录条数,默认为10条。
  -F  --field      可通过该参数指定要输出的字段列表,用逗号分隔。 默认是所有的字段。
  -t  --table      输出格式为sql时,需通过该参数指定要插入数据的表名。
      --dns        指定数据源连接字符串,结合表名使用,可直接插入数据到MySQL数据库表。
      --clear      插入数据前,删除已有数据。
  -T  --trim       输出的字段去除前后缀,通常用在生成SQL格式输出和数据反向解析命令中。
  -H  --human      输出可读格式,打印字段名,并使用tab键进行分割。
  -r  --recursive  递归模式。如不指定,默认为平行模式。平行模式下各个字段独立循环。
                   递归模式下每个字段的取值依赖于前一字段。可增强数据的随机性。
  -R  --root       指定数据生成命令的执行目录,默认为当前目录。

內置数据查看

  -l  --list       列出当前目录下所有的用户数据定义。
  -L               列出ZenData安装目录下所有数据定义。
  -v  --view       查看当前目录下某个用户数据定义的详细信息。
  -V               查看ZenData安装目录下某个数据定义的详细信息。

从SQL生成数据

-i  --input      指定一个数据库Schema或文章文本文件,解析生成yaml配置文件。需通过-o参数指定一个输出的目录。

-D  --decode     根据指定的配置文件,将通过-i参数指定的数据文件解析成json格式。 

HTTP服务相关

  -p  --port       在指定端口上启动Web服务。可通过页面管理测试数据、通过接口请求JSON格式的数据。服务模式下接口只支持数据生成。
  -b  --bind       监听的ip地址,默认监听所有的ip地址。
  -R  --root       运行HTTP服务时根目录。客户端可调用该根目录下面的配置文件。如果不指定,取zd可执行文件所在目录。

帮助相关

  -h  --help       打印帮助。
  -e  --example    打印数据定义文件示例。

命令行调用示例

以下是ZenData命令的一些示例:

数据生成

$>zd.exe -d demo\default.yaml         # 根据-d参数指定的配置文件生成10条记录。
$>zd.exe -c demo\default.yaml         # 根据-c参数指定的配置文件生成10条记录。
$>zd.exe -c demo\default.yaml -r      # 根据-c参数指定的配置文件,采用递归的方式生成10条记录。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100               # -c和-d两个文件的配置合并,输出100条记录。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -o test.txt   # 输出原始格式的数据。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -o test.json  # 输出json格式的数据。
$>zd.exe -d demo\default.yaml -c demo\test.yaml -n 100 -o test.xml   # 输出xml格式的数据。
$>zd.exe -d demo\default.yaml -n 100 -o test.sql -t user             # 输出针对user表的insert语句。

$>zd.exe -d demo\default.yaml -n 100 -o test.sql -t user --trim      # 输出针对user表的insert语句,去掉前后缀。

$>zd.exe -c test\test-sql.yaml -t zendata.table_a --trim -dns mysql://root:P2ssw0rd@127.0.0.1:3306/zendata#utf8 --clear # 插入数据到MySQL数据源。

內置数据查看

$>zd.exe -l                                                          # 列出所有內置数据。
$>zd.exe -v system.address.v1                                        # 查看內置Excel文件system/address/v1.xlsx中的数据表。
$>zd.exe -v system.address.v1.china                                  # 查看內置Excel文件china数据表中的数据。
$>zd.exe -v system.ip.v1.yaml                                        # 查看內置IP地址的Instances数据。

从SQL生成YAML数据定义

$>zd.exe -i demo\zentao.sql -o db                                    # 根据SQL生成各表的yaml定义文件,存储到db目录里面。

从文章生成YAML数据定义

$>zd.exe -i demo\article.txt  -o demo                                # 转换文章为yaml配置,输出到demo目录下。

数据反向解析

$>zd.exe -c demo\default.yaml -i test.txt --decode                   # 将-i指定的文件根据-d参数的配置进行解析。

HTTP服务

启动服务:
$zd.exe -p 80                   # 监听80端口,以zd.exe文件所在目录为根目录。
$zd.exe -p 80 -R d:\zd\def      # 监听80端口,以d:\zd\def为根目录。
客户端调用:
$curl http://loclahost/?d=default.yaml&c=config.yaml&n=100&o=test.sql&t=user  # 通过GET方式指定服务器端配置文件。
$curl http://loclahost/?default=default.yaml&output=test.sql&table=user       # 参数名可以用全拼。
$curl -d "default=...&config=...&lines=10" http://localhost/                  # 可以通过POST方式上传配置。

內置数据定义示例

随着ZenData发行文件,我们打包了如下的內置数据定义。执行ZenData命令时,软件会从用户当前目录和ZenData部署目录寻找数据定义和资源。

  • data目录:  存放Excel格式的基础数据,如国家、地区、人名和中文词语等。
  • yaml目录:  系统内置的一些数据定义,如账号、域名、邮箱、日期和文章等。
  • users 目录: 用于存放用户自己定义的一些数据。
  • demo 目录:   一些演示的例子。

YAML定义语法总览

以下为一个标准的YAML定义文件,各元素含义请见注释。更多详细说明,请参见本手册后续章节。

title: zendata数据配置语法说明
desc:
# 文件组成
# zendata以yaml格式的文件来定义各个字段的格式。
# yaml文件整体由文件说明和字段定义两部分组成。
# 文件说明
# title:   标题,可以用简短的文字概要描述该文件定义的数据类型。
# desc:    描述,可以用多行文本来详细描述该文件定义的数据类型,非必选项。
# author:  作者,非必选项。
# version:版本号,非必选项。
# 字段列表
# 字段定义部分都放在fields这个定义里面。
# 一个yaml文件可以包含一个或者多个字段。
# 字段列表以-field定义开始。
# 一个字段可以通过fields属性定义它的子字段。 
# 字段定义 
# field:    字段名,仅支持英文、数字、下换线和.
# range:    列表范围,最重要的定义。
# loop:     循环次数,可以定义某一字段循环多少次。
# loopfix:  每一次循环时的连接符。
# format:    支持格式化输出。
# prefix:   该字段的前缀。
# postfix:  该字段的后缀。
# length:   该字段的长度。如果不通过分隔符区分,则需要指定字段长度,单位是字节。
# leftpad:  左填充的字符。如果长度不够,可指定左填充的字符。默认是以空格左填充。
# rightpad: 右填充的字符。如果长度不够,可指定右填充的字符。
# config:    可以引用另外一个文件里面的定义。
# from:     引用某一个定义文件。
# use:      使用被引用文件中定义的若干实例。all代表使用所有。
# select:   如果引用的文件是excel表,可以查询里面的某一个字段。
# where:     如果引用的文件是excel表,可以使用查询条件。
# loop定义
# 可以使用一个数字来指定字段循环的次数,比如loop:2。
# 可以使用区间来定义字段循环的次数。比如loop:2-10。
# range定义
# 使用逗号连接不同的元素。比如 range: 1,2,3。
# 元素也可以是一个区间。比如 range:1-10, A-Z。
# 区间可以通过冒号:来指定步长。比如 range:1-10:2。
# 步长可以是小数。比如 range: 1-10:0.1。
# 步长可以是负数。比如 range:100-1:-1。
# 区间可以通过R来指定随机。比如 range: 1-10:R,随机和步长只能二选一。
# 可以通过一个文件来指定列表。比如range: list.txt。文件名是相对路径时,以配置文件为基准计算。
# 可以通过{n}的方式来重复某一个元素。比如 range: user1{100},user2{100}
# 如果区间或者几个元素需要重复,需要用[]括起来。比如 range: [user1,user2,user3]{100}
author: zentao
version: 1.0
fields:
  - field: field_common                 # 默认的列表类型,通过逗号隔成若干区间。
    range: 1-10, 20-25, 27, 29, 30      # 1,2,3...,10,20,21,22...,25,27,29.30
    prefix: ""                          # 前缀
    postfix: "\t"                       # 后缀,特殊字符加引号,否则无法解析。
  - field: field_step                   # 区间指定步长。
    range: 1-10:2, 1-2:0.1              # 1,3,5,7,9,1, 1.1,1.2...,2
    postfix: "\t"
  - field: field_random                 # 区间指定随机。随机属性R同步长不能同时出现。
    range: 1-10:R                       # 1,5,8...
    postfix: "\t"
  - field: field_loop                   # 自循环的字段。
    range: a-z                          # a|b|c ...
    loop: 3                             # 循环三次
    loopfix: _                          # 每次循环的连接符。
    postfix: "\t"
  - field: field_repeat                 # 通过{}定义重复的元素。
    range: user-1{3},[user2,user3]{2}   # user-1,user-1,user-1,user2,user2,user3,user3
    postfix: "\t"
  - field: field_format                 # 通过格式化字符串输出。
    range: 1-10                         # passwd 1,passwd 2,passwd 3 ... passwd10。
    format: "passwd%02d"                # 用%02d补零,使密码整体保持8位。
    postfix: "\t"
  - field: field_length                 # 指定宽度。
    range: 1-99                         # 01\t,02\t,03\t..., 99\t
    length: 3                           # 包含前后缀的宽度。
    leftpad: 0                          # 宽度不够时,补充的字符。
    postfix: "\t"
  - field: field_text                   # 从一个文件中随机读取。
    range: users.txt:R                  # 相对当前文件路径。
    postfix: "\t"
  - field: field_yaml                   # 引用其他的定义文件整体内容。
    range: test/test-nested2.yaml{3}    # 相对当前文件路径。
    postfix: "\t"
  - field: field_use_config             # 引用其他的config定义文件。
    config: number.yaml                 # 相对当前文件路径,config内包含单个字段。
    postfix: "\t"
  - field: field_use_ranges             # 引用內置的定义文件,该文件定义了多个range,他们共享了一些field层面的属性。
    from: zentao.number.v1.yaml         # 引用yaml/zentao/number/v1.yaml文件里面的ranges定义。
    use: medium                         # 使用该文件中定义的medium分组。
    postfix: "\t"
  - field: field_use_instance           # 引用其他的定义文件,该文件定义了多个实例。
    from: ip.v1.yaml                    # yaml/ip/v1.yaml
    use: privateC,privateB              # 使用该文件中定义的privateC和privateB两个实例。
    postfix: "\t"
  - field: field_use_excel              # 从excel数据源里面取数据。
    from: address.cn.v1.china           # 从data/address/v1.xlsx文件中读取名为china的工作簿。
    select: city                        # 查询city字段。
    where: state like '%山东%'           # 条件是省份包含山东。
    rand: true                          # 随机取数据
    postfix: "\t"
  - field: field_with_children          # 字段多层嵌套
    fields:
      - field: child1
        range: a-z
        prefix: part1_
        postfix: '|'
      - field:  child2
        range: A-Z
        prefix: part2_
        postfix: '|'
      - field: child_with_child
        prefix: part3_
        postfix:
        fields:
          - field: field_grandson
            prefix: int_
            range: 10-20
            postfix:
posted on 2022-09-26 17:10  胖妞的瘦猴  阅读(107)  评论(0编辑  收藏  举报