An example analysis of python automatic test exception and log operation

An example of this paper describes the exception and log operation of python automatic test. To share with you for your reference, as follows:

In order to maintain the robustness of automated test cases, exception capture and handling, log recording is particularly important for mastering the execution of automated tests. Here, we will introduce the exceptions and logs used in automated tests in detail, and their detailed usage.

First, log

Printing log is an important requirement of many programs. Good log output can help us detect the running status of programs more conveniently. The Python standard library provides the logging module. Remember that the Logger is never instantiated directly. Its benefits are self-evident. Next, I will explain slowly that the logging module provides two ways to record logs.

Logging module level functional logging

import logging
#Set the log, including filename, level, format, filemode and stream. The format attribute is extremely rich. For details, please refer to the API document. Here is a brief introduction
logging.basicConfig(level = logging.INFO,
  format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
  datefmt = "%Y/%m%d %H%M%S",
  filename = "log.txt")
#Message level, level five
logging.debug("Qin zeduo") 
logging.info("really")
logging.warning("male")
logging.error("people")
logging.critical("!")

The four components of logging system (loggers, processors, filters, formatters) record logs

import logging
# Generating log instances, loggers
logger = logging.getLogger(__name__)
#Basic unit configuration (LEVER)
logger.setLevel(level = logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#Generate pipeline branch, processor
handler_1 = logging.FileHandler("log.txt")
handler_2 = logging.StreamHandler()
#Custom format, formatter
handler_1.setFormater(formatter, "%Y-%m-%d %H:%M:%S")
handler_2.setFormater(formatter, "%Y-%m-%d %H:%M:%S")
#Butt joint branch pipe and source, processor
logger.addHandler(handler_1)
logger.addHandler(handler_2)
#Hierarchy. The name of a logger is a hierarchy divided by '.', and the logger after each '.' is the children of the logger before '.', which is usually used with the filter
#Filter
#... Retain
#Start recording
logger.debug("Qin zeduo") 
logger.info("really")
logger.warning("male")
logger.error("people")
logger.critical("!")

Careful basin friends can also find that logging has a main object for log processing. Other processing methods are added through addHandler. Here, logging.StreamHandler is used to output logs to the stream (console) or FileHandler is used to output logs to the file
Log rollback

import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
#Define a RotatingFileHandler, backup up to 3 log files, each log file up to 1K
rHandler = RotatingFileHandler("log.txt",maxBytes = 1*1024,backupCount = 3)
rHandler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
rHandler.setFormatter(formatter)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)
logger.addHandler(rHandler)
logger.addHandler(console)
logger.debug("Qin zeduo") 
logger.info("really")
logger.warning("male")
logger.error("people")
logger.critical("!")

Multi module use

#Main module
import logging
import subModule
logger = logging.getLogger("mainModule")
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)
logger.addHandler(handler)
logger.addHandler(console)
#Sub module
import logging
module_logger = logging.getLogger("mainModule.sub")
class SubModuleClass(object):
  def __init__(self):
    self.logger = logging.getLogger("mainModule.sub.module")

Careful pen friends will find out again that it is very important to name the logger. First, the main module defines the logger 'mainModule' and configures it. The sub modules can share the definition and configuration of the parent logger. The so-called parent-child logger is identified by naming. Any logger starting with 'mainModule' is its child logger, for example, 'mainModule.sub'

 Recommend a python learning skirt: 233 @ @ 539 @ @ 995, which has a lot of learning materials to share

In fact, even though it has the function of inheriting configuration or user-defined configuration log, it is a little troublesome in large projects. Here, JSON or yaml are mainly used for configuration encapsulation. In this way, the log configuration can be loaded by loading the file, and the specific operations can be decomposed next time. The last instance is issued.

# -*- coding: utf-8 -*-
__author__ = 'Secret608'
import logging
import time
import os
import re
class Log(object):
  def __init__(self, loggerName):
      '''
      //Perform log initialization, including storage path, name, level, call file, etc
      '''
      #Basic attributes
      self.logger = logging.getLogger(loggerName)
      self.logger.setLevel(logging.WARNING)
      #Unique properties (file address + logging format)
      rq = time.strftime('%Y%m%d_%H%M%S', time.localtime(time.time()))
      log_path = os.path.join(os.path.dirname(os.getcwd()), 'logs')
      log_title = os.path.join(log_path, loggerName + '_'+ rq) + ".log"
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
      log = logging.FileHandler(log_title)
      log.setFormatter(formatter)
      #Add to the basic properties to get a complete initialization object
      self.logger.addHandler(log)
  def getLog(self):
    return self.logger
  def delLog(self, fileName):
    log_path = os.path.join(os.path.dirname(os.getcwd()), 'logs')
    regexp = re.compile('^'+fileName+'s.*')
    filelist = os.listdir(log_path)
    try:
      [os.remove(os.path.join(log_path, i)) for i in filelist if regexp.match(i) == None]
    except WindowsError:
      pass
    else:
      return "ok"
if __name__ == "__main__":
  a = Log("hah")
  a.delLog("hah")

Two, abnormal

Exception type
Built in Exception: Python's Exception handling ability is very powerful. It has many built-in exceptions, which can accurately feedback error information to users. In Python, exceptions are also objects that can be manipulated. BaseException is the base class of all built-in exceptions, but user-defined classes do not directly inherit BaseException. All Exception classes inherit from Exception and are defined in exceptions module.
Custom exception: you can create a new exception class to have your own exception. The exception should inherit from the exception class directly or indirectly. For example, a MyError class is created, and the base class is Exception, which is used to output more information when the exception is triggered.
Anomaly capture
When an exception occurs, we need to catch the exception, and then deal with it accordingly. python exception capture common try Except... Structure, put the possible wrong statements in the try module, and use exception to handle exceptions. Each try must correspond to at least one exception. In addition, the key words related to python exception are try/except, pass, as (define exception instance), else, finally, raise.
Catch all exceptions:

# -*- coding: utf-8 -*-
#Syntax for exception handling:
try: 
  #Execute statements with possible exceptions
except 'Abnormal name': 
  #Statement executed abnormally
else: 
  #Execute the statement without exception
finally:
  #Statement executed with exception or not
#demo
try:
  a = 0
  b = 1
  c = b/a
  print(c)
except ZeroDivisionError:
  print("Denominator cannot be 0")
except NameError:
  print("Name error")
except (ZeroDivisionError, NameError):
  print("Your denominator is equal to 0 or the variable name does not exist")
except Exception as e:
  print("Your variable name or denominator value is right, but there are other errors,See for details%s" %e)
  d = 1 
finally:
  print("I heard there is no mistake? I can't bear it. I'll make you sick anyway!")
  if d == 1:
    raise ValueError("You have other mistakes")
  else: 
    raise FuckError("Are you happy?")
  #Why? What is fucker error? It seems that there is no definition. Here is a definition. Then the position will move to the front
  class FuckError(Exception):
    def __int__(self,*args,**keargs):
      super(FuckError,self).__int__(*args,**keargs)#python2
      self.args = args
      print(args)  
Published 9 original articles, won praise 0, visited 5400
Private letter follow

Tags: Python Attribute JSON

Posted on Tue, 04 Feb 2020 11:15:52 -0500 by totof06