性能测试案例

安装示例被测系统

请大家点击此处链接,边看 讲解视频,边学习后面的内容

要讲解 性能测试,需要一个 示例 被测系统

我们使用 白月SMS2系统 作为被测系统。

该系统要进行性能测试,正式安装的环境是 CentOS7。

VIP 学员 请联系 老师,获取 该系统安装好的虚拟机 CentOS镜像,根据教程安装启动被测系统。


非VIP学员 可以使用 Windows版本(注意:Windows版本的性能不够,进行性能测试时,会有大量超时错误)

Windows版本,点击百度网盘链接 ,下载 白月SMS2系统 压缩包 bysms2.zip

下载解压bysms2.zip后,进入bysms2目录,双击运行 runserver.bat 即可启动 白月SMS2 系统。


要通过API接口对服务系统进行性能测试,必须要了解系统的接口。

点击这里,下载 该系统的 API接口文档

请先仔细学习接口文档。

然后,观看上面链接视频里面对 该系统的 功能介绍

性能测试概述

请大家点击此处链接,边看 讲解视频,边学习后面的内容

性能测试通常比较复杂,要真正做好很不容易。

需要有产品视野,明白真实场景下,用户是怎样使用产品的,这样才能知道哪些场景是用户大量使用的。

需要有开发视野,明白产品架构,甚至一些实现细节,这样才能对哪些 使用场景 会带来性能问题 了然于胸。

需要有测试经验, 结合前面的知识,写出良好的性能测试用例。

需要有开发技能,灵活使用各种测试工具,有的测试工具需要二次开发,甚至市场上没有现成可以使用的测试工具,必须得自己开发 测试工具。

所以通常 性能测试 和 自动化测试 能力 是高级测试人员的 必备技能。

这里做个小广告, 如果想系统学习 自动化测试、和性能测试,可以报 白月黑羽的 VIP 班。详情参见文章末尾广告栏。


前面我们学习了性能测试工具 黑羽压测 的使用,但是要做好性能测试这还不够。

必须要明白 整个性能测试的流程。

性能测试 和 功能测试一样,通常需要经历如下3个过程

  • 分析需求、确定性能测试场景

  • 编写测试计划、测试用例

  • 执行测试

在我们开始前,还有个很重要的问题:

也就是什么时候着手 启动 性能测试的工作,包括上面说的3个阶段流程?

你可能要说,那肯定越早越好啊。

但是白月黑羽的经验,不能太早。

因为性能测试的需求指标,随着产品的开发过程会非常容易产生变动。

比如:

原来估计的性能瓶颈场景, 随着开发过程,会发生改变,导致早早写好的测试用例没有用。

再比如,原来计划的产品 生产环境(包括运行设备、操作系统等),到了后来,也会发生改变,导致原来准备的硬件软件环境没有意义,产生金钱和时间上的浪费。

所以白月黑羽建议,在产品功能测试 完成几轮, 产品相对比较稳定,再启动性能测试。

当然,参与性能测试的人员,预先做一些准备是必要的。 比如:对测试工具的熟悉、相关基础知识的学习等。

需求分析

请大家点击此处链接,边看 讲解视频,边学习后面的内容

确定性能测试场景

功能测试需要测试系统的所有功能点,而性能测试只需要关注 系统功能点中 比较容易成为系统性能瓶颈的部分

比如,一个商城系统, 通常系统的瓶颈 在于 大量客户登录浏览商品,秒杀抢购某个商品 的业务场景。

而 管理员 后台操作 通常不会成为性能瓶颈,因为管理员就寥寥数人而已。

所以性能测试的场景应该是这些客户浏览商品、秒杀抢购,而不是去测试管理员 后台操作。


确定性能测试场景, 测试人员需要了解 产品的所有功能点,并且了解业务使用,甚至了解系统的实现细节。

往往测试工程师很难做到所有这些要求, 这就需要 和 产品团队、开发团队 多方面的合作。

性能测试工程师应该仔细分析 产品的功能,并且和系统的设计者交流,细致深入思考,才能 合理、全面的选定性能测试场景。

性能场景确定后,就应该和 产品部门和开发部门一起确定 硬件环境、软件环境 和 性能指标。

性能指标

如果我们要测试 的是 白月crm 系统 这样的一个 API服务系统,

