python接口自动化-实战(第三阶段)

目标

  • 完成手机号码初始化操作:修改excel(对于需要唯一数据的场景,比如注册场景)

    • 第一种操作:利用excel设置初始化手机号码,每次进行+1操作,以及变量替换。记得做数据演示
    • 第二种操作:每次从数据库里面查询最大的手机号码,在这个基础上+1
    • 第三种操作:每次清除这个手机号相关的数据,进行垃圾数据重置操作
    • 当前时间戳生成手机号码
    • 参数替换完成 ${变量名}
  • 学习logging:引入日志模块

初始化手机号

  • 测试数据的excel中新增一个sheet init

    image

  • get_data.py新增一个NoRegTel参数

    from project_path import *
    import pandas
    class GetData:
        access_token = None
        NoRegTel=(pandas.read_excel(test_data_path, sheet_name="init")).ix[0,0]
    
  • 在excel中使用变量

    把要使用唯一手机号的地方用${tel}替换

    image
  • 改造do_excel.py,当读到${tel}init中的手机号进行替换

    # encoding: utf-8
    from openpyxl import load_workbook
    import sys
    reload( sys )
    sys.setdefaultencoding('utf-8')
    from read_config import ReadConfig
    import project_path
    from get_data import GetData
    
    class DoExcel:
    
        @classmethod
        def get_data(cls,file_name):
            wb=load_workbook(file_name)
            mode=eval(ReadConfig.get_config(project_path.case_config_path,"MODE","mode"))
            #新增代码,读取excel中init的手机号,也可以直接读取excel
            tel=getattr(GetData,"NoRegTel")
            test_data=[]
            for key in mode:
                sheet=wb[key]
                if mode[key]=='all':
                    for i in range(2,sheet.max_row+1):
                        row_data={}
                        row_data["case_id"] = sheet.cell(i, 1).value
                        row_data["url"]=sheet.cell(i,2).value
                        row_data["method"]=sheet.cell(i,3).value
                        #新增代码,判断body参数中是否有变量${tel}
                        if sheet.cell(i,4).value.find("${tel}")!=-1:
                            row_data["payload"] = sheet.cell(i, 4).value.replace("${tel}",str(tel))
                            tel = tel + 1
                        else:
                            row_data["payload"]=sheet.cell(i,4).value
                        row_data["title"]=sheet.cell(i,5).value
                        row_data["expected"] = sheet.cell(i, 6).value
                        row_data["sheet_name"]=key
                        test_data.append(row_data)
                        #将使用后的tel+1重新写到init,保证每次用到都是新的
                        cls.update_tel(tel,file_name,'init')
                else:
                    for case_id in mode[key]:
                        row_data = {}
                        row_data["case_id"] = sheet.cell(case_id+1, 1).value
                        row_data["url"] = sheet.cell(case_id+1, 2).value
                        row_data["method"] = sheet.cell(case_id+1, 3).value
                        if sheet.cell(case_id+1, 4).value.find("${tel}") != -1:
                            row_data["payload"] = sheet.cell(case_id+1, 4).value.replace("${tel}", str(tel))
                            tel=tel+1
                        else:
                            row_data["payload"] = sheet.cell(case_id+1, 4).value
                        row_data["title"] = sheet.cell(case_id+1, 5).value
                        row_data["expected"] = sheet.cell(case_id+1, 6).value
                        row_data["sheet_name"] = key
                        test_data.append(row_data)
                        cls.update_tel(tel, file_name, 'init')
    
            return test_data
    
        @staticmethod
        def write_back_data(file_name,sheet_name,i,result,TestResult):
            wb=load_workbook(file_name)
            sheet=wb[sheet_name]
            sheet.cell(i,7).value=result
            sheet.cell(i,8).value=TestResult
            wb.save(file_name) #保存
    
        #新增代码,新增更新手机号的方法
        @classmethod
        def update_tel(cls,tel,file_name,sheet_name):
            """更新手机号"""
            wb = load_workbook(file_name)
            sheet = wb[sheet_name]
            sheet.cell(2,1).value=tel
            wb.save(file_name)
    
    

