• Python+requests接口自动化完整项目框架整理笔记


    前言

    通过学习“上海悠悠”博客,自己手动敲了一遍整体的自动化项目搭建,编写用例,打印log日志,生成测试报告,将报告发送至邮箱整体流程跑了一遍,勉强跑通了

    一,项目结构

    --case:这个包放test开头的测试用例,也可以放一些封装接口的方法,如:LoginBlogs(如果封装的接口比较多,也可以单独放一个包)

    --common:这个包放一些公共的方法,如:读取excel文件方法,读取mysql、oracle,logger.py这个是封装日志的输入

    --config:config.ini这里是配置文件,如邮箱的一些参数:收件人,发件人,密码等,readConfig.py用于读取配置文件

    --logs:这里存放日志信息

    --report:这里存放测试报告

    二,run_main

    第一步:用discover方法加载所有的测试用例

    1.cur_path这个参数是读取当前这个脚本的真实路径,也就是run_main.py的真实路径

    2.caseName="case"这个case是存放测试用例的文件夹,如果没有的话,自动创建。如果想运行其它文件夹的用例,就改下caseName这个参数值

    3.rule="test*.py"这个是匹配用例脚本名称的规则,默认匹配test开头的所有用例

    其中有一些自己不明白的地方,如:

    cur_path=os.path.dirname(os.path.realpath(__file__)) 
    打印后显示:D:PyCharmhpliud (注:当前脚本所在hpliud这个项目的真实路径地址)
    case_path=os.path.join(cur_path,caseName)
    打印后显示:D:PyCharmhpliudcase (注:将上一步的cur_path获得的目录和case文件合成一个路径)
    discover=unittest.defaultTestLoader.discover(case_path,pattern=rule,top_level_dir=None)
    注:discover方法找到指定目录下所有测试模块,并可递归查到子目录下的测试模块,只有匹配到文件名时才加载(即加载D:PyCharmhpliudcase目录下所有test开头的py文件)

    第二步,生成HTML报告

    1.把上一步加载到用例的参数传入这个函数,测试报告的文件名称默认report文件夹:reportName="report"

    2.如果没有这个report文件夹也没关系,可以自动创建的

    a:
    fp=open(report_abspath,"wb")
    注:open() 函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写
    wb:以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
    b:
    runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u'自动化报告结果如下:',description=u'用例执行情况:')
    注:批量执行完用例后,生成的测试报告是文本形式的,不够直观,为了更好的展示测试报告,最好是生成HTML格式的;unittest里面是不能生成html格式报告的,需要导入一个第三方的模块:HTMLTestRunner(导入方法可参考第二篇文章)
    --stream:测试报告写入文件的存储区域
    --title:测试报告的主题
    --description:测试报告的描述

    c:
    python3中用HTMLTestRunner.py报ImportError: No module named 'StringIO'
    原因是官网的是python2语法写的,需手动把官网的HTMLTestRunner.py改成python3的语法执行就不会报错了:
    修改汇总:
    第94行,将import StringIO修改成import io
    第539行,将self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer = io.StringIO()
    第642行,将if not rmap.has_key(cls):修改成if not cls in rmap:
    第766行,将uo = o.decode('latin-1')修改成uo = e
    第775行,将ue = e.decode('latin-1')修改成ue = e
    第631行,将print >> sys.stderr, ' Time Elapsed: %s' % (self.stopTime-self.startTime)修改成print(sys.stderr, ' Time Elapsed: %s' % (self.stopTime-self.startTime))

    第三步,获取最新的测试报告

     

    1.如果第二步生成的测试报告加了时间戳,想找到最新的文件就用第三步

    2.如果第二步不加时间戳,只是生成result.html,那第三步其实没用,可以忽略

    (个人觉得报告用一个名称result.html就行,新的自动覆盖旧的,那么我们就来改造下第二步的函数)

    第四步,发送测试报告到邮箱 

    1.像QQ邮箱这种ssl加密的就走SMTP_SSL,用授权码登录

    2.其它邮箱就正常账号密码登录,走SMTP

    第五步,最后执行代码

     三,config配置

    1,在config文件夹下新建一个config.ini文件,输入邮箱相关配置项

    使用第三方SMTP发送,这里使用了 QQ 邮箱(你也可以使用 163,Gmail等)的 SMTP 服务,需要做以下配置:

    QQ 邮箱 SMTP 服务器地址:smtp.qq.com,ssl 端口:465

    2,用readConfig.py读取配置文件,读取的内容就是在第二步操作里面需要传的数据

    四,logger

    1.logger.py这个文件放到common目录下,封装日志文件的读取

    2.日志保存到logs文件夹

    3.封装代码

    此处贴出logger文件的源码,自己也没看太懂代码,直接拷贝的“上海悠悠”的代码

    # coding=utf-8
    import logging, time
    import os
    # log_path是存放日志的路径
    cur_path = os.path.dirname(os.path.realpath(__file__))
    log_path = os.path.join(os.path.dirname(cur_path), 'logs')
    # 如果不存在这个logs文件夹,就自动创建一个
    if not os.path.exists(log_path):os.mkdir(log_path)

    class Log():
    def __init__(self):
    # 文件的命名
    self.logname = os.path.join(log_path, '%s.log'%time.strftime('%Y_%m_%d'))
    self.logger = logging.getLogger()
    self.logger.setLevel(logging.DEBUG)
    # 日志输出格式
    self.formatter = logging.Formatter('[%(asctime)s] - %(filename)s] - %(levelname)s: %(message)s')

    def __console(self, level, message):
    # 创建一个FileHandler,用于写到本地
    fh = logging.FileHandler(self.logname, 'a') # 追加模式 这个是python2的
    # fh = logging.FileHandler(self.logname, 'a', encoding='utf-8') # 这个是python3的
    fh.setLevel(logging.DEBUG)
    fh.setFormatter(self.formatter)
    self.logger.addHandler(fh)

    # 创建一个StreamHandler,用于输出到控制台
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    ch.setFormatter(self.formatter)
    self.logger.addHandler(ch)

    if level == 'info':
    self.logger.info(message)
    elif level == 'debug':
    self.logger.debug(message)
    elif level == 'warning':
    self.logger.warning(message)
    elif level == 'error':
    self.logger.error(message)
    # 这两行代码是为了避免日志输出重复问题
    self.logger.removeHandler(ch)
    self.logger.removeHandler(fh)
    # 关闭打开的文件
    fh.close()

    def debug(self, message):
    self.__console('debug', message)

    def info(self, message):
    self.__console('info', message)

    def warning(self, message):
    self.__console('warning', message)

    def error(self, message):
    self.__console('error', message)

    if __name__ == "__main__":
    log = Log()
    log.info("---测试开始----")
    log.info("操作步骤1,2,3")
    log.warning("----测试结束----")

     五,case放用例

    常用的接口,需要检查被调用的单独封装处理,如登录等

    六,logs日志查看

    运行完成后日志就会在logs文件夹下生成

    七,生成测试报告

    这里调用的是HTMLTestRunner生成html的测试报告

     

    八,发送报告到邮箱

    运行run_main.py就会自动生成报告,然后发送到邮箱了

    关于整个项目的源码稍后会单独整理发出来

  • 相关阅读:
    Unity3D学习笔记(十九):UGUI、Image、Text、Button
    Unity3D学习笔记(十八):动画内容补充
    Unity3D学习笔记(十七):IK动画、粒子系统和塔防
    Unity3D学习笔记(十六):Animator新动画
    Unity3D学习笔记(十五):寻路系统
    Unity3D学习笔记(十四):Animation旧动画
    Unity3D学习笔记(十三):委托、考试复习
    Unity3D学习笔记(十二):2D模式和异步资源加载
    加密解密
    linux 常用命令
  • 原文地址:https://www.cnblogs.com/hpliud/p/10694468.html
Copyright © 2020-2023  润新知