常见的性能指标有:

  • 支持并发连接数量 (使用业务用户数量)
  • 单位时间处理请求数量
  • 响应正确的数量、百分比
  • 响应错误的数量、百分比
  • 响应超时的数量、百分比
  • 平均响应时间

而且还应该包括,在执行性能测试的过程中,被测系统对硬件的资源占用情况,

最重要的是:

  • CPU 占用率
  • 内存使用率

有时也需要观察如下指标:

  • 磁盘访问量
  • 网络吞吐量

运行环境、数据配置

给出测试性能指标,却不提 在什么样的 运行环境、数据配置 下测试的,是没有意义的。


  • 运行环境

运行环境 就是 被测系统在服务客户时,所运行的 硬件环境软件环境

脱离 被测系统的运行环境 谈指标是毫无意义的。

进行 测试时,要尽量 使测试环境 贴近 实际的 运行环境。

运行环境,包括:

  1. 硬件环境

包括: 服务器机型、CPU配置、内存配置、网卡配置、硬盘配置 等

有些被测系统 运行在集群系统,就需要指明集群的整体环境配置。

有些被测系统 运行在云平台上,也需要指明相应的 环境配置。

  1. 软件环境

    包括 : 操作系统、数据库 和 被测系统运行时所依赖的其他第三方组件服务,比如:消息队列系统、缓存系统、异步任务系统、反向代理系统等。

    重要系统的设置项也应该 指明,比如 缓存的内存大小分配,数据库系统的参数设置等。


  • 数据配置

数据配置 是性能测试的 业务数据设置,不同的系统有各自的业务数据。

比如 白月CRM 系统 包括:多少条注册用户、多少药品数据、多少业务订单等。

业务数据配置 对 测试结果 影响非常大。


VIP 学员请看白月crm 系统的视频介绍,思考一下,如果你来测试性能,会选取哪些功能点做性能测试。

编写测试计划、测试用例

请大家点击此处链接,边看 讲解视频,边学习后面的内容

确定 测试资源,包括:测试工程师人选、测试工具、所需测试硬件(包括何时采购到位)、测试预计启动时间、结束时间。

这和功能测试计划没有太大差异,不赘述了。


性能测试用例,就是根据前面需求分析阶段得出的测试场景来写 ,当然要注意包括 如下信息

  • 运行硬件、软件环境、数据配置

  • 对被测系统的输入,通过工具 测试出的 系统性能指标

  • 对资源的占用指标


因为性能测试通常执行比较复杂, 为了方便执行, 测试用例中可以附加上 测试工具的对应 操作步骤 和 测试代码等。


下面是 对 白月SMS2 系统的 一个性能测试用例 示例

  • 测试用例场景分析

    在月末结算时,大量代理商(销售) 会登陆 白月SMS2 系统,查询 自己的销售数据, 对系统的造成性能冲击。

    根据系统的架构设计、和数据库设计, 代理商查询销售数据 会涉及到 服务端对 订单表,用户表、药品表、代理商表 进行联合查询, 比较容易成为性能瓶颈。

    尤其是 月末 结算时, 他们会在同一时间段,查询销售数据, 前期系统曾经出现,查询卡死现象。

    本用例针对该场景进行测试。

    目前系统共有 :

    客户 2000 左右, 性能测试 模拟 3000

    代理商账户 1800 左右, 性能测试 模拟 2000

    药品 800 左右, 性能测试 模拟 1000

    历史订单数量 40000 左右, 性能测试 模拟 50000

  • 运行主机

主机 : 惠普 HPE ProLiant DL580 Gen10 Server
CPU  : Intel® Xeon® Scalable 5220 (8 core, 2.2 GHz, 24.75 MB, 125 W)
内存 : 32 GB (2x 16 GB) RDIMM
硬盘 : 1TB SSD ( 三星970 Pro M2 SSD)
网络 : 千兆网口 连接 千兆 交换机 连接  千兆网口测试主机
  • 操作系统
CentOS 7.2 x64 
  • 其他软件系统
  MySQL 5.7  参数配置由 产品自动化安装工具 设置
  Memcached  参数配置由 产品自动化安装工具 设置
  RabbitMQ   参数配置由 产品自动化安装工具 设置 
  • 测试工具
  黑羽压测 1.3.1
  • 数据配置:
  客户账户    3000 条
  代理商账户  2000 条
  药品       1000 个
  订单数量   50000 条 :
    为每个代理商,创建 25 条订单,
    每条订单中,随机选择一个客户,随机选择一种药品。                         
  • 测试过程

