Python3+selenium自动化测试框架详解

背景

为了更好的发展自身的测试技能,应对测试行业以及互联网行业的迭代变化。自学python以及自动化测试。

虽然在2017年已经开始接触了selenium,期间是断断续续执行自动化测试,因为还有其他测试任务,培训任务要执行…
前期建议大家能够学习python基本语法(python基础教程)

任务

搭建自动化测试框架,并能有效方便的进行测试,维护成本也要考虑其中。

过程

我的自动化框架可能不成熟,因为是自学的。请多包涵。也请大佬指导~

common

包含:基本的公共方法类,比如HTML报告、Log处理、发送邮件、基本页面对象等

其中pageObject里面是对各个测试系统操作页面的一个封装,以后用例的方法直接继承即可。可多次调用,维护起来比较方便。

conf

基本的系统参数配置信息,可以包含url,正确用户的信息,简单日志级别,某些输出位置,邮件信息等

​现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:485187702【暗号:csdn11】

data

对于数据驱动或者其他测试用例中需要测试的数据,之后测试用例流程不变,可以直接在文档中进行测试数据的修改。暂时采用excel。也可以采用csv,xml等等方法

log

日志输出,暂时包括了 log输出,htmlreport输出以及img的保存。

test

其中包含testcase以及testsuite两个模块

testcase 负责编写测试用例如果某个功能有多个py文件编写可以再新建一个目录。
testsuite 就是测试套件,可以按需求进行选择需要的测试项(包含测试用例以及测试类)
注意:使用ddt则不可以再使用addTest方式单独添加测试用例了。

1

代码部分

- common中的BasePage

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

class BasePage():

 global logg

 logg = LogHandler().logger

 def __init__(self,driver,url=None):

  self.wd = driver

  self.wd.implicitly_wait(5)

  self.actions = ActionChains(self.wd)

  if url :

   self.url = url

  else:

   self.url = self.server_url_conf()

 #浏览器行为的一些方法

 def get_conf_url(self):

        self.wd.get(self.url)

  self.wd.maximize_window()

  logg.debug("enter conf_url : " + str(self.url))

 def brower_close(self):

  return self.wd.close()

 def brower_quit_all(self):

  return self.wd.quit()

...     下面还有刷新,前进后退等

 #定位 这里通过 By.xx 方法

 def find_web_element(self,*loc):

  #self.wd.find_element(*loc)

  return self.wd.find_element(*loc)

 #元素操作

 def type_text(self,loc,text):

  return self.wd.find_element(*loc).send_keys(text)

   

 def clear_text(self,*loc):

  return self.wd.find_element(*loc).clear()

   

 def submit_func(self,*loc):

  return self.wd.find_element(*loc).submit()

 def click_btn(self,*loc):

  return self.wd.find_element(*loc).click()

   

    #鼠标相关

 def mouse_move_to_element(self,*loc):

  elem = self.find_web_element(*loc)

  self.actions.move_to_element(elem).perform()

... 下面还有点击,双击,右击的一些方法 

 #获取信息行为

 def get_web_url(self):

  return self.wd.current_url

 def get_title(self):

  return self.wd.title

 def get_element_text(self,*loc):

  return self.find_web_element(*loc).text

 #元素是否存在 是 True

 def check_element_isexist(self,loc):

  isexist = False

  try:

   EC.presence_of_element_located(loc)(self.wd)

   isexist = True

  except Exception as e:

   isexist = False

   logg.debug(' isexist or not :',exc_info = True)

  return isexist

 def check_element_has_text(self,loc,text):

        pass #省略

  

 def check_element_isdisplayed(self,*loc):

    pass #省略

     

 #生成图

 def __inser_img(self,passorfailed,imgname):

  time_loc = time.strftime("%m%d_%H%M%S",time.localtime())

  file_path = os.path.abspath(__file__)

  file_path = os.path.join(file_path+"/../../log/%s_%s.png" %(imgname,time_loc))

  self.wd.get_screenshot_as_file(file_path)

  logg.debug('insert_%s_img %s ' %(passorfailed,(file_path)))

 def insert_error_img(self,imgname):

  self.__inser_img("error",imgname)

 def insert_success_img(self,imgname):

  self.__inser_img("success",imgname)

 def insert_debug_img(self,imgname):

  self.__inser_img("debug",imgname)

 def server_url_conf(self):

  self.host = readconfig.ReadConfig().getserver('host')

  self.port = readconfig.ReadConfig().getserver('port')

  urlvalue = self.host + ":" + self.port

  return urlvalue

