Selenium+Python做web端自动化测试框架与实例详解教程

最近受到万点暴击,由于公司业务出现问题,工作任务没那么繁重,有时间摸索selenium+python自动化测试,结合网上查到的资料自己编写出适合web自动化测试的框架,由于本人也是刚刚开始学习python,这套自动化框架目前已经基本完成了所以总结下编写的得失,便于以后回顾温习,有许多不足的的地方,也遇到了各种奇葩问题,希望大神们多多指教

首先我们要了解什么是自动化测试,简单的说编写代码、脚本,让软件自动运行,发现缺陷,代替部分的手工测试。了解了自动化测试后,我们要清楚一个框架需要分那些模块:

上图的框架适合大多数的自动化测试,比如web UI  、接口自动化测试都可以采用,如大佬有好的方法请多多指教,简单说明下每个模块:

  • common:存放一些共通的方法
  • data:存放一些文件信息
  • logs:存放程序中写入的日志信息
  • picture:存放程序中截图文件信息
  • report:存放测试报告
  • test_case:存放编写具体的测试用例
  • conf.ini、readconf.py:存放编写的配置信息

下面就具体介绍每个模块的内容:conf.ini主要存放一些不会轻易改变的信息,编写的代码如下:

[DATABASE]
host = 127.0.0.1
username = root
password = root
port = 3306
database = cai_test[HTTP]
# 接口的url
baseurl = http://xx.xxxx.xx
port = 8080
timeout = 1.0
readconf.py文件主要用于读取conf.ini中的数据信息
# *_*coding:utf-8 *_*
__author__ = "Test Lu"
import os,codecs
import configparser
prodir = os.path.dirname(os.path.abspath(__file__))
conf_prodir = os.path.join(prodir,'conf.ini')
class Read_conf():def __init__(self):with open(conf_prodir) as fd:data = fd.read()#清空文件信息if data[:3] ==codecs.BOM_UTF8:data = data[3:]file = codecs.open(conf_prodir,'w')file.write(data)file.close()self.cf = configparser.ConfigParser()self.cf.read(conf_prodir)def  get_http(self,name):value = self.cf.get("HTTP",name)return valuedef get_db(self,name):return self.cf.get("DATABASE",name)
这里需要注意,python3.0以上版本与python2.7版本import configparser的方法有一些区别
读取一些配置文集就介绍完了,下面就说说common包下的公共文件

现在就从上往下结束吧!common主要是封装的一些定位元素的方法:

# *_*coding:utf-8 *_*
__author__ = "Test Lu"
from selenium import webdriver
import time,os
import common.config
# from common.logs import MyLog
project_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
class Comm(object):def __init__(self,driver):self.driver = driver# self.driver = webdriver.Firefox()self.driver = webdriver.Chrome()self.driver.maximize_window()def open_url(self,url):self.driver.get(url)self.driver.implicitly_wait(30)# selenium 定位方法def locate_element(self,loatetype,value):if (loatetype == 'id'):el = self.driver.find_element_by_id(value)if (loatetype == 'name'):el = self.driver.find_element_by_name(value)if (loatetype == 'class_name'):el = self.driver.find_element_by_class_name(value)if (loatetype == 'tag_name'):el = self.driver.find_elements_by_tag_name(value)if (loatetype == 'link'):el = self.driver.find_element_by_link_text(value)if (loatetype == 'css'):el = self.driver.find_element_by_css_selector(value)if (loatetype == 'partial_link'):el = self.driver.find_element_by_partial_link_text(value)if (loatetype == 'xpath'):el = self.driver.find_element_by_xpath(value)return el if el else None# selenium 点击def click(self,loatetype,value):self.locate_element(loatetype,value).click()#selenium 输入def input_data(self,loatetype,value,data):self.locate_element(loatetype,value).send_keys(data)#获取定位到的指定元素def get_text(self, loatetype, value):return self.locate_element(loatetype, value).text# 获取标签属性def get_attr(self, loatetype, value, attr):return self.locate_element(loatetype, value).get_attribute(attr)# 页面截图def sc_shot(self,id):for filename in os.listdir(os.path.dirname(os.getcwd())) :if filename == 'picture':breakelse:os.mkdir(os.path.dirname(os.getcwd()) + '/picture/')photo = self.driver.get_screenshot_as_file(project_dir +  '/picture/'+ str(id) + str('_') + time.strftime("%Y-%m-%d-%H-%M-%S") + '.png')return photodef __del__(self):time.sleep(2)self.driver.close()self.driver.quit()
下面介绍下,config文件主要用于读取文件中的信息:
import os,xlrd
from common.logs import MyLog
from xml.etree import ElementTree as ElementTree
mylogger = MyLog.get_log()
project_dir = os.path.dirname(os.getcwd())def user_Add():'''excel文件中读取用户登录信息'''with xlrd.open_workbook(project_dir+'/data/test_data.xlsx') as files:table_user = files.sheet_by_name('userdata')try:username = str(int(table_user.cell(1,0).value))except:username = str(table_user.cell(1,0).value)try:passwd = str(int(table_user.cell(1,1).value))except:passwd = str(table_user.cell(1,1).value)try:check = str(int(table_user.cell(1, 2).value))except Exception:check = str(table_user.cell(1, 2).value)table_url = files.sheet_by_name('base_url')base_url = str(table_url.cell(1,0).value)return (username,passwd,base_url,check)
#从xml文件中读取信息,定义全局一个字典来存取xml读出的信息
database={}
def set_read_xml():sql_path = os.path.join(project_dir,'data','SQL.xml')data =ElementTree.parse(sql_path)for db in data.findall('database'):name = db.get('name')table = {}for tb in db.getchildren():table_name = tb.get("name")sql = {}for data in tb.getchildren():sql_id = data.get("id")sql[sql_id] = data.texttable[table_name] = sqldatabase[name] = tablemylogger.info("读取的xml文件的信息%s" %database)
def get_sql_sen(database_name,table_name,sql_id):set_read_xml()db = database.get(database_name).get(table_name)if db.get(sql_id):sql = db.get(sql_id).strip()mylogger.info("返回sql语句信息%s" % sql)return sqlelse:mylogger.info("查下的信息为空,传递的参数有误!数据库名称:【%s】,表信息【%s】,查询的id【%s】"%(database_name,table_name,sql_id))
接着介绍最简单的日志logs.py模块:
# logging模块支持我们自定义封装一个新日志类
import logging,time
import os.path
class Logger(object):def __init__(self, logger,cases="./"):       self.logger = logging.getLogger(logger)self.logger.setLevel(logging.DEBUG)self.cases = cases# 创建一个handler,用于写入日志文件for filename in os.listdir(os.path.dirname(os.getcwd())):if filename == "logs":breakelse:os.mkdir(os.path.dirname(os.getcwd())+'/logs')rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))log_path = os.path.dirname(os.getcwd()) + '/logs/'  log_name = log_path + rq + '.log'  # 文件名# 将日志写入磁盘fh = logging.FileHandler(log_name)fh.setLevel(logging.INFO)# 创建一个handler,用于输出到控制台ch = logging.StreamHandler()ch.setLevel(logging.INFO)# 定义handler的输出格式formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')fh.setFormatter(formatter)ch.setFormatter(formatter)# 给logger添加handlerself.logger.addHandler(fh)self.logger.addHandler(ch)def getlog(self):return self.logger
common模块最后一个是test_runner.py这个方法主要是用来执行全部的测试用例
import time,HTMLTestRunner
import unittest
from common.config import *
project_dir = os.path.abspath(os.path.join(os.path.dirname(__file__),os.pardir))
class TestRunner(object):''' 执行测试用例 '''def __init__(self, cases="../",title="Auto Test Report",description="Test case execution"):self.cases = casesself.title = titleself.des = descriptiondef run(self):for filename in os.listdir(project_dir):if filename == "report":breakelse:os.mkdir(project_dir+'/report')# fp = open(project_dir+"/report/" + "report.html", 'wb')now = time.strftime("%Y-%m-%d_%H_%M_%S")# fp = open(project_dir+"/report/"+"result.html", 'wb')fp = open(project_dir+"/report/"+ now +"result.html", 'wb')tests =  unittest.defaultTestLoader.discover(self.cases,pattern='test*.py',top_level_dir=None)runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title=self.title, description=self.des)runner.run(tests)fp.close()
以上就是common公共模块所有的模块,简单说下在写这些公共模块时,出现了各种问题,特别是读取xml文件的,唉!对于一个python的小白真是心酸啊!接着说下db模块的内容,db模块主要是读取sql语句以及返回对应的值!
import pymysql
import readconf
import common.config as conf
readconf_conf = readconf.Read_conf()host = readconf_conf.get_db("host")
username = readconf_conf.get_db("username")
password = readconf_conf.get_db("password")
port = readconf_conf.get_db("port")
database = readconf_conf.get_db("database")
config_db = {'host': str(host),'user': username,'password': password,'port': int(port),'db': database
}
class Mysql_DB():def __init__(self):'''初始化数据库'''self.db = Noneself.cursor = Nonedef connect_db(self):'''创建连接数据库'''try:self.db = pymysql.connect(**config_db)#创建游标位置self.cursor = self.db.cursor()# print("链接数据库成功")conf.mylogger.info("链接IP为%s的%s数据库成功" %(host,database))except ConnectionError as ex:conf.mylogger.error(ex)def get_sql_result(self,sql,params,state):self.connect_db()try:self.cursor.execute(sql, params)self.db.commit()# return self.cursorexcept ConnectionError as ex:self.db.rollback()if state==0:return self.cursor.fetchone()else:return self.cursor.fetchall()def close_db(self):print("关闭数据库")conf.mylogger.info("关闭数据库")self.db.close()
刚开始写db模块是一直对字典模块的信息怎样传递到数据链接的模块,进过网上查询好些资料才彻底解决,对自己来说也是一种进步,哈哈,下面说下自己踩的坑,帮助自己以后学习**config_db把字典变成关键字参数传递,
下面举例说明下:
如果kwargs={'a':1,'b':2,'c':3}那么**kwargs这个等价为test(a=1,b=2,c=3)是不是很简单!哈哈以上就是框架的主要模块,其他的模块每个项目与每个系统都不一样,在这里就是列举出来了,因为就算写出来大家也不能复用,下面就给大家看看小白还有哪些模块