使用 黑羽压测 模拟高峰期 代理商登录查询场景。

单个 代理商的 模拟操作如下:

1. 从登录网页 登录网站
2. 查询自己的所有订单(25条,分5页展示)
   每隔30秒,点击下一页订单,到底后,每隔30秒,点击前一页订单
   这样循环2次

预估 单个个代理商操作总时长    (30*4*2)*2 = 480秒 (8分钟)

整个性能场景如下:

每秒2个代理商登录, 直到 2000 人全部登录操作完毕。预计耗时 1000秒

每个代理商各自进行上述流程的操作.

整个测试预计耗时 1000+480=1480秒 。

注意:

  1. 测试前,进入黑羽压测监控统计界面,先点击 右上角 清除 按钮,确保重新产生统计文件

  2. 测试前,使用 黑羽压测 部署资源统计软件到被测主机,删除老的资源统计数据,并启动 对 被测主机的 资源统计进程

  3. 测试完成后, 停止对 被测主机的 资源统计进程,获取资源统计数据

  • 预期结果
并发连接数量 : 系统要求最大支持10000代理商客户同时访问, 
               所以该场景 不应该出现 HTTP 连接超时错误

请求 正确响应率 = 100%
平均响应时长 <= 500ms
响应时长 [500ms,1000ms]  不超过 20个
响应时长 [1000ms,2000ms] 不超过 10个
响应时长 [2000ms,5000ms] 不超过 5个

在执行性能测试的过程中,被测系统对硬件的资源占用情况,

CPU 占用率  没有出现连续1分钟超过 70% 
系统使用内存使用率  不超过 50% 16G

执行测试

请大家点击此处链接,边看 讲解视频,边学习后面的内容

运行环境搭建

首先要搭建 硬件运行环境,包括 运行主机、网络环境 等。 根据产品规划,可能简单到 一台主机即可,也可能复杂到 搭建 大型的集群环境、云集群环境。

现在很多公司产品都部署到云服务器上, 这种情况我们做性能测试,有两种方式:

  • 本地测试

    需要购买 几台 主机,放到公司实验室里。

    这些主机 一部分是组建被测系统, 一部分是安装测试工具。

    然后在本地进行测试。

  • 云端测试

    需要购买 几台云主机, 一部分是组建被测系统, 一部分是安装测试工具。

    然后直接 在 云端环境进行测试。

    千万不要 只是被测系统 在 云端, 自己本地用测试工具进行测试。

    因为 本地到云端 网络 节点很多,时延较长, 而且带宽往往也是受限的,失去了性能测试的意义。

硬件环境准备好后, 要在其上安装 软件运行环境,包括:操作系统、数据库 等 系统依赖的软件。

用例执行

创建数据环境

执行性能测试用例,通常需要准备大量的测试数据。

大家不要小看性能测试的 数据准备,往往是非常麻烦的。

特别是首次创建数据环境。需要自己编写、调试创建环境的 脚本,程序,很考验开发技能。



比如,白月SMS2 系统, 上面给出的示例用例 就需要 准备大量客户、销售、药品、订单数据。这些数据怎么创建?

可以写Python程序,调用API插入。

当然也可以直接用黑羽压测,导入数据。

上面给出的 测试用例,用黑羽压测进行初始化,代码如下。具体的代码讲解,请观看视频。

# 定义 创建 客户、代理商、药品的数量
NUM_CUSTOMER = 3000
NUM_SALES    = 2000
NUM_MEDICINE = 1000

# 每个代理商创建多少订单
ORDERS_PER_SALES = 25


from urllib.parse import quote
from base64 import  b64encode

# 创建客户端     
client = HttpClient('127.0.0.1', # 目标地址:端口
                    timeout=10   # 超时时间,单位秒
                   ) 


# 管理员登录

username = 'byhy'
password = '88888888'
up = b64encode(quote(username+'#$%'+password).encode())

print('管理员登录')
response = client.sendAndRecv(
    'POST',
    '/api/mgr/signin',
    data={
        'up':up
    })


# 记录管理员 token,后面直接使用
admin_jwt = response.getheader('jwt')   
pprint(response.json('utf8'))