if __name__ == '__main__':

 test = BasePage(webdriver.Chrome())

 test.get_conf_url()

common中登录页的页面对象

包含了页面的一些方法比如

输入用户名,输入密码,点击登录

test中的 logintestcase

则直接使用 登录页面对象的 输入用户名,输入密码,点击登录即可

后期维护,如果元素变动,则只需要修改页面对象代码而对用例则无需修正

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

class AioLogin(BasePage):

 global logg

 logg = LogHandler().getlog()

 username_loc = (By.NAME, "username")

 password_loc = (By.CSS_SELECTOR, "input[type='password']")

 login_loc = (By.CLASS_NAME, "login-btn")

 login_loc_oem = (By.ID,"submit")

 check_login_loc = (By.CLASS_NAME,"error-tip")

 elements = [username_loc,password_loc,login_loc,check_login_loc]

 log_menu = (By.CSS_SELECTOR,"[name='log']")

 logg.debug(elements)

  

 def set_username(self,username):

  self.clear_text(*self.username_loc) #直接使用BasePage的方法

  self.type_text(self.username_loc,username)

  logg.info('Enter username: ' + username)

  sleep(0.1)

... 其他

logintest

这里使用了ddt数据驱动方法

from ddt import data,ddt,unpack

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

@ddt

class TestLogin(unittest.TestCase):

 global logg

 logg = LogHandler().getlog()

  

 @classmethod  #该类方法,执行中只会启动一次。区别于setUp的 每个用例都执行一遍

 def setUpClass(cls):

  cls.test = aiologinpage.AioLogin(webdriver.Chrome())

  cls.test.get_conf_url()

  # print('start TestSearch')

   

 @classmethod

 def tearDownClass(cls):

  # TestLogin().logg.info("brower quit")

  TestLogin().test.brower_close()

  pass

 logindata = ReadExcel().getValue('login')

  

 @data(*logindata)

 @unpack  #当有多组数据时,需要unpack

 def testcase2(self,username,passwd,result):

  logg.info(username+" " + passwd +" " +str(result))

  self.test.set_username(username) #用例直接使用登录页面对象,后期除了修改测试用例,否则无需变动

  self.test.set_password(passwd)

  self.test.type_login_btn()

   

  # 断言登录结果和预期结果是否一致

  self.assertTrue(self.test.check_login_result(result),

      msg="\r login_test fail \r username :%s \r passwd : %s " %(username,passwd))

if __name__ == '__main__':

 unittest.main()

其他页面

比如我有个 创建设备分组的页面

我必须要先登录才可以执行下面的操作

此时,可以从conf中获取成功登录的用户名和密码,把correct_login方法写在登录页面对象中。

1

2

3

4

5

6

def correct_login(self):

  self.get_conf_url()

  self.userpasswd = self.correct_userpasswd_conf()

  self.set_username(self.userpasswd[0])

  self.set_password(self.userpasswd[1])

  self.type_login_btn()

之后,其他页面初始化时候直接调用这个correct_login即可登录