引入日志模块

  • logging是什么?作用是什么?

    logging是python自带的一个日志模块

  • 作用:

    • 代替print,可以把大部分你想要进行调试的信息打印出来或者输出到指定文件。
    • 可以对一些输出的调试信息分类做输出,比如说:DEBUG、INFO、WARNING、ERROR、CRITICAL
  • logging默认日志级别:NOTSET、DEBUG、INFO、WARNING、ERROR、CRITICAL;测试使用INFO和ERROR够用

  • 日志想要输出的两道门槛

    • logger 收集日志,收集指定级别的日志,如指定收集DEBUG、INFO、ERROR
    • handdler 输出日志,输出收集的日志到指定的文件,不设置文件默认到控制台
  • 示例

    import logging
    logging.debug("今天天气真好")
    logging.info("今天天气有点差")
    logging.warning("马上就是大佬")
    logging.error("有人是金牛座")
    logging.critical("发现什么问题了")
    

    控制台输出:


    image
    • 默认输出warning及以上级别的日志
    • root是日志收集器的名字
  • 自定义日志

    #输出渠道是控制台
    
    import logging
    
    #定义一个日志收集器
    my_logger=logging.getLogger("new")
    
    #设定收集的级别,不设定的话,默认收集warning及以上级别的日志
    my_logger.setLevel("DEBUG")
    
    #创建一个自己的输出渠道(输出也要设定级别,否则也是默认输出warning及以上级别的日志)
    ch=logging.StreamHandler()
    ch.setLevel("DEBUG")
    
    #将收集和输出对接,指定输出渠道
    my_logger.addHandler(ch)
    
    #收集日志
    my_logger.debug("自己定义的debug日志")
    my_logger.info("自己定义的info日志")
    my_logger.warning("自己定义的warning日志")
    my_logger.error("自己定义的error日志")
    my_logger.critical("自己定义的critical日志")
    

    控制台输出:

    image
    #输出渠道是文件
    
    import logging
    import sys
    reload( sys )
    sys.setdefaultencoding('utf-8')
    
    #定义一个日志收集器
    my_logger=logging.getLogger("new")
    
    #设定收集的级别,不设定的话,默认收集warning及以上级别的日志
    my_logger.setLevel("DEBUG")
    
    #创建输出渠道-输出到文件
    fh=logging.FileHandler("20191005log.txt",encoding="UTF-8")
    #设定输出日志的级别
    fh.setLevel("INFO")
    
    #将收集和输出对接
    my_logger.addHandler(fh)
    
    #收集日志
    my_logger.debug("自己定义的debug日志")
    my_logger.info("自己定义的info日志")
    my_logger.warning("自己定义的warning日志")
    my_logger.error("自己定义的error日志")
    my_logger.critical("自己定义的critical日志")
    

    日志文件:

    image

    ps:python2.7 报错'ascii' codec can't decode byte 0xe8 in position 0,添加代码:

    import sys
    reload( sys )
    sys.setdefaultencoding('utf-8')
    
  • 日志格式 formatter

日志记录的最终输出格式,formatter对象定义了最终的log信息的顺序、结构和内容,规定了日志输出按照什么样的格式,默认的时间格式为%Y-%m-%d %H:%M:%S

常用格式:·formatter=logging.Formatter("%(asctime)s-%(levelname)s-%(filename)s-%(name)s-日志信息:%(massage)s")

#设定输出格式


import logging
import sys
reload( sys )
sys.setdefaultencoding('utf-8')

# 定义一个日志收集器
my_logger = logging.getLogger("new")

# 设定收集的级别,不设定的话,默认收集warning及以上级别的日志
my_logger.setLevel("DEBUG")

#新增,设定输出格式
formatter=logging.Formatter('%(asctime)s-%(levelname)s-%(filename)s-%(name)s-日志信息:%(message)s')