# 添加客户
print(f'添加{NUM_CUSTOMER}客户')
# 记录 客户 id,后面添加订单时要用到
customerids = []
for i in range(NUM_CUSTOMER):
    
    username = f'hospital_{i}'
    print(f'添加客户 {username}')
    response = client.sendAndRecv(
        'POST',
        '/api/mgr/users',
        headers={'Authorization':admin_jwt},
        json= {
            "action":"add_customer",
            "data":{
                "username": username,
                "password": "88888888",
                "realname": f"测试医院{i}",
                "desc":     f"测试医院{i}",
                "phone": f"1380000{i:04d}"
            }
        }
        )

    ret = response.json('utf8')
    if ret["retcode"] != 0:
        print('添加失败')
        exit()
        
    customerids.append(ret["id"])


# 添加代理商
print(f'添加{NUM_SALES}代理商')

for i in range(NUM_SALES):
    
    username = f'sales_{i}'
    print(f'添加代理商 {username}')
    response = client.sendAndRecv(
        'POST',
        '/api/mgr/users',
        headers={'Authorization':admin_jwt},
        json= {
            "action":"add_distributor",
            "data":{
                "username": username,
                "password": "88888888",
                "realname": f"测试代理商{i}",
                "desc":     f"测试代理商{i}",
                "phone": f"1380001{i:04d}"
            }
        }
        )

    ret = response.json('utf8')
    if ret["retcode"] != 0:
        print('添加失败')
        exit()



# 添加药品
print(f'添加{NUM_MEDICINE}药品')

# 记录 药品 id,后面添加订单时要用到
medicineids = []
for i in range(NUM_MEDICINE):
    
    medicinename = f'青霉素_{i:04d}'
    print(f'添加药品 {medicinename}')
    response = client.sendAndRecv(
        'POST',
        '/api/mgr/medicines',
        headers={ 'Authorization':admin_jwt },
        json= {
            "action":"add_one",
            "data":{
                "name": medicinename,
                "desc": "青霉素 国字号",
                "sn": f"SN00001{i:04d}"
            }
        }
        )

    
    ret = response.json('utf8')
    if ret["retcode"] != 0:
        print('添加失败')
        exit()

    medicineids.append(ret["id"])


# 添加订单
print(f'每个代理商 创建{ORDERS_PER_SALES}条订单')
for i in range(NUM_SALES):
    
    # 代理商登录
    username = f'sales_{i}'
    print(f'代理商{username}登录')
    password = '88888888'
    up = b64encode(quote(username+'#$%'+password).encode())
    
    response = client.sendAndRecv(
        'POST',
        '/api/distributor/signin',
        data={
            'up':up
        })
    

    sales_jwt = response.getheader('jwt')  

    # 创建订单
    for j in range(ORDERS_PER_SALES):
        
        time1 = time.time()
        # 随机挑选 客户 和 药品, 作为订单的采购内容
        from random import randint 
        
        customerid = customerids[randint(0,len(customerids)-1)]
        medicineid = medicineids[randint(0,len(medicineids)-1)]
    
        ordername = f"测试订单_{username}_{j}"
        print(f'创建订单 {ordername}')
        response = client.sendAndRecv(
            'POST',
            '/api/distributor/orders',
            headers={'Authorization':sales_jwt},
            json={
                "action": "wf_order",
                "wf_action": "wf_submit_order",
                "data": {
                    "name": ordername,
                    "desc": ordername,
                    "customer_id": customerid,
                    "medicinelist": [
                        {
                            "id": medicineid,
                            "v": "20000",
                            "name": "青霉素盒装"
                        }
            
                    ]
                }
            }
    
        )
    
        ret = response.json('utf8')
        if ret["retcode"] != 0:
            print('创建订单失败')
            exit()

        orderid = ret["id"]
        
        
        # 审批订单
        # print('审批订单')
        response = client.sendAndRecv(
            'POST',
            '/api/mgr/orders',
            headers={'Authorization':admin_jwt},
            json={
                "action": "wf_order",
                "wf_action": "wf_approve_order",
                "data": {
                    "id": orderid,
                    "comment": "同意"
                }
            }
    
        )
        
        ret = response.json('utf8')
        if ret["retcode"] != 0:
            print('审批订单失败')
            exit()
            
        
        # 签收订单
        # print('签收订单')
        response = client.sendAndRecv(
            'POST',
            '/api/distributor/orders',
            headers={'Authorization':sales_jwt},
            json={
                "action": "wf_order",
                "wf_action": "wf_confirm_receive",
                "data": {
                    "id": orderid,
                    "comment": "收到"
                }
            }
        )
        
        ret = response.json('utf8')
        if ret["retcode"] != 0:
            print('签收订单失败')
            exit()
            
        
        takes = time.time()-time1
        print(f'一个订单耗时{takes} 秒')