测试套件添加方法
TestSuite方法
#添加一个类
st1 = unittest.makeSuite(TestLogin)
#单独添加多个用例
st = unittest.TestSuite(map(TestClassName,[‘testcase1',‘testcase2']))
st = unittest.TestSuite(TestClaseeName(‘testcase1'))

#添加一个或者多个测试用例
st2 = unittest.TestSuite()
st2.addTests(map(TestCaseClassName,[‘testcase2',‘testcase1']))
st2.addTest(TestCaseClassName(‘testcase1'))
#添加一个类
st2.addTest(unittest.makeSuite(TestClassName))

TestLoader 方法
discovery 发现脚本
st = unittest.TestLoader().discovery(“dir_path”,pattern=“a*.py”)

#loadTestFromTestCase 加载 测试类
st1 = unittest.TestLoader().loadTestsFromTestCase(TestLoginCheck)
st2 = unittest.TestLoader().loadTestsFromTestCase(TestLogin)
stt = unittest.TestSuite()
stt.addTests([st1,st2])

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】

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

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

相关文章

W11+Ipv6+可道云+PHPstudy实现私人云盘搭建

W11Ipv6可道云PHPstudy实现私人云盘搭建 一、搭建原因二、搭建过程软件选择服务器环境管理软件私人云盘 可道云搭建小皮面板搭建 三、相关配置程序开机自启远程关机远程开机 四、相关参考 一、搭建原因 工位电脑上一些文件想备份到家里电脑,购买NAS又有点多余&…

solidity实现ERC1155多代币标准

文章目录 1、NFT - 维基百科2、IERC1155MetadataURI3、IERC1155Receiver4、IERC11555、ERC11556、NFT11557、开源地址 1、NFT - 维基百科 ERC-1155 标准于2018年6月由Witek Radomski、Andrew Cooke、Philippe Castonguay、James Therien、Eric Binet及Ronan Sandford提出。此标…

从微软官网下载系统镜像重装的方法

一、制作系统镜像介质U盘 1、在一台能够正常进入系统的电脑中登录以下网址:https://www.microsoft.com/zh-cn/software-download/windows10, 点击立即下载工具。 2、在下载完成后,双击打开,选择为另一台电脑创建安装介质&#xf…

controller能接收到数据有数据但是前端无法显示数据

又是制作系统时遇到的问题。只是想做个查询商品的页面,结果弄了一天,在网上各种查问题,各种解决办法用在我的代码上,换了无数种关键词搜索终于找到了一条成功解决了问题。 问题描述: 事情是这样的:我要写一…

云原生之深入解析Kubernetes策略引擎对比:OPA/Gatekeeper与Kyverno

一、前言 ① Kubernetes 策略 Kubernetes 的 Pod Security Policy,正如其名字所暗示的,仅是针对 Pod 工作的,是一种用来验证和控制 Pod 及其属性的机制。另外 PSP 只能屏蔽非法 Pod 的创建,无法执行任何补救/纠正措施。而 Gatek…

如何将Java条码Dynamsoft Barcode Reader集成到命令行、GUI和Web应用程序中

Dynamsoft Barcode Reader SDK一款多功能的条码读取控件,只需要几行代码就可以将条码读取功能嵌入到Web或桌面应用程序。这可以节省数月的开发时间和成本。能支持多种图像文件格式以及从摄像机或扫描仪获取的DIB格式。使用Dynamsoft Barcode Reader SDK,…

实验案例二:多表查询

1、表联接类型。 表联接类型可以分为内联接.外联接和交叉联接等。 1.内联接。 内联接〈 inner join)是最常用的-一-种联接方式,只返回两个数据集合之间匹配关系的行,将位于两个互相交叉的数据集合中重叠部分以内的数…

ROS第一个程序——helloworld

目录 一、工作空间的创建 1.创建工作空间并初始化 2.进入 src 创建 ros 包并添加依赖 二、C实现helloworld C源码实现 编辑 ros 包下的 Cmakelist.txt文件 进入工作空间目录并编译 执行 三、python实现helloworld 进入 ros 包添加 scripts 目录并编辑 python 文件 …

推荐6个AI相关开源项目

1.GPT 学术优化 - 一个专注优化论文的 AI 工具 🌐开源地址:https://github.com/binary-husky/gpt_academic 🖥️体验地址:https://huggingface.co/spaces/qingxu98/gpt-academic 📄该工具可以为你的论文提供一键润色…

flink安装与配置-脚本一键安装(超简单)

文章目录 前言使用shell脚本一键安装1. 复制脚本2. 增加执行权限3. 执行脚本4. 加载用户环境变量5. 浏览器访问 总结 前言 本文介绍了使用shell脚本一键安装和配置Apache Flink单机版的方法。通过复制并执行提供的安装脚本,可以自动下载、安装和配置Flink。脚本会检…

ZYNQ_project:HDMI

实验目标:先显示彩条,通过uart串口传输100x100 大小图片像素信息,然后开始弹跳显示该图片在显示器上。 HDMI 是新一代的多媒体接口标准, 英文全称是 High-Definition Multimedia Interface, 即高清多媒体接口。 它能够…

录视频人不在电脑旁,怎么设置定时关机

如果你平常工作比较忙,或者要录制的视频/音频文件需要很长时间,最好选择预约录制,这样可使录屏软件自动开始和停止录制,并且定时关机。此外,你还可以设置保存录制文件、关闭录屏软件。是不是听起来很感兴趣&#xff1f…

进程程序替换和shell实现

先前fork说创建子进程执行代码,如何让子进程执行和父进程完全不一样的代码?程序替换。 一 单进程替换演示 1 execl函数使用 最近转到在vs code下写代码,之前也在xhell下用过execl函数,所以才想写篇博客总结总结,没想到在vs code…

Docker Compose简单入门

Docker Compose 简介 Docker Compose 是一个编排多容器发布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。 Docker Compose 真正的作用是在一个文件(docker-compose.yml)中定义并运…

Arthas安装及简单使用

一. 背景介绍 Arthas 是 Alibaba 在 2018 年 9 月开源的 Java 诊断工具。支持 JDK6, 采用命令行交互模式,提供 Tab 自动补全,可以方便的定位和诊断线上程序运行问题。得益于 Arthas 强大且丰富的功能,让 Arthas 能做很多的事情&a…

超声波眼镜清洗机是智商税吗?2023年超声波清洗机比较不错推荐

随着科技的日新月异,我们生活中充满了各种各样的智能设备。其中,超声波清洗机以其独特的清洗能力,逐渐走进我们的生活。然而,对于很多人来说,超声波清洗机还是一个相对陌生的概念。那么,超声波清洗机到底是…

P9 链表 清空链表|销毁链表

目录 前言 01销毁链表 02 清空链表 测试代码 前言 🎬 个人主页:ChenPi 🐻推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ 🔥 推荐专栏2: 《Linux C应用编程(概念类)_ChenPi的博客-CSDN博客》✨✨✨ …

Markdown语法入门与进阶指南

一、Markdown简介 Markdown是一种轻量级标记语言,创始人为约翰格鲁伯(john Gruber)。它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档。这种语言吸收了很多在电子邮件中…

Spring Session介绍

Spring SessionSession储存到Redis1:添加依赖2:配置信息3:Spring Session存String3:Spring Session存对象 项目改造-Redis储存Session Spring Session Spring Session储存在Redis和取的执行流程: 1:request.getSession() 方法时&…

地隔离放大器集成电路芯片D3121,低噪声低失真双通道且外接电容小,能有效消除由线 路电阻所引起的问题及噪声

D3121 是一块对地能动冲放大器集成电路,该电路能有效消除由线 路电阻所引起的问题及噪声。所需外围电容小,便于设计时小型化的同 时可靠性不降低。广泛应用于车载音响系统内。 D3121 系列采用 DIP8 、 SOP8 、 SIP8 的封装形式封装。 主要特点&#x…