#输出到控制台
ch = logging.StreamHandler()
ch.setLevel("DEBUG")
    #新增,使用格式
ch.setFormatter(formatter)

#输出到文件
fh=logging.FileHandler("20191005log.txt",encoding="UTF-8")
fh.setLevel("INFO")
    #新增,使用格式
fh.setFormatter(formatter)

# 将收集和输出对接,指定输出渠道
my_logger.addHandler(ch)
my_logger.addHandler(fh)

# 收集日志
my_logger.debug("自己定义的debug日志")
my_logger.info("自己定义的info日志")
my_logger.warning("自己定义的warning日志")
my_logger.error("自己定义的error日志")
my_logger.critical("自己定义的critical日志")

输出:


image
  • 格式中的变量含义
image
image
  • 写为一个类-日志类

    import logging
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    from common.public.project_path import *
    
    class MyLog:
        def my_log(self,msg,level):
            # 定义一个日志收集器
            my_logger = logging.getLogger("my_log")
    
            # 设定收集的级别,不设定的话,默认收集warning及以上级别的日志
            my_logger.setLevel("DEBUG")
    
            # 设定输出格式
            formatter = logging.Formatter('%(asctime)s-%(levelname)s-%(filename)s-%(name)s-日志信息:%(message)s')
    
            # 输出到控制台
            ch = logging.StreamHandler()
            ch.setLevel("DEBUG")
            ch.setFormatter(formatter)
    
            # 输出到文件
            # 在project_path.py中新增一个log路径
            fh = logging.FileHandler(log_path, encoding="UTF-8")
            fh.setLevel("DEBUG")
            fh.setFormatter(formatter)
    
            # 将收集和输出对接,指定输出渠道
            my_logger.addHandler(ch)
            my_logger.addHandler(fh)
    
            # 收集日志
            if level=="DEBUG":
                my_logger.debug(msg)
            elif level=="INFO":
                my_logger.info(msg)
            elif level=="WARNING":
                my_logger.warning(msg)
            elif level=="ERROR":
                my_logger.error(msg)
            elif level=="CRITICAL":
                my_logger.critical(msg)
    
            #关闭渠道,否则会重复收集、重复输出
            my_logger.removeHandler(ch)
            my_logger.removeHandler(fh)
    
        def debug(self,msg):
            self.my_log(msg,"DEBUG")
    
        def info(self,msg):
            self.my_log(msg,"INFO")
    
        def warning(self,msg):
            self.my_log(msg,"WARNING")
    
        def error(self,msg):
            self.my_log(msg,"ERROR")
    
        def critical(self,msg):
            self.my_log(msg,"CRITICAL")
    
    if __name__ == '__main__':
        my_logger=MyLog()
        my_logger.debug("是啥")
        my_logger.error("是啥呢")
    
  • 使用日志类

    from common.public.my_log import MyLog
    my_logging=MyLog()
    

    把原来使用print的地方,修改为使用日志类

    #print
    print("测试用例失败{0}".format(e))
    #使用日志类
    my_logging.debug("测试用例失败{0}".format(e))
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,392评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,258评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,417评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,992评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,930评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,199评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,652评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,327评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,463评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,382评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,432评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,118评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,704评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,787评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,999评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,476评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,057评论 2 341

推荐阅读更多精彩内容

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 2,689评论 0 3
  • 再次强调,因为视频中实战地址已无法访问,建议大家根据原理,用自己公司的业务逻辑、代码来练手。本人公司使用pyhon...
    DayBreakL阅读 802评论 0 2
  • 常用模块 认识模块 什么是模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文...
    go以恒阅读 1,930评论 0 6
  • 本文参考自:https://www.cnblogs.com/Nicholas0707/p/9021672.html...
    handsomePeng阅读 1,393评论 1 4
  • 我是一名普普通通的高中女生,我有着爱我的妈妈和爷爷奶奶,我觉得自己很幸福,我很感恩我现在拥有的一切。 六岁那年...
    N1YuZ阅读 80评论 0 1