调用API插入的方式可能耗时很长(为什么?自己思考一下)。

比如上面的代码,在普通个人电脑上执行,创建完数据,要耗时 1小时左右。

如果有更大量的测试数据要导入,就会花费更多时间。


实际项目中,调用API插入数据慢到不可接受。

所以往往 我们采用的方法是: 通过SQL语句直接往数据库插入数据。

当然,前提是 写程序的人 需要 充分了解产品的数据库定义。

这种方式,这样会快很多。

还是上面的用例,同样的数据,用下面的代码,导入 sqlite 数据库,只需要 几秒钟,比用API插入的程序快 几百倍!!

# 定义 创建 客户、代理商、药品的数量
NUM_CUSTOMER = 3000
NUM_SALES    = 2000
NUM_MEDICINE = 1000

# 每个代理商创建多少订单
ORDERS_PER_SALES = 25

# sqlite 数据库文件路径
DB_FILE = r'd:\tools\bysms2\bysms2\bycrm.sqlite3'


# 客户id范围,用户表开始有3条数据
ID_CUSTOMER = [4,4+NUM_CUSTOMER-1] 

# 代理商id范围
ID_SALES = [4+NUM_CUSTOMER,4+NUM_CUSTOMER+NUM_SALES-1]


# 药品id范围,药品表开始有1条数据
ID_MEDICINE = [1,1+NUM_MEDICINE-1] 

from random import randint 
import sqlite3
conn = sqlite3.connect(DB_FILE)

c = conn.cursor()

# 添加客户
print('添加客户')
tplt = '''INSERT INTO `by_user` (`password`, `last_login`, `is_superuser`, `username`, `first_name`, `last_name`, `email`, `is_staff`, `is_active`, `date_joined`, `usertype`, `realname`, `desc`, `phone`, `avatar_url`) VALUES
	('md5$eaLJpard8wB4$136393387ec65b9e4a4cc5e4bb46ada9', NULL, 0, 'hospital_%s', '', '', '', 1, 1, '2018-10-07 13:26:16.355364', 3000, '测试医院%s', '测试医院%s', NULL, NULL)  ; '''

for i in range(NUM_CUSTOMER):
    sql =   tplt % (i,i,i)
    c.execute(sql)

conn.commit()


# 添加代理商
print('添加代理商')
tplt = '''INSERT INTO `by_user` (`password`, `last_login`, `is_superuser`, `username`, `first_name`, `last_name`, `email`, `is_staff`, `is_active`, `date_joined`, `usertype`, `realname`, `desc`, `phone`, `avatar_url`) VALUES
	('md5$eaLJpard8wB4$136393387ec65b9e4a4cc5e4bb46ada9', NULL, 0, 'sales_%s', '', '', '', 1, 1, '2018-10-07 13:26:16.355364', 4000, '测试代理商%s', '测试代理商%s', NULL, NULL) ; '''

for i in range(NUM_SALES):
    sql =   tplt % (i,i,i)
    c.execute(sql)

conn.commit()



# 添加药品
print('添加药品')
tplt = '''INSERT INTO `by_medicine` ( `name`, `sn`, `desc`) VALUES
	( '青霉素_%s', 'snb000001', '青霉素_%s'); '''

for i in range(NUM_MEDICINE):
    sql =   tplt % (i,i)
    c.execute(sql)

conn.commit()



# 添加订单
print('添加订单')
tplt1 = '''
INSERT INTO `by_order` ( `name`, `create_date`, `desc`, `creator_id`, `customer_id`, `workflow_ver`, `workflow_cur_statename`, `workflow_cur_statecode`, `fee`,`medicinelist`,  `workflow_rec`) VALUES
	('$订单名$', '2019-10-13 16:33:33.140735', '$订单名$', $代理商id$, $客户id$, '1.0', '订单完成', 's3', $金额$, 
    
    '[{"id": $药品id$, "v": "200", "name": "测试药品"}]', 
    
    '{"steps": [{"statecode": "init", "statename": "创建", "time": "2019-10-13 16:33:33", "action": "wf_submit_order", "actionname": "提交订单", "actor": $代理商id$, "actorname": "$代理商姓名$"}, {"statecode": "s1", "statename": "审核", "time": "2019-10-13 16:33:33", "action": "wf_approve_order", "actionname": "批准订单", "actor": 1, "actorname": "白月黑羽", "comment": ""}, {"statecode": "s5", "statename": "发货", "time": "2019-10-13 16:33:33", "action": "wf_confirm_receive", "actionname": "确认收货", "actor": $代理商id$, "actorname": "$代理商姓名$", "comment": ""}, {"statecode": "s3"}]}')
'''