看下了下data模块下的xml模块大家可能用的到,就给大家贴出来吧!因为ui测试主要就用到select与delete语句,所以也没有写多么复杂的sql语句

<?xml version="1.0" encoding="utf-8" ?>
<data><database name="database_member"><table name="table_member"><sql id="select_member">select * from user where real_name=%s</sql><sql id="select_member_one">select mobile from user where mobile=%s</sql><sql id="delete_member">delete from user where mobile=%s</sql><sql id="insert_member">insert into user(id) value(%s)</sql><sql id="update_member">uodate user set real_name = %s where uuid=%s</sql></table></database>
</data>
下面介绍下其他模块的内容:test_data.xlsx文件主要是存放一些用户信息,以及url信息,这样修改用户信息与url信息就不要修改代码方便以后操作!logs是在代码运行时候产生的日志信息,picture是存放图片信息,report存放输入的报告信息,
test_case是编写用户的模块需要所有的用例名称都要以test开头来命名哦,这是因为unittest在进行测试时会自动匹配test_case文件夹下面所有test开头的.py文件

Python接口自动化测试零基础入门到精通(2023最新版)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/178806.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于HTML+CSS+JavaScript的登录注册界面设计

一、界面效果: 二、HTML代码: 登录注册html: 登录成功html: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <h1>登录成功!</h1> </body> <…

类指针压缩空间

一、类指针压缩介绍 压缩指针&#xff0c;指的是在 64 位的机器上&#xff0c;使用 32 位的指针来访问数据&#xff08;堆中的对象或 Metaspace 中的元数据&#xff09;的一种方式。 对象头中的 Class Pointer 默认占 8 个字节&#xff0c;开启 -XX:UseCompressedOops 后&…

跳表的学习记录

跳表&#xff08;Skip List&#xff09;是一种数据结构&#xff0c;它通过在多个层次上添加额外的前向指针来提高有序数据的搜索效率。跳表与其他常见的有序数据结构&#xff08;如二叉搜索树、平衡树如AVL树和红黑树、B树等&#xff09;相比&#xff0c;具有其独特的优缺点&am…

vue3中如何使用TypeScript?

在Vue 3中引入和使用TypeScript非常简单。下面是在Vue 3中引入和使用TypeScript的步骤&#xff1a; 创建Vue 3项目&#xff1a;首先&#xff0c;使用Vue CLI创建一个新的Vue 3项目。可以使用以下命令&#xff1a; vue create my-project在创建项目时&#xff0c;选择TypeScri…

国标GB28181安防监控平台EasyCVR周界入侵AI算法检测方案

在城市管理和公共安全领域&#xff0c;安全视频监控的重要性日益凸显。AI视频智能分析平台基于深度学习和计算机视觉技术&#xff0c;利用AI入侵算法&#xff0c;能够实时、精准地监测周界入侵行为。 TSINGSEE青犀在视频监控及AI视频智能分析领域拥有深厚的技术积累和丰富的实…

全面介绍SSO(单点登录)

全面介绍SSO&#xff08;单点登录&#xff09; SSO英文全称Single SignOn&#xff0c;单点登录。SSO是在多个应用系统中&#xff0c;用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比…

亮相史上规模最大高交会,Coremail展现邮件技术创新实力

11月19日&#xff0c;第二十五届中国国际高新技术成果交易会在深圳落下帷幕&#xff0c;作为国内邮件行业引领者&#xff0c;Coremail受邀参展。 展览现场&#xff0c;Coremail邮件解决方案及系列产品受到了众多参观者与业内人士的关注与好评。Coremail XT6邮件系统技术成熟&a…

【JavaEE初阶】——Linux 基本使用和 web 程序部署(下)

文章目录 前言一、Linux 常用命令 1.1 ls 命令 1.2 pwd 命令 1.3 cd 命令 1.4 touch 命令 1.5 cat 命令 1.6 mkdir 命令 1.7 rm 命令 1.8 cp 命令 1.9 mv 命令 1.10 man 命令 1.11 less 命令 1.12 head 命令 1.13 tail 命…

