zoukankan      html  css  js  c++  java
  • 读取excel表格以及生成自动化报告

    数据库读取

    标签(空格分隔): 数据库读取


    读excel数据xlrd

    当登录的账号有多个的时候,我们一般用excel存放测试数据,本节课介绍,python读取excel方法,并保存为字典格式。

    1.先安装xlrd模块,打开cmd,输入pip install xlrd在线安装

    pip install xlrd

    二、基本操作
    1.exlce基本操作方法如下

    # 打开exlce表格,参数是文件路径
    data = xlrd.open_workbook('test.xlsx')
    # table = data.sheets()[0]           #  通过索引顺序获取
    # table = data.sheet_by_index(0)     #  通过索引顺序获取
    table = data.sheet_by_name(u'Sheet1')  # 通过名称获取
    nrows = table.nrows  # 获取总行数
    ncols = table.ncols  # 获取总列数
    # 获取一行或一列的值,参数是第几行
    print table.row_values(0)  # 获取第一行值
    print table.col_values(0)  # 获取第一列值
    

    三、excel存放数据
    1.在excel中存放数据,第一行为标题,也就是对应字典里面的key值,如:username,password
    2.如果excel数据中有纯数字的一定要右键》设置单元格格式》文本格式,要不然读取的数据是浮点数
    (先设置单元格格式后编辑,编辑成功左上角有个小三角图标)
    image.png-6.9kB

    四、封装读取方法
    1.最终读取的数据是多个字典的list类型数据,第一行数据就是字典里的key值,从第二行开始一一对应value值

    #!/usr/bin/env python
    # coding=utf-8
    import xlrd
    class ExcelUtil():
        def __init__(self, excelPath, sheetName):
            self.data = xlrd.open_workbook(excelPath)
            self.table = self.data.sheet_by_name(sheetName)
            # 获取第一行作为key值
            self.keys = self.table.row_values(0)
            # 获取总行数
            self.rowNum = self.table.nrows
            # 获取总列数
            self.colNum = self.table.ncols
            
        def dict_data(self):
            if self.rowNum <= 1:
                print("总行数小于1")
            else:
                r = []
                j = 1
                for i in range(self.rowNum - 1):
                    s = {}
                    # 从第二行取对应values值
                    values = self.table.row_values(j)
                    for x in range(self.colNum):
                        s[self.keys[x]] = values[x]
                    r.append(s)
                    j += 1
                return r
    if __name__ == "__main__":
            filepath = "C:\Users\Administrator\Desktop\test.xlsx"
            sheetName = "Sheet1"
            data = ExcelUtil(filepath, sheetName)
            print(data.dict_data())
    

    执行结果:

    [{'username': '1358590672343543', 'password': '123412343434343'}, {'username': '13585906743345435', 'password': '12341234234343243'}, {'username': '1246879034343543543', 'password': '111111123434343'}]
    

    数据驱动

    一、环境准备
    1.安装ddt模块,打开cmd输入pip install ddt在线安装

    pip install ddt

    二、数据驱动原理
    1.测试数据为多个字典的list类型
    2.测试类前加修饰@ddt.ddt
    3.case前加修饰@ddt.data()
    4.运行后用例会自动加载成三个单独的用例

    #coding:utf-8
    import ddt
    import unittest
    testdata=[{"username":"selenium","psw":"23232323"},
              {"username": "python", "psw": "123"},
              {"username": "appium", "psw": "1234"}]
    @ddt.ddt
    class Test(unittest.TestCase):
        def setUp(self):
            print("start")
        def tearDown(self):
            print("end")
        @ddt.data(*testdata)
        def test_ddt(self,data):
            print(data)
    if __name__ == "__main__":
        unittest.main()
    

    执行结果:

    start
    {'username': 'selenium', 'psw': '23232323'}
    end
    start
    {'username': 'python', 'psw': '123'}
    end
    start
    {'username': 'appium', 'psw': '1234'}
    end
    Process finished with exit code 0
    

    例如:结合上次的读取excle数据,大家可以建立两个py文件,然后使用继承就可以了,下边的代码,我写在一起了,两个类写到一个文件里面了,大家自行拆分;

    #coding:utf-8
    import ddt
    import unittest
    from appium import webdriver
    import time
    import xlrd
    # 测试数据
    class ExcelUtil():
        def __init__(self, excelPath, sheetName):
            self.data = xlrd.open_workbook(excelPath)
            self.table = self.data.sheet_by_name(sheetName)
            # 获取第一行作为key值
            self.keys = self.table.row_values(0)
            # 获取总行数
            self.rowNum = self.table.nrows
            # 获取总列数
            self.colNum = self.table.ncols
    
        def dict_data(self):
            if self.rowNum <= 1:
                print("总行数小于1")
            else:
                r = []
                j = 1
                for i in range(self.rowNum - 1):
                    s = {}
                    # 从第二行取对应values值
                    values = self.table.row_values(j)
                    for x in range(self.colNum):
                        s[self.keys[x]] = values[x]
                    r.append(s)
                    j += 1
                return r
    filepath = "C:\Users\Administrator\Desktop\test.xlsx"
    sheetName = "Sheet1"
    data = ExcelUtil(filepath, sheetName)
    testData = data.dict_data()
    @ddt.ddt
    class Bolg(unittest.TestCase,):
        u'''登录博客'''
        def setUp(self):
            self.driver = webdriver.Chrome()
            url = "https://passport.cnblogs.com/user/signin"
            self.driver.get(url)
            self.driver.implicitly_wait(30)
        def login(self, username, psw):
            u'''这里写了一个登录的方法,账号和密码参数化'''
            self.driver.find_element_by_id("input1").send_keys(username)
            self.driver.find_element_by_id("input2").send_keys(psw)
            self.driver.find_element_by_id("signin").click()
            time.sleep(3)
    
        def is_login_sucess(self):
            u'''判断是否获取到登录账户名称'''
            try:
                text = self.driver.find_element_by_id("lnk_current_user").text
                print(text)
                return True
            except:
                return False
        @ddt.data(*testData)
        def test_login(self, data):
            u'''登录案例参考'''
            print("当前测试数据%s" % data)
            # 调用登录方法
            self.login(data["username"], data["password"])
            # 判断结果
            result = self.is_login_sucess()
            self.assertTrue(result)
        def tearDown(self):
            self.driver.quit()
    
    if __name__ == "__main__":
        unittest.main()
    

    连接mysql数据库:

    #!/usr/bin/env python
    # coding=utf-8
    
    
    
    import os
    os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
    import MySQLdb
    mysql_info = {"host": '172.17.1.175',
                  "port": 3306,
                  "user": 'xzdba',
                  "passwd": 'zaq1_XSW2',
                  "db": 'mysql',
                  "charset": 'utf8'}
    class MysqlUtil():
        '''
        mysql数据库相关操作
        连接数据库信息:mysql_info
        创建游标:mysql_execute
        查询某个字段对应的字符串:mysql_getstring
        查询一组数据:mysql_getrows
        关闭mysql连接:mysql_close'''
        def __init__(self):
            self.db_info = mysql_info
            u'''连接池方式'''
            self.conn = MysqlUtil.__getConnect(self.db_info)
    
        @staticmethod
        def __getConnect(db_info):
            '''
        静态方法,从连接池中取出连接
        '''
            try:
                conn = MySQLdb.connect(host=db_info['host'],
                                       port=db_info['port'],
                                       user=db_info['user'],
                                       passwd=db_info['passwd'],
                                       db=db_info['db'],
                                       charset=db_info['charset'])
                return conn
            except Exception as a:
                print("数据库连接异常:%s" % a)
    
        def mysql_execute(self, sql):
            '''执行sql语句'''
            cur = self.conn.cursor()
            try:
                cur.execute(sql)
            except Exception as a:
                self.conn.rollback()# sql执行异常后回滚
                # print("执行SQL语句出现异常:%s" % a)
            else:
                cur.close()
                self.conn.commit()# sql无异常时提交
    
        def mysql_getrows(self, sql):
            ''' 返回查询结果'''
            cur = self.conn.cursor()
            try:
                cur.execute(sql)
            except Exception as a:
                print("执行SQL语句出现异常:%s" % a)
            else:
                rows = cur.fetchall()
                cur.close()
                return rows
    
        def mysql_getstring(self, sql):
            '''查询某个字段的对应值'''
            rows = self.mysql_getrows(sql)
            if rows != None:
                for row in rows:
                    for i in row:
                        return i
        def mysql_close(self):
            ''' 关闭 close mysql'''
            try:
                self.conn.close()
            except Exception as a:
                print("数据库关闭时异常:%s" % a)
        # MySQLdb.connect()     建立数据库连接
        # cur = conn.cursor()    #通过获取到的数据库连接conn下的cursor()方法来创建游标。
        # cur.execute()    #过游标cur 操作execute()方法可以写入纯sql语句。通过execute()方法中写如sql语句来对数据进行操作。
        # cur.close()     # cur.close() 关闭游标
        # conn.commit()   # conn.commit()方法在提交事物,在向数据库插入(或update)一条数据时必须要有这个方法,否则数据不会被真正的插入。
        # conn.rollback() # 发生错误时候回滚
        # conn.close()     # Conn.close()关闭数据库连接
    if __name__ == "__main__":
        mysql = MysqlUtil()
        sql = "SELECT * FROM xxx  where ID = 'xxx'"
        mysql.mysql_execute(sql)
        print(mysql.mysql_getrows(sql))
        print(mysql.mysql_getstring(sql))
        mysql.mysql_close()
    

    执行发送邮件:

    先上代码,大家或者可以查看我们的selenium的测试的发送邮件的文章:
    发送邮件的资料

    #!/usr/bin/env python
    # coding=utf-8
    import unittest
    import os
    import HTMLTestRunner
    import time
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    import smtplib
    
    
    ####下面三行代码python2报告出现乱码时候可以加上####
    # import sys
    #
    # reload(sys)
    # sys.setdefaultencoding('utf8')
    
    
    # 这个是优化版执行所有用例并发送报告,分四个步骤
    # 第一步加载用例
    # 第二步执行用例
    # 第三步获取最新测试报告
    # 第四步发送邮箱 (这一步不想执行的话,可以注释掉最后面那个函数就行)
    
    def add_case(case_path, rule):
        u'''加载所有的用例'''
        testunit = unittest.TestSuite()
        # 定义discover方法参数
        discover = unittest.defaultTestLoader.discover(case_path,
                                                       pattern=rule,
                                                       top_level_dir=None)
        # discover方法筛选出来的用例,循环添加到测试套件中
        # for test_suite in discover:
        #      for test_case in test_suite:
        #          testunit.addTests(test_data)
        #          print testunit
        testunit.addTest(discover)  # 直接加载discover
        print(testunit)
        return testunit
    
    
    def run_case(all_case, report_path):
        u'''执行所有的用例, 并把结果写入测试报告'''
        now = time.strftime("%Y_%m_%d %H_%M_%S")
        report_abspath = os.path.join(report_path, now + "result.html")
        # report_abspath = "D:\web_project\report\"+now+"result.html"
        fp = open(report_abspath, "wb")
        runner = HTMLTestRunner.HTMLTestRunner(stream=fp,
                                               title=u'自动化测试报告,测试结果如下:',
                                               description=u'用例执行情况:')
        # 调用add_case函数返回值
        runner.run(all_case)
        fp.close()
    
    
    def get_report_file(report_path):
        u'''获取最新的测试报告'''
        lists = os.listdir(report_path)
        lists.sort(key=lambda fn: os.path.getmtime(os.path.join(report_path, fn)))
        print(u'最新测试生成的报告: ' + lists[-1])
        # 找到最新生成的报告文件
        report_file = os.path.join(report_path, lists[-1])
        return report_file
    
    
    def send_mail(sender, psw, receiver, smtpserver, report_file):
        u'''发送最新的测试报告内容'''
        # 读取测试报告的内容
        with open(report_file, "rb") as f:
            mail_body = f.read()
            # 定义邮件内容
        msg = MIMEMultipart()
        body = MIMEText(mail_body, _subtype='html', _charset='utf-8')
        msg['Subject'] = u"自动化测试报告"
        msg["from"] = sender
        msg["to"] = receiver
        # 加上时间戳
        #  msg["date"] = time.strftime('%a, %d %b %Y %H_%M_%S %z')
        msg.attach(body)
        # 添加附件
        att = MIMEText(open(report_file, "rb").read(), "base64", "utf-8")
        att["Content-Type"] = "application/octet-stream"
        att["Content-Disposition"] = 'attachment; filename= "report.html"'
        msg.attach(att)
        # 登录邮箱
        smtp = smtplib.SMTP()
        # 连接邮箱服务器
        smtp.connect(smtpserver)
        # 用户名密码
        smtp.login(sender, psw)
        smtp.sendmail(sender, receiver, msg.as_string())
        smtp.quit()
        print('test report email has send out !')
    
    
    if __name__ == "__main__":
        # 测试用例的路径、匹配规则
        case_path = "G:\apptoefl\t_toefl\test_data"
        rule = "test*.py"
        all_case = add_case(case_path, rule)  # 1加载用例
        # 生成测试报告的路径
        report_path = "G:\apptoefl\t_toefl\test_report"
        run_case(all_case, report_path)  # 2执行用例
        # 获取最新的测试报告文件
        report_file = get_report_file(report_path)  # 3获取最新的测试报告
        # 邮箱配置
        sender = "***"
        psw = "*****"
        # 收件人多个时,中间用逗号隔开,如'a@xx.com,b@xx.com'
        receiver = "****"
        smtp_server = 'smtp.exmail.qq.com'
        send_mail(sender, psw, receiver, smtp_server, report_file)#4最后一步发送报告,需要发邮件就取消注释
    

    如上图:有发送邮件,加载用例,生成最新的报告,添加附件等等方法,大家可以自行套用;(具体的邮箱配置,可以参考链接里面的邮箱配置,的说明)

  • 相关阅读:
    idea vue.js插件安装
    vue.js 开发环境配置
    Stream grouping-storm的流分组策略
    Kafka web console安装
    call 方法 (Function) (JavaScript)
    bind 方法 (Function) (JavaScript)
    CSS选择器、优先级和常用的选择器
    CSS3.0盒子模型:display:-webkit-box
    有了自己的博客了
    Javascript进阶篇——(DOM—节点---获取浏览器窗口可视区域大小+获取网页尺寸)—笔记整理
  • 原文地址:https://www.cnblogs.com/surewing/p/9585317.html
Copyright © 2011-2022 走看看