前言
本来是想先更新一手UI自动化的文章续写的,也已经写到了一半,但是因为今天美女开发无意问了一下如何批量造100条告警数据在告警记录列表中,虽然可以用navicat直接Excel批量导入,但是既然近期又有在复习点python,前面我也学到了关于python构造数据的方法,心血来潮还是准备小小的水一篇博客,也不算水肯定是软件测试的干货!
我们软件测试平常最有质量活的不一定是接口而是在测试站数据库里进行一些新增功能的数据模拟,这在每一次的迭代里都是必不可少的,因此我们如果学会了对想要的数据进行大批量的构造的话,那么对于功能验证的可靠度必然是事半功倍。
ps:其实python也可以用来做接口测试的自动化,不过我是觉得接口测试用工具快的很多,而且是可视化的更好。
1.环境搭建及代码基本流程
因为前言说的太水,这里环境搭建我直接进入正题,只要能够有一个基本的框架就能够直接搭建起我们的数据构造,btw这里我默认是用过navicat知道基本的sql语句和一定python基础的要求,如果纯新手可能不一定看得很清楚。可以去看一波mysql基本语句学习~
1.1安装PyMySQL
有两种方法,一个是 pip install PyMySQL,这个是python终端自己下载的可能受限速会慢很多;第二个方法是pip install PyMySQL -i https://pypi.douban.com/simple/ ,这直接从第三方下载镜像会快很多。
如果导入成功的话可以直接使用对应的导包语句,来验证不成功就会有提醒。
1.2操作数据库的基本流程
代码实现步骤:
1.导包 import pymysql
2.创建数据库连接 conn = pymysql.connect()
3.获取游标对象 cursor = conn.Cursor()
4.执行增删改查 cursor.execute("sql语句")
提取数据:fetch *
conn.commit()--成功提交事务
conn.rollback()--失败回滚事务
5.关闭游标对象 cursor.close()
6.关闭数据库连接 conn.close()
ps:这里事务的概念主要是关系型数据库mysql特有的概念,可以把它看作是一个虚拟的容器,在这个容器中存放一系列的数据库操作,看做一个整体。内部的所有操作,要么一次性全部成功,只要有一个失败,就全部失败。 例如一张银行卡往另外一张银行卡转钱,一个会减少一个会变多,如果只有一个成功了意味着这个事务是失败的。
2.代码讲解
2.1创建数据库对象和获取游标对象
第一步的导包就不用解释了,我们直接来看创建数据库对象。既然我们要对数据库操作我们就要先去连接数据库,这里我们以navicat来举例,navicat在连接数据库前会有以下的这个框来进行连接
那么很显然,我们也需要去填写这些数据才能连接上我们的数据库。pymsql包就提供给我们这么一个接口让我们来连接。如下图所示
能够很清晰的看到,我们创建的数据库连接对象 conn ,它引用了我们pymysql包中的connect()模块,(如果对包,模块,类,方法之间的关系还不清楚的话也可以去看一下前面ui自动化部分的博客)connect模块所需要的形参包含了我们连接数据库所需要的主机ip、用户名、密码、数据库名等。
至此,我们就完成了数据库连接对象的创建了,接下来就是获取游标对象。怎么样获取游标对象,同样也是一样我们去定义一个对象名也就是 “cursor”,那么就有了接下来的这行代码
cursor = conn.cursor()
看得出来cursor对象引用的是来自于conn数据库连接对象里的游标方法,因为我们已经对数据库连接创建了对应的conn对象,那么我们就可以调用连接好的数据库里的游标方法cursor()。
所以这行代码由此而来,我们也完成了获取游标对象的步骤。
2.2利用游标执行增删改查
2.2.1理解游标和常用的提取方法
其实我们的代码或者navicat相当于是客户端,我们要去访问我们的mysql让它作为服务器。我们已经用conn连接方法铺了一条路,那么游标cursor就是在这条路上行驶的车,传递客户端和服务端之间的信息,连接方法也就是路有一条就可以了,但是我们的游标cursor作为在路上行驶的车可以有多个(辆)。
例如我们利用游标cursor去执行我们的sql语句,也就是cursor.execute("mysql语句")。这里的mysql语句例如是select * from goods ,返回的是我们货物的表,那么我们返回的数据肯定是多条的。这里,需要强调的是游标提取的数据始终是游标所在位置的下一行!!每提取一行后就会往自动下走一行,其实这里用数组的形式来理解即可游标初始位置就是0开始,然后提取第一行的数据。
游标常用的方法有以下几种:
1.fetchone():从结果集中,提取一行
2.fetchmany(size):从结果集中,提取size行
3.fetchall():提取全部
4.rownumber:设置游标位置,ex:cursor.rownumber = 0 游标位置 回零
2.2.2简单的查询语句和增加语句
我们平常最常用的语句就是select * from xx表,然后以这个基本架构展开来检索我们的数据库表,那么我们使用游标来执行的话就可以是下面的形式
图片里的注释也写的很清晰,我们利用常用的几个游标提取方法,就能够提取到我们想要的查询返回记录里的某条记录,例如想要提取第四第五第六条数据,那么我们就可以使用游标的rownumber来将位置从一开始的0直接定位到3,然后再使用fetchmany的方法选择三条数据,这样思路出来了就可以以下面的形式实现。
cursor.execute("select * from goods")
cursor.rownumber = 3 # 游标定位到第三行
result = cursor.fetchmany(3) # 提取三行数据,因为游标在第三行的位置它会从下一行开始,最后取到我们想要的第四五六三行的记录
print(result)
那么如果我们把这里的mysql语句从查询改变为插入新增的语句呢,毕竟我们本是就是想要去构造数据。我们重新回顾一下我们的插入语句,insert into 表(字段1,字段2) values("记录1","记录2";),现在代入到代码中来简单试试看,有去尝试的话就会发现并不会生效,因为我们这里缺少了事务的提交也就是commit()方法。
2.2.3 异常捕获方法封装
在讲commit事务提交方法之前先补充一个比较有完整性的结构,它是由try,except,finally几个关键词进行组合而成的能够抛出错误异常的一个结构。为了防止我们无法出现代码执行判断的一个验证,我们是用了这样一个结构来抛出过程中的异常。
一般的格式如下:
try:
尝试执行的代码
except Exception as err:
有错误出现时,执行的代码
finally:
无论有没有错误,都会执行的代码
这样的格式,try中尝试执行的代码一般就是我们前面从创建数据库连接开始的部分到我们使用游标执行mysql语句后输出结果结束,finally的语句就是最后关闭游标和关闭连接的部分。因此中except 这部分一般是print("执行错误")。
ps:这里因为用了这个结构,所以我们还得考虑到先前创建的连接数据库对象conn和游标对象cursor进行一个全局变量的声明,也就是用conn =None,cursor =None,让他们的初始值为 None。
2.2.4 事务提交和回滚
上面讲的这个抛出异常的结构是为了我们去提交事务commit()和rollback()这样的语句执行。那么我们实际上去构造我们想要的数据,我们就需要使用对应的commit()方法来提交我们的插入语句。commit()方法就是我们先前创建数据库连接对象能够调取到的一个方法。
在下图看来我们新增的这条语句就能够成功在数据库当中增添一条我们想要的数据。
3.批量构造10万条数据
3.1步骤
其实很简单,就是两步
1.准备插入数据的SQL语句
2.循环执行SQL语句来插入数据
我们还是以navicat举例,我们想要插入一条语句,我们就利用工具的便捷性,点击 -查询 -新建查询,直接select *from 表名,找到我们想要构造数据的表的内容,例如我们想要构造用户的表。通过查询到这张表,然后以下图右键选择复制为
到这一步,已经知道了我们可以复制成我们想要插入的sql语句已经出来了:INSERT INTO `litemall`.`litemall_admin`(`id`, `username`, `password`, `last_login_ip`, `last_login_time`, `avatar`, `add_time`, `update_time`, `deleted`, `role_ids`) VALUES (5, 'mall123', '$2a$10$aCtsc4rG6KmxQ59.IkYse.oRyKuwQoU2CPCmxSdB.d5nXq6aw/z4O', '', NULL, 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', '2019-01-07 15:17:25', '2019-01-07 15:21:05', 0, '[2]');
这一大串sql格式的语句其实并不重要,重要的是我们怎么插入大量重复的数据呢?没错,就是用for i in range()我们最常见的循环语句。
3.2实现结果
博客写到这里已经是凌晨了,上面其实说的很详细,这里我也不再赘述。直接展示简单的一个循环语句结果就好,我们主要是要避免一些键的重复,一般来说可以直接对主键进行一个循环的累加从而实现具体的一个构造数据的操作。
对于除了主键以为的某些字段比如username或者password我们也可以使用{}format函数来进行变量的替代,例如上图里的代码脚本就更改了对应的数据使用字符串类型的组合构造出用户名和密码的更改,基于id的一百次循环就能够让每个构造的数据有可信性。
总结
其实这个博客的最后写的还是比较匆忙写完已经接近凌晨两点了,但是能够灵活使用这个脚本的前提还是要对python有一定的熟悉程度,并且能够有较好的mysql理论知识且能利用远程工具对数据库进行一个熟练的操作,才好体会到快速构造大量数据的妙处。包括朋友在工作上的实践用例分享,也是涵盖了多个知识点由接口性能工具开始到前端知识点中的html、正则表达式、shell语言操作等才实现的繁琐化简,因此还是那句话stay hungry,stay foolish。