tplt2 = '''INSERT INTO `by_order_medicine` ( `amount`, `medicine_id`, `order_id`) VALUES
	( 2000, '%s', '%s'); '''

# 订单id,因为数据库中已经有一条记录,所以从2开始
orderid = 2

for i in range(NUM_SALES):
    salesname = f'sales_{i}'     # 代理商登录名
    salesrealname = f'测试代理商_{i}' # 代理商真实姓名
    sales_uid = ID_SALES[0] + i  # 代理商id
    print(salesrealname)
    for j in range(ORDERS_PER_SALES): 

         # 随机挑选 客户 和 药品, 作为订单的采购内容
        
        customerid = randint(ID_CUSTOMER[0],ID_CUSTOMER[1])
        medicineid = randint(ID_MEDICINE[0],ID_MEDICINE[1])
        
        sql =  tplt1.replace('$订单名$',f'测试订单_{salesrealname}_{j}') \
                    .replace('$代理商id$',f'{sales_uid}') \
                    .replace('$客户id$',f'{customerid}') \
                    .replace('$药品id$',f'{medicineid}') \
                    .replace('$药品名称$',f'{medicineid}') \
                    .replace('$代理商姓名$',f'{salesrealname}') \
                    .replace('$金额$',f'{randint(50000,90000)}.00')
        
        # 订单表插入记录
        c.execute(sql)

        # by_order_medicine 表插入记录
        sql = tplt2 % (medicineid,orderid)
        c.execute(sql)

        orderid += 1


conn.commit()

conn.close()


如果 数据库服务是 MySQL ,创建数据程序如下,也只需不到1分钟,即可完成数据导入。

# 定义 创建 客户、代理商、药品的数量
NUM_CUSTOMER = 3000
NUM_SALES = 2000
NUM_MEDICINE = 1000

# 每个代理商创建多少订单
ORDERS_PER_SALES = 25


# 客户id范围,用户表开始有3条数据
ID_CUSTOMER = [4, 4 + NUM_CUSTOMER - 1]

# 代理商id范围
ID_SALES = [4 + NUM_CUSTOMER, 4 + NUM_CUSTOMER + NUM_SALES - 1]

# 药品id范围,药品表开始有1条数据
ID_MEDICINE = [1, 1 + NUM_MEDICINE - 1]

from random import randint

import MySQLdb

# 创建一个 Connection 对象,代表了一个数据库连接
conn = MySQLdb.connect(
       host="192.168.1.100",# 数据库IP地址
       user="user2",     #  mysql用户名
       passwd="Mima123$",      # mysql用户登录密码
       db="bycrm" ,        # 数据库名
       charset = "utf8")

c = conn.cursor()

# 添加客户
print('添加客户')
tplt = '''INSERT INTO `by_user` (`password`, `last_login`, `is_superuser`, `username`, `first_name`, `last_name`, `email`, `is_staff`, `is_active`, `date_joined`, `usertype`, `realname`, `desc`, `phone`, `avatar_url`) VALUES
	('md5$eaLJpard8wB4$136393387ec65b9e4a4cc5e4bb46ada9', NULL, 0, 'hospital_%s', '', '', '', 1, 1, '2018-10-07 13:26:16.355364', 3000, '测试医院%s', '测试医院%s', NULL, NULL)  ; '''

for i in range(NUM_CUSTOMER):
    sql = tplt % (i, i, i)
    c.execute(sql)

conn.commit()

# 添加代理商
print('添加代理商')
tplt = '''INSERT INTO `by_user` (`password`, `last_login`, `is_superuser`, `username`, `first_name`, `last_name`, `email`, `is_staff`, `is_active`, `date_joined`, `usertype`, `realname`, `desc`, `phone`, `avatar_url`) VALUES
	('md5$eaLJpard8wB4$136393387ec65b9e4a4cc5e4bb46ada9', NULL, 0, 'sales_%s', '', '', '', 1, 1, '2018-10-07 13:26:16.355364', 4000, '测试代理商%s', '测试代理商%s', NULL, NULL) ; '''

