Selenium3与Python3实战 Web自动化测试框架
Posted 付俊捷
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Selenium3与Python3实战 Web自动化测试框架相关的知识,希望对你有一定的参考价值。
1、行为驱动环境搭建:
- 行为驱动:Behavie
- 断言:Pyhamcrest
- 环境语言:Python
- 框架:Selenium
安装:
1
2
3
|
pip install behave pip install pyhamcrest |
我们需要新建features包,在该包下要包含至少一个.feature文件和steps包,steps下包含对应执行的测试用例.py文件,场景描述文件写在.feature文件里
目录结构:
1)新建项目:feature_test
2)新建包:features
3)在features包中新建文件:register.feature ,写入场景描述:
# register.feature Feature: Register User As a developer This is my frist BDD project
Scenario: register_test # Given open register website When I open the register website Then I except that the title is "注册" # Scenario: input user_info # Then I set with useremail "nan@163.com" # And I set with username "nan" # And I set with password "111111" # And I set with code "tests" # And I click with register_button # Then I except that text "验证码错误"
4)在features包中新建environment.py环境:
from selenium import webdriver def before_all(context): context.driver = webdriver.Chrome() def after_all(context): context.driver.close()
5)在features包中新建steps包
6)在steps包下新建文件:register_user.py:
from behave import * use_step_matcher(\'re\') # 正则匹配 @when(\'I open the register website\') def step_register(context): context.driver.get("http://www.5itest.cn/register") @then(\'I except that the title is "([^"]*)"\') # 匹配除"外的所有字符,0个或多个 def step_register1(context,title_name): title = context.driver.title # 获取网页的title assert title_name in title # assert断言
注意:BDD运行方式,是在终端,进入项目中,执行:behave ,本项目执行如下
运行结果:
二、日志模块的使用
1、logging基本介绍
logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:
- 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
- print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出;
import logging import sys # 获取logger实例,如果参数为空则返回root logger logger = logging.getLogger("AppName") # 指定logger输出格式 formatter = logging.Formatter(\'%(asctime)s %(levelname)-8s: %(message)s\') # 文件日志 file_handler = logging.FileHandler("test.log") file_handler.setFormatter(formatter) # 可以通过setFormatter指定输出格式 # 控制台日志 console_handler = logging.StreamHandler(sys.stdout) console_handler.formatter = formatter # 也可以直接给formatter赋值 # 为logger添加的日志处理器 logger.addHandler(file_handler) logger.addHandler(console_handler) # 指定日志的最低输出级别,默认为WARN级别 logger.setLevel(logging.INFO) # 输出不同级别的log logger.debug(\'this is debug info\') logger.info(\'this is information\') logger.warn(\'this is warning message\') logger.error(\'this is error message\') logger.fatal(\'this is fatal message, it is same as logger.critical\') logger.critical(\'this is critical message\') # 2016-10-08 21:59:19,493 INFO : this is information # 2016-10-08 21:59:19,493 WARNING : this is warning message # 2016-10-08 21:59:19,493 ERROR : this is error message # 2016-10-08 21:59:19,493 CRITICAL: this is fatal message, it is same as logger.critical # 2016-10-08 21:59:19,493 CRITICAL: this is critical message # 移除一些日志处理器 logger.removeHandler(file_handler)
格式化输出日志:
# 格式化输出 service_name = "Booking" logger.error(\'%s service is down!\' % service_name) # 使用python自带的字符串格式化,不推荐 logger.error(\'%s service is down!\', service_name) # 使用logger的格式化,推荐 logger.error(\'%s service is %s!\', service_name, \'down\') # 多参数格式化 logger.error(\'{} service is {}\'.format(service_name, \'down\')) # 使用format函数,推荐 # 2016-10-08 21:59:19,493 ERROR : Booking service is down!
logging.basicConfig函数各参数: filename:指定日志文件名; filemode:和file函数意义相同,指定日志文件的打开模式,\'w\'或者\'a\'; format:指定输出的格式和内容,format可以输出很多有用的信息, 参数:作用 %(levelno)s:打印日志级别的数值 %(levelname)s:打印日志级别的名称 %(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0] %(filename)s:打印当前执行程序名 %(funcName)s:打印日志的当前函数 %(lineno)d:打印日志的当前行号 %(asctime)s:打印日志的时间 %(thread)d:打印线程ID %(threadName)s:打印线程名称 %(process)d:打印进程ID %(message)s:打印日志信息 datefmt:指定时间格式,同time.strftime(); level:设置日志级别,默认为logging.WARNNING; stream:指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略;
# StreamHandler:logging.StreamHandler;日志输出到流,可以是sys.stderr,sys.stdout或者文件 # FileHandler:logging.FileHandler;日志输出到文件 # BaseRotatingHandler:logging.handlers.BaseRotatingHandler;基本的日志回滚方式 # RotatingHandler:logging.handlers.RotatingHandler;日志回滚方式,支持日志文件最大数量和日志文件回滚 # TimeRotatingHandler:logging.handlers.TimeRotatingHandler;日志回滚方式,在一定时间区域内回滚日志文件 # SocketHandler:logging.handlers.SocketHandler;远程输出日志到TCP/IP sockets # DatagramHandler:logging.handlers.DatagramHandler;远程输出日志到UDP sockets # SMTPHandler:logging.handlers.SMTPHandler;远程输出日志到邮件地址 # SysLogHandler: logging.handlers.SysLogHandler;日志输出到syslog # NTEventLogHandler: logging.handlers.NTEventLogHandler;远程输出日志到Windows NT/2000/XP的事件日志 # MemoryHandler:logging.handlers.MemoryHandler;日志输出到内存中的指定buffer # HTTPHandler:logging.handlers.HTTPHandler;通过"GET"或者"POST"远程输出到HTTP服务器
设置消息等级
# FATAL:致命错误 # CRITICAL:特别糟糕的事情,如内存耗尽、磁盘空间为空,一般很少使用 # ERROR:发生错误时,如IO操作失败或者连接问题 # WARNING:发生很重要的事件,但是并不是错误时,如用户登录密码错误 # INFO:处理请求或者状态变化等日常事务 # DEBUG:调试过程中使用DEBUG等级,如算法中每个循环的中间状态
记录异常信息
当你使用logging模块记录异常信息时,不需要传入该异常对象,只要你直接调用logger.error()
或者 logger.exception()
就可以将当前异常记录下来。
# 记录异常信息 try: 1 / 0 except: # 等同于error级别,但是会额外记录当前抛出的异常堆栈信息 logger.exception(\'this is an exception message\') # 2016-10-08 21:59:19,493 ERROR : this is an exception message # Traceback (most recent call last): # File "D:/Git/py_labs/demo/use_logging.py", line 45, in # 1 / 0 # ZeroDivisionError: integer division or modulo by zero
Configuration 配置方法
logging的配置大致有下面几种方式。
- 通过代码进行完整配置,参考开头的例子,主要是通过getLogger方法实现。
- 通过代码进行简单配置,下面有例子,主要是通过basicConfig方法实现。
- 通过配置文件,下面有例子,主要是通过
logging.config.fileConfig(filepath)
demo:日志模块应用
info级别以上内容会记入指定日志文件中
import logging import os import datetime class UserLog(object): def __init__(self): self.logger1 = logging.getLogger(__name__) # 生成log对象 # 以下三行代码为清空上次创建log文件 logging.Logger.manager.loggerDict.pop(__name__) # 清空当前文件存于loggerDict的日志实例。(logging 模块为了保证同一个名称引用同一个日志实例,所以就把所有的日志实例全部存在了一个 loggerDict 的字典里,要释放某实例则需清除) self.logger1.handlers=[] # 将handers清空 self.logger1.removeHandler(self.logger1.handlers) # 移除当前文件的logging相关配置 if not self.logger1.handlers: # 如果logger.handlers列表为空,则新添加,否则表示文件存在,可以直接去写日志 self.logger1.setLevel(logging.DEBUG) #控制台输出日志 #consle = logging.StreamHandler() #logger.addHandler(consle) #文件名字 log_dir = os.path.dirname(os.path.abspath(__file__)) log_file = datetime.datetime.now().strftime("%Y-%m-%d") + ".log" log_name = os.path.join(log_dir,"logs",log_file) # 日志文件名 #文件输出日志 self.file_handle = logging.FileHandler(log_name,\'a\',encoding=\'utf-8\') self.file_handle.setLevel(logging.INFO) formatter = logging.Formatter(\'%(asctime)s %(filename)s--> %(funcName)s %(levelno)s: %(levelname)s ----->%(message)s\') self.file_handle.setFormatter(formatter) self.logger1.addHandler(self.file_handle) def get_log(self): return self.logger1 def close_handle(self): self.logger1.removeHandler(self.file_handle) self.file_handle.close() # if __name__ == \'__main__\': # user = UserLog() # log = user.get_log() # log.debug(\'test\') # user.close_handle()
"""
logging.Logger.manager.loggerDict.pop(__name__) self.logger1.handlers=[] self.logger1.removeHandler(self.logger1.handlers)
"""
解析:logging 模块为了保证同一个名称引用同一个日志实例,所以就把所有的日志实例全部存 在了一个 loggerDict 的字典里,。除非程序退出, 否则创建的日志实例引用是不会释放的, 日志实例里的 handlers 也不会释放.所以需要做以上操作处理。
在测试用例中操作:
# 1)setUpClass @classmethod def setUpClass(cls): cls.log = UserLog() cls.logger = cls.log.get_log() cls.driver = webdriver.Chrome() cls.driver.get(\'http://www.5itest.cn/register\') cls.driver.maximize_window() cls.file_name = setting.code_path cls.login = RegisterBusiness(cls.driver) # 2)setUp def setUp(self): self.driver.refresh() self.logger.info("this is chrome_tset") # 3)tearDownClass @classmethod def tearDownClass(cls): cls.log.close_handle() cls.driver.close()
执行结果:
三、持续集成
1、Jenkins 环境搭建,参考:https://www.cnblogs.com/Eric15/p/9834120.html
2、新建任务
Jenkins安装及配置好环境后,我们到Jenkins安装目录下执行命令:jenki.exe start ,启动服务器
浏览器访问:127.0.0.1:8080 , 进入服务器(需账号密码)
1)新建我们的第一个任务
2)命名并选择‘构建一个自由风格的软件项目’
3)进入下一步后,暂时只需要进行下面简单配置操作:
源码管理 → 先选无
构建 → 选择:执行Windows批处理命令
在命令里配置执行程序:python G:\\Python\\python_selenium\\case\\first_case.py
保存
执行 ‘立即构建’,之后可点击 ‘控制台输出’查看运行结果
跳出界面 →
因本项目是在虚拟环境下配置的,故在构建时,python执行文件应该选择虚拟环境中的python执行文件:
3、Jenkins邮件通知
以上是关于Selenium3与Python3实战 Web自动化测试框架的主要内容,如果未能解决你的问题,请参考以下文章
Selenium3与Python3实战 Web自动化测试框架
Selenium3与Python3实战 Web自动化测试框架
Selenium3与Python3实战 Web自动化测试框架
Selenium3 Python3 Web自动化测试从基础到项目实战之二浏览器的不同设置