Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集

系统 1141 0

简介

生活中的日志是记录你生活的点点滴滴,让它把你内心的世界表露出来,更好的诠释自己的内心世界,而电脑里的日志是有价值的信息宝库。

日志文件是专门用于记录系统操作事件的记录文件或文件集合,操作系统有操作系统日志文件,数据库系统有数据库系统日志文件,等等。

系统日志文件是包含关于系统消息的文件,包括内核、服务、在系统上运行的应用程序等。不同的日志文件记载不同的信息。例如,有的是默认的系统日志文件,有的记载特定任务。

在数据库中用事务日志文件记录数据的修改操作,其中的每条日志记录或者记录所执行的逻辑操作,或者记录已修改数据的前像和后像。前像是操作执行前的数据复本;后像是操作执行后的数据复本。

问题思考

在自动化脚本运行过程中, IDE控制台一般都会输出运行日志。但是如果测试项目是在liunx服务器上面运行,没有IDE控制台输出log,那么我们该如何采集日志? 元芳,你怎么看?

Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第1张图片       Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第2张图片   

日志概述

日志作用

不管是在项目开发还是测试过程中,项目运行一旦出现问题日志信息就非常重要了。日志是定位问题的重要手段,就像侦探人员要根据现场留下的线索来推断案情。

日志级别

脚本运行会有很多的情况,比如调试信息、报错异常信息等。日志要根据这些不同的情况来继续分级管理,不然对于排查问题的筛选会有比较大的干扰。 。日志一般定位的级别如下:

 

级别

何时使用

DEBUG

调试信息,也是最详细的日志信息。

INFO

证明事情按预期工作。

WARNING

表明发生了一些意外,或者不久的将来会发生问题(如‘磁盘满了’)。软件还是在正常工作。

ERROR

由于更严重的问题,软件已不能执行一些功能了。

CRITICAL

严重错误,表明软件已不能继续运行了。

首先我们日志需要按照 info、debug、error等级别来进行区分的。当然这个级别可以自己去设置。在一般的情况下我们普通的输出我们直接用info类型,调试的时候用debug类型,如果预计有错误时那么我们就需要用error类型的日志,一般情况去info级别最为合适。

日志格式

日志格式化是为了提高日志的可阅读性,比如: 时间 +模块+行数+日志具体信息  的内容格式。如果日志信息杂乱无章的全部输出来,这样也不利于定位问题。如下所示就是日志格式化输出,非常便于阅读查看。

            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              22
            
            :
            
              02
            
            :
            
              35
            
            ,
            
              633
            
             backup.py[line:
            
              18
            
            ] INFO ============test backup================


            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              22
            
            :
            
              02
            
            :
            
              39
            
            ,
            
              253
            
             backup.py[line:
            
              20
            
            
              ] INFO click backup button


            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              22
            
            :
            
              02
            
            :
            
              54
            
            ,
            
              025
            
             backup.py[line:
            
              23
            
            
              ] INFO click next button


            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              22
            
            :
            
              03
            
            :
            
              09
            
            ,
            
              280
            
             common_fun.py[line:
            
              83
            
            
              ] INFO Start send Email..


            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              22
            
            :
            
              03
            
            :
            
              11
            
            ,
            
              840
            
             common_fun.py[line:
            
              91
            
            ] INFO Send Email finish!


            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              22
            
            :
            
              03
            
            :
            
              13
            
            ,
            
              305
            
             common_fun.py[line:
            
              168
            
            ] INFO 
            
              get
            
            
               backup screenshot


            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              23
            
            :
            
              36
            
            :
            
              00
            
            ,
            
              238
            
             backup.py[line:
            
              17
            
            ] INFO ============test backup================


            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              23
            
            :
            
              36
            
            :
            
              04
            
            ,
            
              530
            
             backup.py[line:
            
              19
            
            
              ] INFO click backup button


            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              23
            
            :
            
              37
            
            :
            
              20
            
            ,
            
              107
            
             backup.py[line:
            
              17
            
            ] INFO ============test
          