for i in range(NUM_SALES):
    sql = tplt % (i, i, i)
    c.execute(sql)

conn.commit()

# 添加药品
print('添加药品')
tplt = '''INSERT INTO `by_medicine` ( `name`, `sn`, `desc`) VALUES
	( '青霉素_%s', 'snb000001', '青霉素_%s'); '''

for i in range(NUM_MEDICINE):
    sql = tplt % (i, i)
    c.execute(sql)

conn.commit()

# 添加订单
print('添加订单')
tplt1 = '''
INSERT INTO `by_order` ( `name`, `create_date`, `desc`, `creator_id`, `customer_id`, `workflow_ver`, `workflow_cur_statename`, `workflow_cur_statecode`, `fee`,`medicinelist`,  `workflow_rec`) VALUES
	('$订单名$', '2019-10-13 16:33:33.140735', '$订单名$', $代理商id$, $客户id$, '1.0', '订单完成', 's3', $金额$, 

    '[{"id": $药品id$, "v": "200", "name": "测试药品"}]', 

    '{"steps": [{"statecode": "init", "statename": "创建", "time": "2019-10-13 16:33:33", "action": "wf_submit_order", "actionname": "提交订单", "actor": $代理商id$, "actorname": "$代理商姓名$"}, {"statecode": "s1", "statename": "审核", "time": "2019-10-13 16:33:33", "action": "wf_approve_order", "actionname": "批准订单", "actor": 1, "actorname": "白月黑羽", "comment": ""}, {"statecode": "s5", "statename": "发货", "time": "2019-10-13 16:33:33", "action": "wf_confirm_receive", "actionname": "确认收货", "actor": $代理商id$, "actorname": "$代理商姓名$", "comment": ""}, {"statecode": "s3"}]}')
'''


# 订单id,因为数据库中已经有一条记录,所以从2开始
orderid = 2
medicine_order_recs = []
for i in range(NUM_SALES):
    salesname = f'sales_{i}'  # 代理商登录名
    salesrealname = f'测试代理商_{i}'  # 代理商真实姓名
    sales_uid = ID_SALES[0] + i  # 代理商id
    print(salesrealname)
    for j in range(ORDERS_PER_SALES):
        # 随机挑选 客户 和 药品, 作为订单的采购内容

        customerid = randint(ID_CUSTOMER[0], ID_CUSTOMER[1])
        medicineid = randint(ID_MEDICINE[0], ID_MEDICINE[1])

        sql = tplt1.replace('$订单名$', f'测试订单_{salesrealname}_{j}') \
            .replace('$代理商id$', f'{sales_uid}') \
            .replace('$客户id$', f'{customerid}') \
            .replace('$药品id$', f'{medicineid}') \
            .replace('$药品名称$', f'{medicineid}') \
            .replace('$代理商姓名$', f'{salesrealname}') \
            .replace('$金额$', f'{randint(50000, 90000)}.00')

        # 订单表插入记录
        c.execute(sql)

        medicine_order_recs.append((medicineid, orderid))

        orderid += 1

conn.commit()

# by_order_medicine 表插入记录
tplt2 = '''INSERT INTO `by_order_medicine` ( `amount`, `medicine_id`, `order_id`) VALUES
	( 2000, '%s', '%s'); '''
print('by_order_medicine 表插入记录 ')
for rec in medicine_order_recs:
    sql = tplt2 % rec
    c.execute(sql)
conn.commit()

conn.close()

print('=== 完成 ====')

但是这种 方式 有一定风险,要确保你的插入数据格式 和 当前发布的产品 插入的 数据 格式 一致。

因为,你要测试的新版本,有可能数据格式已经有了改变,你必须做出相应的调整。

执行测试步骤

请大家点击下面两个链接,边看 讲解视频,边学习后面的内容

执行性能测试用例-上

执行性能测试用例-下

执行测试,主要就是根据测试用例的描述进行测试。

先写好对应测试用例的 测试代码。

VIP学员请联系 老师获取 上面 用例 对应的代码。

我使用 黑羽压测 测试完 该 后,得到如下的 性能统计图

image


和 如下的 被测主机 资源 占用图

image

具体请参考视频讲解。





扫码分享给朋友,一起学更有动力哦




上一页