玻色量子事件活动

2023年 2023.7 玻色量子携最新相干光量子计算机惊艳亮相2023数字经济大会 2023.6 打造“新型计算数据中心”&#xff01;玻色量子与科华数据&#xff08;002335.SZ&#xff09;携手共创 2023.6 玻色量子“天工量子大脑”亮相中关村论坛&#xff0c;大放异彩 2023.5 100量…

基于mvc的大学生家教信息网站系统php+vue

运行环境:phpstudy/wamp/xammp等 开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp5 前端框架&#xff1a;vue.js 服务器&#xff1a;apache 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat/phpmyadmin 开发软件&#xff1a;hbuilderx/vscode/Dreamweaver/PhpSt…

029 - STM32学习笔记 - ADC(三) 独立模式单通道DMA采集

029 - STM32学习笔记 - 单通道DMA采集&#xff08;三&#xff09; 单通道ADC采集在上节中学习完了&#xff0c;这节在上节的内容基础上&#xff0c;学习单通道DMA采集。程序代码以上节的为基础&#xff0c;需要删除NVIC配置函数、中段服务子程序、R_ADC_Mode_Config()函数中使能…

python绑定或无绑定类方法

1 python绑定或无绑定类方法 python函数是一种对象&#xff0c;在导入时会运行def语句&#xff0c;将函数对象赋值给函数名。 python方法是类内def定义的函数&#xff0c;即类方法。 1.1 访问类方法 python类方法可以通过类或实例进行访问。 NO访问方式描述1类.方法名(实例…

21.什么是bean的自动装配?

什么是bean的自动装配? 在Spring框架中,在配置文件中设定bean的依赖关系是一个很好的机制,Spring 容器能够自动装配相互合作的bean,这意味着容器不需要配置,能通过Bean工厂自动处理bean之间的协作。这意味着 Spring可以通过向Bean Factory中注入的方式自动搞定bean之间的…

50-75GHz大功率六倍频源设计

摘 要 本文介绍了毫米波的特点&#xff0c;根据构成毫米波倍频器的不同器件&#xff0c;介绍了不同毫米波倍频器的实现方法&#xff0c;综述了毫米波倍频器这一领域的研究水平及其发展动态&#xff0c;重点研究频段全波导带宽倍频器的设计方法&#xff0c;从而将波段信号扩展到…

华为鸿蒙开发(HarmonyOs开发):超详细的:DevEco Studio 的安装和配置 、华为第三方包依赖:SDK软件包的安装、Nodejs的导入配置

2023年11月28日20:00:00 ⚠️⚠️HarmonyOs 开发工具 ⚠️⚠️ ⚠️⚠️DevEco Studio 的安装和配置⚠️⚠️ 文章目录 一、打开鸿蒙开发工具官网二、下载 DevEco Studio三、配置 DevEco Studio四、错误处理 ⚠️⚠️⚠️❤️❤️ 关注了解更多 一、打开鸿蒙开发工具官网 下面…

人工智能原理复习--绪论

文章目录 人工智能原理概述图灵测试人工智能的研究方法符号主义连接主义行为主义总结 下一篇 人工智能原理概述 人工智能是计算机科学基础理论研究的重要组成部分 现代人工智能一般认为起源于美国1956你那夏季的达特茅斯会议&#xff0c;在这次会议上&#xff0c;John McCart…

利用python对数据进行季节性和趋势拆解

1. 引言 时间序列数据是按时间顺序排列的数据点的集合。与传统的交叉-sectional 数据不同&#xff0c;时间序列数据通常具有时间维度&#xff0c;因此每个数据点都与一个特定的时间点相关联。这种数据类型在许多领域中都很常见&#xff0c;如经济学、气象学、股票市场分析等。…

泛微E-Office SQL注入漏洞复现

0x01 产品简介 泛微E-Office是一款标准化的协同 OA 办公软件&#xff0c;泛微协同办公产品系列成员之一,实行通用化产品设计&#xff0c;充分贴合企业管理需求&#xff0c;本着简洁易用、高效智能的原则&#xff0c;为企业快速打造移动化、无纸化、数字化的办公平台。 0x02 漏…

【Python小游戏】推荐8款自由的Python游戏项目

推荐8款自由的Python游戏项目 今天给大家推荐8款不错的Python小游戏&#xff0c;这些小游戏所有项目文件&#xff08;包括所需的所有代码、图像和音频文件&#xff09;&#xff0c;给大家已经放到平台的下载频道&#xff0c;需要的可以注意一下文末的链接地址。 下面给大家简单…

智能优化算法应用:基于蝙蝠算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于蝙蝠算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于蝙蝠算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蝙蝠算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…