日志位置

一个项目中会有很多的日志采集点,而日志采集点必须结合业务属性来设置。比如在登录代码执行前可以插入 “准备登录..”日志信息,如果登录完成之后,再设置登录的提示日志就会给人造成误解,无法判断到底是登录之前的问题还是登录之后的问题,因此日志采集点的位置很重要。

logging模块

简介

Python的logging模块提供了通用的日志系统,这个模块提供不同的日志级别,并可以采用不同的方式记录日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己实现方式记录日志。

# 导入 logging 模块

import logging

logging模块官方文档

logging构成

logging模块包括 logger,Handler,Filter,Formatter 四个部分。

  • Logger 记录器,用于设置日志采集。
  • Handler 处理器,将日志记录发送至合适的路径。
  • Filter 过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。
  • Formatter 格式化器,指明了最终输出中日志的格式。

Logger 记录器

Logger是一个树形层级结构,在使用接口debug,info,warn,error,critical;使用之前必须创建Logger实例,即创建一个记录器,如果没有显式的进行创建,则默认创建一个root logger,并应用默认的日志级别(WARN),处理器Handler(StreamHandler,即将日志信息打印输出在标准输出上),和格式化器Formatter(默认的格式即为第一个简单使用程序中输出的格式)。

方法:

basicConfig(**kwargs) 为日志记录系统做基本配置。

部分参数

filename  指定日志文件名称

filemode   指定打开文件的模式,如果指定了 filename(如果文件模式未指定,则默认为'a)

Tips:文件读写模式

  • w 以写方式打开,
  • W 文件若存在,首先要清空,然后(重新)创建
  • a 以追加模式打开 (从 EOF 开始, 必要时创建新文件)
  • r+ 以读写模式打开
  • w+ 以读写模式打开 (参见 w )
  • a+ 以读写模式打开 (参见 a )

format  为处理程序使用指定的格式字符串。

datefmt   使用指定的日期 /时间格式。样式如果指定了格式字符串,则使用它来指定 格式字符串的类型.

level  将根记录器级别设置为指定级别。

logging_test.py

            # coding=utf-
            
              8
            
            
              
# 
            
            
              1
            
            .先设置编码,utf-
            
              8可支持中英文,如上,一般放在第一行

# 
            
            
              2
            
            
              .注释:包括记录创建时间,创建人,项目名称。

            
            
              '''

            
            Created on 
            
              2019
            
            -
            
              8
            
            -
            
              14
            
            
              
@author: 北京
            
            -宏哥   QQ交流群:
            
              707699217
            
            
              
Project:学习和使用appium自动化测试
            
            -代码和数据分离-
            
              日志收集

            
            
              '''

            
            # 
            
              3
            
            
              .导入模块

import  logging
# logging.basicConfig(level
            
            =
            
              logging.DEBUG)
logging.basicConfig(level
            
            =
            
              logging.INFO)

logging.debug(
            
            
              '
            
            
              debug info
            
            
              '
            
            
              )
logging.info(
            
            
              '
            
            
              hello 宏哥
            
            
              '
            
            
              )
logging.warning(
            
            
              '
            
            
              warning info
            
            
              '
            
            
              )
logging.error(
            
            
              '
            
            
              error info
            
            
              '
            
            
              )
logging.critical(
            
            
              '
            
            
              critical info
            
            
              '
            
            )
          

Handler 处理器

Handler 处理器,将日志记录发送至合适的路径,Handler处理器类型有很多种,比较常用的有三个:

1.StreamHandler

将日志记录输出发送到诸如 sys.stdout,sys.stderr或任何类似文件流的对象。上面例子就是输出到控制台

2.FileHandler

将日志记录输出发送到磁盘文件。 它继承了 StreamHandler的输出功能。

            logging.basicConfig(filename=
            
              '
            
            
              runlog.log
            
            
              '
            
            ,level=logging.DEBUG)
          

