本篇介绍的事情:连接MySQL数据库--操作数据库--初始化数据--输出结果--与selenium相结合完成数据驱动。
在平时的自动化测试中应用的数据驱动有多种方式,包含MySQL数据库数据驱动测试、XML进行数据驱动测试、Excel进行数据驱动测试、数据文件进行数据驱动测试等。
从大多数的实际实施过程来看,主要用的是MySQL数据库数据驱动测试、Excel进行数据驱动测试。两者大同小异,但又各有千秋,看个人喜好,说实在的Excel数据驱动要好使一点,但是用MySQL进行数据驱动逼格更高(这是跟一个大佬交流所得的),逼格高,自然就敢要价喽,所以嘛就学这个啦!毕竟一切都是为了钱!!!嘿嘿
一、本篇代码的目录结构
Mysql_Test_Data:工程名称
DataDriverMysql.py:用于编写执行数据驱动的测试脚本
DatabaseInit.py :用于编写初始化数据库的脚本
MysqlUtil.py:用于从数据库获取测试数据
文件的编写先后顺序:DatabaseInit.py--->MysqlUtil.py--->DataDriverMysql.py
二、文件内容详细说明
(1)、第一个DatabaseInit.py文件内容。
1 # -*- coding: utf-8 -*-
2
3 import pymysql
4 import sys
5 from sql import *
6
7 # 初始化数据库操作
8 class DataBaseInit():
9 def __init__(self,host,user,dbName,passwd,charset):
10 self.host = host
11 self.user = user
12 self.db = dbName
13 self.passwd = passwd
14 self.charset = charset
15 print("--------------载入mysql模块完成--------------")
16 def create(self):
17 try:
18 # 连接数据库
19 con = pymysql.connect(
20 host = self.host,
21 user = self.user,
22 passwd = self.passwd,
23 charset = self.charset
24 )
25 print("创建连接完成")
26 cur = con.cursor()
27 print("获取光标完成")
28 # 因为的数据库已经创建完成,所以创建的过程注释掉了。
29 # cur.execute("create database test_db character set utf8;")
30 # print("创建test_db库完成")
31 cur.execute("use test_db;")
32 print("进入test_db库完成")
33 except pymysql.Error as e:
34 raise e
35
36 def insertDatas(self):
37 # 连接到数据库的指定的数据表(其实在当前情况下可以省略这个步骤,但是也不影响,就留这吧,备用)
38 try:
39 con = pymysql.connect(
40 host = self.host,
41 user = self.user,
42 db = self.db,
43 passwd = self.passwd,
44 charset = self.charset
45 )
46 # 对数据库test_db的数据表test_tab1进行操作,增、改、删
47 cur = con.cursor()
48 cur.execute("INSERT INTO test_db.test_tab1(id,username,pasword,studentName,age,sex,phone,bjId,gyId,ishd,iszc,isdelete) VALUES(6,'LQ006',123456,'邓亚萍',35,'女',17927524652,1,205,'是','是',1);")
49 cur.execute("update test_db.test_tab1 SET isdelete=1 WHERE id=6;")
50 cur.execute("delete FROM test_db.test_tab1 WHERE id=6;")
51 # 对数据库进行增、改、删操作后需要进行commit提交操作,否则进行的操作将不会被保存。
52 con.commit()
53 print("...操作数据库成功...")
54 except pymysql.Error as e:
55 raise e
56 if __name__ == '__main__':
57 # 数据库连接信息
58 db = DataBaseInit(
59 host='localhost', # 数据库连接地址
60 user='root', # 数据库连接用户名
61 dbName = 'test_db', # 连接的数据库
62 passwd='1234', # 连接数据库的密码
63 charset='utf8' # 连接数据库的编码,不要用utf-8,会有意想不到的结果。
64 )
65 db.create()
66 db.insertDatas()
67 print("...初始化数据结束...")
对于这个文件内容的思路已经备注。
在文中有一个创建数据表的步骤我没写,现在也贴出来吧,方便查看,同时明白所操作的数据表的结构:
1 创建数据表
2 cur.execute("""create table test_tab1(
3 id int primary key auto_increment comment '主键',
4 username varchar(100) comment '录取通知书编号',
5 pasword varchar(100) comment '身份证号',
6 studentName varchar(100) comment '姓名',
7 age varchar(100) comment '年龄',
8 sex varchar(100) comment '性别',
9 phone varchar(100) comment '电话',
10 bjId int comment '班级',
11 gyId int comment '宿舍',
12 ishd varchar(100) comment '信息是否核对',
13 iszc varchar(100) comment '是否注册')
14 isdelete varchar(5) comment,是否删除)
15 comment '学生';""")
16 print('创建test_tab1表完成')
对应的创建完成的数据表长这样:
以上文件完成了对数据库的连接、初始化、增、删、改操作。其中对数据库操作的SQL语句是可以分离出来单独存放一个文件的,留给各位自己折腾吧。
在实际工作中我们可以把对应的测试所需数据存放在数据表中,然后直接去查询调用。维护测试数据的时候我们就直接去数据库中进行操作就好了。
(2)、第二个MysqlUtil.py文件内容。
1 # -*- coding: utf-8 -*-
2
3 import pymysql
4 # 导入DatabaseInit文件的DataBaseInit类
5 from DatabaseInit import DataBaseInit
6
7 class ObtainResult():
8 def __init__(self,host,user,dbName,passwd,charset):
9 # 进行数据库初始化
10 dbInit = DataBaseInit(host,user,dbName,passwd,charset)
11 dbInit.insertDatas()
12 self.con = pymysql.connect(
13 host = host,
14 user = user,
15 db = dbName,
16 passwd = passwd,
17 charset = charset
18 )
19 self.cur = self.con.cursor()
20 def getDataFromBaseas(self):
21 # 从表中查询测试所需数据并返回查询结果
22 self.cur.execute("SELECT studentName FROM test_db.test_tab1 WHERE id=1;")
23 dataTup = self.cur.fetchall()
24 return dataTup
25 # 数据库的后期清理工作
26 def closeDatabase(self):
27 self.cur.close()
28 self.con.commit()
29 self.con.close()
30 if __name__ == "__main__":
31 db = ObtainResult(
32 host='localhost',
33 user='root',
34 dbName = 'test_db',
35 passwd='1234',
36 charset='utf8'
37 )
38 print (db.getDataFromBaseas())
39 db.closeDatabase()
第一个文件完成了对数据库的基本操作,第二个文件主要是针对后边的测试需要进行的操作,也就是为第三个文件做铺垫的。在这个文件中查询出了表中ID=1的studentName的值。
(3)、第三个DataDriverMysql.py文件。
1 # -*- coding: utf-8 -*-
2
3 from selenium import webdriver
4 import unittest,time
5 import ddt
6 import logging,traceback
7 import pymysql
8 import sys
9 from sql import *
10 from MysqlUtil import ObtainResult
11 from selenium.common.exceptions import NoSuchElementException
12
13
14 # 初始化日志对象
15 logging.basicConfig(
16 # 定义日志级别
17 level = logging.INFO,
18 # 定义日志格式(包含时间、代码所在文件夹、代码行号、日志级别名字、日志信息)
19 format = '%(asctime)s%(filename)s[line:%(lineno)d]%(levelname)s %(message)s',
20 # 显示打印日志的时间
21 datefmt = '%Y/%m/%d %H:%M:%S',
22 # 日志文件的存放目录(目录已经存在)以及日志文件名称
23 filename = 'F:Test_CaseMysql_Test_DatadataPreport.log',
24 # 定义日志内容的打开方式
25 filemode = 'w'
26 )
27
28 def getTestDatas():
29 # 初始化数据库(文件中的初始化数据的操作可以全部抽出来,单独存放文件,调用即可)
30 db = ObtainResult(
31 host='localhost',
32 user='root',
33 dbName = 'test_db',
34 passwd='1234',
35 charset='utf8'
36 )
37 # 从第二个文件中获取查询的数据
38 testData = db.getDataFromBaseas()
39 # 关闭数据库
40 db.closeDatabase()
41 return testData
42
43 @ddt.ddt
44 class TestDemo(unittest.TestCase):
45 def setUp(self):
46 self.driver = webdriver.Chrome(executable_path = "F:PythonScriptschromedriver.exe")
47 @ddt.data( * getTestDatas())
48 def test_dataDriverDatabase(self,data):
49 # 对上边获取的数据进行解包供其后边填写使用
50 testData,sex = data
51 # 请求Baidu实例,调用Baidu进行搜索由数据库中查到的studentName,sex值
52 url = "https://www.baidu.com/"
53 self.driver.get(url)
54 # 最大化当前窗口
55 self.driver.maximize_window()
56 print(testData,sex)
57 # 设置隐示等待时间5秒
58 self.driver.implicitly_wait(5)
59 try:
60 # 在ID=kw的Baidu搜索数据库中输入在数据库中查询到的值
61 self.driver.find_element_by_id("kw").send_keys(testData)
62 # 点击“百度一下”按钮
63 self.driver.find_element_by_id("su").click()
64 time.sleep(5)
65 # 断言页面中是否出现预期的结果
66 self.assertTrue(sex in self.driver.page_source)
67 except NoSuchElementException as e:
68 logging.error("查找的页面信息不存在,异常的堆栈信息:"+str(traceback.format_exc()))
69 except AssertionError as e:
70 logging.info("搜索的内容:%s,预期的结果:%s,搜索失败" %(testData,sex))
71 except Exception as e:
72 logging.error("来自未知的错误信息:"+str(traceback.format_exc()))
73 else:
74 logging.info("搜索的内容:%s,预期的结果:%s,搜索成功" %(testData,sex))
75
76 def tearDown(self):
77 self.driver.quit()
78 if __name__ == '__main__':
79 unittest.main()
首先,为了打印出我们所需的测试日志,方便进行后续的执行分析,进行了初始化日志操作并结合后边的断言,实现了日志的输出与记录。最终执行后的日志文件内容如下:
然后,初始化数据库并接收到第二个文件中查询出的所需数据。接受的内容我们进行了打印:
最后,通过selenium脚本定位的方式对Baidu进行了实例操作,并且搜索了来自第二个文件的查询内容并判断页面中是否出现了我的预期结果。
至此,python3操作MySQL实现数据驱动完整实例就完成了,后边对相关的知识点做一丢丢补充。
三、相关知识点补充。
1、关于日志
(1)、logging 的函数
√、日志记录的级别:
1 logging.debug(msg, *args, **kwargs);
2 logging.info(msg, *args, **kwargs);
3 logging.warning(msg, *args, **kwargs);
4 logging.error(msg, *args, **kwargs);
5 logging.critical(msg, *args, **kwargs);
日志级别排序: CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET。
(2)、logging.basicconfig() 函数
关于使用的实例,请在上边第三个文件中查看。关于用法以及可选参数说明如下:
1 filename 指定日志文件名;
2 filemode 指定日志文件打开的模式,w 或 a;
3 level 指定日志级别,默认 logging.WARNING;
4 format 指定输出的格式和内容,format 的参考信息如下;
5 datefmt 使用指定的时间格式,format 参数中有 asctime 的话,需要使用 datefmt 指定格式。
(3)、关于日志中输出格式参数的说明与补充。
1 %(levelno)s: 打印日志级别的数值;
2 %(levelname)s: 打印日志级别名称;
3 %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0];
4 %(filename)s: 打印当前执行程序名;
5 %(funcName)s: 打印日志的当前函数;
6 %(lineno)d: 打印日志的当前行号;
7 %(asctime)s: 打印日志的时间;
8 %(thread)d: 打印线程ID;
9 %(threadName)s: 打印线程名称;
10 %(process)d: 打印进程ID;
11 %(message)s: 打印日志信息。
2、关于Python中对数据库的操作
1 con = pymysql.connect(连接内容) 建立数据库连接,返回连接对象con;
2 con.cursor() 创建游标对象cur;
3 cur.execute(sql) 执行SQL语句;
4 cur.execute(sql,parameters) 执行带参数的SQL语句;
5 cur.executemany(sql,seq_of_pqrameters) 根据参数执行多次SQL语句;
6 cur.executescript(sql_script) 执行SQL脚本;
7 cur.fetchone() 返回结果集的下一行,无数据时返回None;
8 cur.fetchall() 返回结果集的剩余行,无数据时返回空list;
9 cur.fetchmany() 返回结果集的多行,无数据时返回空list;
10 con.commit() 事务提交;
11 con.rollback() 事务回滚;
12 cur.close() 关闭游标对象;
13 con.close() 关闭数据库对象。
原创文章,欢迎转载,表明出处,欢迎留言,共同学习,共同进步!!