3.NullHandler

不做任何格式化或输出。 它本质上是一个开发人员使用的 “无操作”处理程序。

Filter 过滤器

Handlers和Loggers可以使用Filters来完成比级别更复杂的过滤。

Formatter

使用 Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S。

格式

描述

%(levelno)s

打印日志级别的数值

%(levelname)s

打印日志级别名称

%(pathname)s

打印当前执行程序的路径

%(filename)s

打印当前执行程序名称

%(funcName)s

打印日志的当前函数

%(lineno)d

打印日志的当前行号

%(asctime)s

打印日志的时间

%(thread)d

打印线程id

%(threadName)s

打印线程名称

%(process)d

打印进程ID

%(message)s

打印日志信息

使用方法:

            logging.basicConfig(filename=
            
              '
            
            
              runlog.log
            
            
              '
            
            ,level=
            
              logging.DEBUG,

                  format
            
            =
            
              '
            
            
              %(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
            
            
              '
            
            )               
          

输出结果:

            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              14
            
            :
            
              35
            
            :
            
              19
            
            ,
            
              430
            
             logging_test.py[line:
            
              6
            
            
              ]DEBUGdebug info

            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              14
            
            :
            
              35
            
            :
            
              19
            
            ,
            
              430
            
             logging_test.py[line:
            
              7
            
            
              ]INFOhello hongge

            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              14
            
            :
            
              35
            
            :
            
              19
            
            ,
            
              430
            
             logging_test.py[line:
            
              8
            
            
              ]WARNINGwarning info

            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              14
            
            :
            
              35
            
            :
            
              19
            
            ,
            
              430
            
             logging_test.py[line:
            
              9
            
            
              ]ERRORerror info

            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              14
            
            :
            
              35
            
            :
            
              19
            
            ,
            
              430
            
             logging_test.py[line:
            
              10
            
            ]CRITICALcritical info
          

Logging实战操作

测试场景

将前面所学的启动考研帮 App的脚本增加log采集功能,设置指定的日志格式输出,并将日志保存到指定文件。

代码实现

kyb_logger.py

            # coding=utf-
            
              8
            
            
              
# 
            
            
              1
            
            .先设置编码,utf-
            
              8可支持中英文,如上,一般放在第一行

# 
            
            
              2
            
            
              .注释:包括记录创建时间,创建人,项目名称。

            
            
              '''

            
            Created on 
            
              2019
            
            -
            
              8
            
            -
            
              14
            
            
              
@author: 北京
            
            -宏哥   QQ交流群:
            
              707699217
            
            
              
Project:学习和使用appium自动化测试
            
            -代码和数据分离-
            
              日志收集

            
            
              '''

            
            # 
            
              3
            
            
              .导入模块

            
            
              from
            
            
               appium import webdriver
import yaml
import logging

            
            
              from
            
            
               selenium.common.exceptions import NoSuchElementException

file
            
            =open(
            
              '
            
            
              ./desired_caps.yaml
            
            
              '
            
            ,
            
              '
            
            
              r
            
            
              '
            
            
              )
data
            
            =
            
              yaml.load(file)

logging.basicConfig(level
            
            =logging.INFO,filename=
            
              '
            
            
              runlog.log
            
            
              '
            
            
              ,
                    format
            
            =
            
              '
            
            
              %(asctime)s %(filename)s[line:%(lineno)d]%(levelname)s%(message)s
            
            
              '
            
            
              )

desired_caps
            
            =
            
              {}
desired_caps[
            
            
              '
            
            
              platformName
            
            
              '
            
            ]=data[
            
              '
            
            
              platformName
            
            
              '
            
            
              ]
desired_caps[
            
            
              '
            
            
              platformVersion
            
            
              '
            
            ]=data[
            
              '
            
            
              platformVersion
            
            
              '
            
            
              ]
desired_caps[
            
            
              '
            
            
              deviceName
            
            
              '
            
            ]=data[
            
              '
            
            
              deviceName
            
            
              '
            
            
              ]

desired_caps[
            
            
              '
            
            
              app
            
            
              '
            
            ]=data[
            
              '
            
            
              app
            
            
              '
            
            
              ]
desired_caps[
            
            
              '
            
            
              appPackage
            
            
              '
            
            ]=data[
            
              '
            
            
              appPackage
            
            
              '
            
            
              ]
desired_caps[
            
            
              '
            
            
              appActivity
            
            
              '
            
            ]=data[
            
              '
            
            
              appActivity
            
            
              '
            
            
              ]
desired_caps[
            
            
              '
            
            
              noReset
            
            
              '
            
            ]=data[
            
              '
            
            
              noReset
            
            
              '
            
            
              ]

logging.info(
            
            
              '
            
            
              start app...
            
            
              '
            
            
              )
driver
            
            =webdriver.Remote(
            
              '
            
            
              http://
            
            
              '
            
            +str(data[
            
              '
            
            
              ip
            
            
              '
            
            ])+
            
              '
            
            
              :
            
            
              '
            
            +str(data[
            
              '
            
            
              port
            
            
              '
            
            ])+
            
              '
            
            
              /wd/hub
            
            
              '
            
            
              ,desired_caps)

def check_cancelBtn():
    logging.info(
            
            
              '
            
            
              check cancelBtn
            
            
              '
            
            
              )

    
            
            
              try
            
            
              :
        cancelBtn 
            
            = driver.find_element_by_id(
            
              '
            
            
              android:id/button2
            
            
              '
            
            
              )
    except NoSuchElementException:
        logging.info(
            
            
              '
            
            
              no cancelBtn
            
            
              '
            
            
              )
    
            
            
              else
            
            
              :
        cancelBtn.click()

def check_skipBtn():
    logging.info(
            
            
              '
            
            
              check skipBtn
            
            
              '
            
            
              )

    
            
            
              try
            
            
              :
        skipBtn 
            
            = driver.find_element_by_id(
            
              '
            
            
              com.tal.kaoyan:id/tv_skip
            
            
              '
            
            
              )
    except NoSuchElementException:
        logging.info(
            
            
              '
            
            
              no skipBtn
            
            
              '
            
            
              )
    
            
            
              else
            
            
              :
        skipBtn.click()

check_cancelBtn()
check_skipBtn()
            
          

runlog.log

            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              15
            
            :
            
              27
            
            :
            
              38
            
            ,
            
              964
            
             kyb_logger.py[line:
            
              32
            
            
              ]INFOstart app...

            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              15
            
            :
            
              27
            
            :
            
              47
            
            ,
            
              641
            
             poolmanager.py[line:
            
              358
            
            ]INFORedirecting http:
            
              //
            
            
              127.0.0.1:4723/wd/hub/session -> 
            
            
              http://127.0.0.1
            
            
              :4723/wd/hub/session/dfc8e7e7-71cc-4f0b-9aa6-5db0fdc98a84
            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              15
            
            :
            
              27
            
            :
            
              47
            
            ,
            
              644
            
             kyb_logger.py[line:
            
              36
            
            
              ]INFOcheck cancelBtn

            
            
              2019
            
            -
            
              08
            
            -
            
              14
            
            
              15
            
            :
            
              27
            
            :
            
              49
            
            ,
            
              442
            
             kyb_logger.py[line:
            
              46
            
            ]INFOcheck skipBtn
          

问题思考

前面我们已经实现了在代码中增添 log,log也按照预期的采集到了,看似一切完美无瑕。但是该log配置的作用域也只是控制当前的脚本 。 然而一个自动化项目中通常有很多模块脚本,难道我们需要每一个脚本都这样配置吗? 元芳,你怎么看?

Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第3张图片   Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第4张图片

解决思路

回大人,以我跟随大人多年的断案经验: 将这些日志配置的参数抽离出来,各个模块需要使用则直接引用即可。

Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第5张图片

日志格式配置

log输出格式,输出路径等参数抽离出来作为一个配置表,如下所示:

log.conf

            
              [loggers]
keys
            
            =
            
              root,infoLogger

[logger_root]
level
            
            =
            
              DEBUG
handlers
            
            =
            
              consoleHandler,fileHandler

[logger_infoLogger]
handlers
            
            =
            
              consoleHandler,fileHandler
qualname
            
            =
            
              infoLogger
propagate
            
            =
            
              0
            
            
              

[handlers]
keys
            
            =
            
              consoleHandler,fileHandler

[handler_consoleHandler]

            
            
              class
            
            =
            
              StreamHandler
level
            
            =
            
              INFO
formatter
            
            =
            
              form02
args
            
            =
            
              (sys.stdout,)

[handler_fileHandler]

            
            
              class
            
            =
            
              FileHandler
level
            
            =
            
              INFO
formatter
            
            =
            
              form01
args
            
            =(
            
              '
            
            
              runlog.log
            
            
              '
            
            , 
            
              '
            
            
              a
            
            
              '
            
            
              )

[formatters]
keys
            
            =
            
              form01,form02

[formatter_form01]
format
            
            =%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %
            
              (message)s

[formatter_form02]
format
            
            =%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
          

在需要调用的模块增加如下代码:

            
              import logging

import logging.config



CON_LOG
            
            =
            
              '
            
            
              log.conf
            
            
              '
            
            
              

logging.config.fileConfig(CON_LOG)

logging
            
            =logging.getLogger()
          

方法:

            fileConfig(fname, defaults=None, disable_existing_loggers=True)
          

该放在作用是从 ConfigParser格式的文件中读取日志配置,同时如果当前脚本有配置log参数,则覆盖当前log配置选项。

代码实现

kyb_logconf.py

            # coding=utf-
            
              8
            
            
              
# 
            
            
              1
            
            .先设置编码,utf-
            
              8可支持中英文,如上,一般放在第一行

# 
            
            
              2
            
            
              .注释:包括记录创建时间,创建人,项目名称。

            
            
              '''

            
            Created on 
            
              2019
            
            -
            
              8
            
            -
            
              14
            
            
              
@author: 北京
            
            -宏哥   QQ交流群:
            
              707699217
            
            
              
Project:学习和使用appium自动化测试
            
            -代码和数据分离-
            
              日志收集

            
            
              '''

            
            # 
            
              3
            
            
              .导入模块

            
            
              from
            
            
               appium import webdriver
import yaml
import logging
import logging.config

            
            
              from
            
            
               selenium.common.exceptions import NoSuchElementException

file
            
            =open(
            
              '
            
            
              ./desired_caps.yaml
            
            
              '
            
            ,
            
              '
            
            
              r
            
            
              '
            
            
              )
data
            
            =
            
              yaml.load(file)

CON_LOG
            
            =
            
              '
            
            
              log.conf
            
            
              '
            
            
              
logging.config.fileConfig(CON_LOG)
logging
            
            =
            
              logging.getLogger()

desired_caps
            
            =
            
              {}
desired_caps[
            
            
              '
            
            
              platformName
            
            
              '
            
            ]=data[
            
              '
            
            
              platformName
            
            
              '
            
            
              ]
desired_caps[
            
            
              '
            
            
              platformVersion
            
            
              '
            
            ]=data[
            
              '
            
            
              platformVersion
            
            
              '
            
            
              ]
desired_caps[
            
            
              '
            
            
              deviceName
            
            
              '
            
            ]=data[
            
              '
            
            
              deviceName
            
            
              '
            
            
              ]

desired_caps[
            
            
              '
            
            
              app
            
            
              '
            
            ]=data[
            
              '
            
            
              app
            
            
              '
            
            
              ]
desired_caps[
            
            
              '
            
            
              appPackage
            
            
              '
            
            ]=data[
            
              '
            
            
              appPackage
            
            
              '
            
            
              ]
desired_caps[
            
            
              '
            
            
              appActivity
            
            
              '
            
            ]=data[
            
              '
            
            
              appActivity
            
            
              '
            
            
              ]
desired_caps[
            
            
              '
            
            
              noReset
            
            
              '
            
            ]=data[
            
              '
            
            
              noReset
            
            
              '
            
            
              ]

logging.info(
            
            
              '
            
            
              start app...
            
            
              '
            
            
              )
driver
            
            =webdriver.Remote(
            
              '
            
            
              http://
            
            
              '
            
            +str(data[
            
              '
            
            
              ip
            
            
              '
            
            ])+
            
              '
            
            
              :
            
            
              '
            
            +str(data[
            
              '
            
            
              port
            
            
              '
            
            ])+
            
              '
            
            
              /wd/hub
            
            
              '
            
            
              ,desired_caps)

def check_cancelBtn():
    logging.info(
            
            
              '
            
            
              check cancelBtn
            
            
              '
            
            
              )

    
            
            
              try
            
            
              :
        cancelBtn 
            
            = driver.find_element_by_id(
            
              '
            
            
              android:id/button2
            
            
              '
            
            
              )
    except NoSuchElementException:
        logging.info(
            
            
              '
            
            
              no cancelBtn
            
            
              '
            
            
              )
    
            
            
              else
            
            
              :
        cancelBtn.click()

def check_skipBtn():
    logging.info(
            
            
              '
            
            
              check skipBtn
            
            
              '
            
            
              )

    
            
            
              try
            
            
              :
        skipBtn 
            
            = driver.find_element_by_id(
            
              '
            
            
              com.tal.kaoyan:id/tv_skip
            
            
              '
            
            
              )
    except NoSuchElementException:
        logging.info(
            
            
              '
            
            
              no skipBtn
            
            
              '
            
            
              )
    
            
            
              else
            
            
              :
        skipBtn.click()

check_cancelBtn()
check_skipBtn()
            
          

 小结

元芳,今天分享的知识快要结束,你给总结一下,把结案文书写一下,交给我。元芳,你怎么看?日志的收集。

Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第6张图片

 好了好了,大人,元芳今天太累了,所以说出如此大逆不道的话,求大人原谅他,结案文书我稍后交给大人。

结案文书:

1.Logger是一个树形层级结构

Logger可以包含一个或多个Handler和Filter,即Logger与Handler或Fitler是一对多的关系;
一个Logger实例可以新增多个Handler,一个Handler可以新增多个格式化器或多个过滤器,而且日志级别将会继承。

Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第7张图片

 

 

2.Logging工作流程

logging模块使用过程

  1. 第一次导入logging模块或使用reload函数重新导入logging模块,logging模块中的代码将被执行,这个过程中将产生logging日志系统的默认配置。
  2. 自定义配置(可选)。logging标准模块支持三种配置方式: dictConfig,fileConfig,listen。其中,dictConfig是通过一个字典进行配置Logger,Handler,Filter,Formatter;fileConfig则是通过一个文件进行配置;而listen则监听一个网络端口,通过接收网络数据来进行配置。当然,除了以上集体化配置外,也可以直接调用Logger,Handler等对象中的方法在代码中来显式配置。
  3. 使用logging模块的全局作用域中的getLogger函数来得到一个Logger对象实例(其参数即是一个字符串,表示Logger对象实例的名字,即通过该名字来得到相应的Logger对象实例)。
  4. 使用Logger对象中的debug,info,error,warn,critical等方法记录日志信息。
Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第8张图片

 

您的肯定就是我进步的动力。 如果你感觉还不错,就请鼓励一下吧!记得点波  推荐  哦!!!(点击右边的小球即可!( ^__^ ) 嘻嘻……)
Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第9张图片

       个人公众号                                                              微信群  (微信群已满100,可以加宏哥的微信拉你进群,请备注:进群)          

Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第10张图片                                                                   Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)_第11张图片

 

 

 


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论