python+unittest框架整理(一点点学习前辈们的封装思路,一点点成长。。。)

预期框架整理目标:

1.单个用例维护在单个.py文件中可单个执行,也可批量生成组件批量执行

2.对定位参数,定位方法,业务功能脚本,用例脚本,用例批量执行脚本,常用常量进行分层独立,各自维护在单独的.py文件中

3.加入日志,htlm报表,发送邮件功能

框架结构

 

结构说明:

config:配置部分,浏览器种类和定位信息维护在此处

constant:常量部分,固定不变的数据维护在此处

data:存放用于参数化的文本表格等文件

encapsulation:定位等selenium功能二次封装在此处

error_picture:存放错误截图

function:业务功能脚本维护在此处

log:存放log类

report:存放测试报告文件

test_case:存放用例文件

all_case.py:用来执行所有用例

debug_case.py:本人调试用的,可以忽略

tst.log:生成的日志

逐个介绍各个包下面的.py文件,并附上源码(说明见注释哈哈~):

 

 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @Time    : 2017-05-11 13:42
 4 # config/config_01.py
 5 from selenium import webdriver
 6 import time
 7 from selenium.webdriver.common.action_chains import *
 8 
 9 
10 # config配置部分
11 
12 # 浏览器种类维护在此处
13 browser_config = {
14     'ie': webdriver.Ie,
15     'chrome': webdriver.Chrome
16 }
17 
18 # 定位信息维护在此处,维护结构由外到内为:页面名称--页面下元素名称--元素的定位方式+参数
19 locat_config = {
20     '博客园首页': {
21         '找找看输入框': ['id', 'zzk_q'],
22         '找找看按钮': ['xpath', '//input[@value="找找看"]']
23     }
24 }
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # @Time    : 2017-05-15 13:20
4 # constant/constant_1.py
5 
6 # 常量部分(固定不变使用频繁的参数维护在此处)
7 LOGIN_URL = 'https://www.cnblogs.com/'
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @Time    : 2017-05-15 13:20
 4 # encapsulation/encapsulation.py
 5 
 6 # 封装部分维护在此
 7 
 8 from config.config_01 import locat_config
 9 from log.log import Logger
10 from selenium.webdriver.support.wait import WebDriverWait
11 
12 from selenium.webdriver.support import expected_conditions as EC
13 
14 class UIHandle():
15     logger = Logger()
16 
17     # 构造方法,用来接收selenium的driver对象
18     @classmethod
19     def __init__(cls, driver):
20         cls.driver = driver
21 
22     # 输入地址
23     @classmethod
24     def get(cls, url):
25         cls.logger.loginfo(url)
26         cls.driver.get(url)
27 
28     # 关闭浏览器驱动
29     @classmethod
30     def quit(cls):
31         cls.driver.quit()
32 
33     # element对象(还可加入try,截图等。。。)
34     @classmethod
35     def element(cls, page, element):
36         # 加入日志
37         cls.logger.loginfo(page)
38         # 加入隐性等待
39         # 此处便可以传入config_o1中的dict定位参数
40         el = WebDriverWait(cls.driver, 10).until(EC.presence_of_element_located(locat_config[page][element]))
41         # 加入日志
42         cls.logger.loginfo(page+'OK')
43         return el
44     # element对象(还未完成。。。)
45     def elements(cls, page, element):
46         # 加入日志
47         cls.logger.loginfo(page)
48         # 加入隐性等待
49         WebDriverWait(cls.driver, 10)
50         els = cls.driver.find_elements(*locat_config[page][element])
51         # 注意返回的是list
52         return els
53 
54     # send_keys方法
55     @classmethod
56     def Input(cls, page, element, msg):
57         el = cls.element(page, element)
58         el.send_keys(msg)
59 
60     # click方法
61     @classmethod
62     def Click(cls, page, element):
63         el = cls.element(page, element)
64         el.click()
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @Time    : 2017-05-15 13:22
 4 # function/function_01.py
 5 # 业务功能脚本(用例脚本可调用此处的功能脚本)
 6 
 7 from encapsulation.encapsulation import UIHandle
 8 from constant.constant_1 import LOGIN_URL
 9 from config.config_01 import browser_config
10 from time import sleep
11 
12 # 打开博客园首页,进行找找看搜索功能
13 def search(msg):
14     # 打开浏览器
15     driver = browser_config['chrome']()
16     # 传入driver对象
17     uihandle = UIHandle(driver)
18     #输入url地址
19     uihandle.get(LOGIN_URL)
20     # 调用二次封装后的方法,此处可见操作了哪个页面,哪个元素,msg是要插入的值,插入值得操作在另外一个用例文件中传入
21     uihandle.Input('博客园首页', '找找看输入框', msg)
22     uihandle.Click('博客园首页', '找找看按钮')
23     uihandle.quit()
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @Time    : 2017-05-17 11:19
 4 # log/log.py
 5 
 6 import logging
 7 import logging.handlers
 8 
 9 # 日志类
10 class Logger():
11     LOG_FILE = 'tst.log'
12 
13     handler = logging.handlers.RotatingFileHandler(LOG_FILE, maxBytes = 1024*1024, backupCount = 5) # 实例化handler
14     fmt = '%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s'
15 
16     formatter = logging.Formatter(fmt)   # 实例化formatter
17     handler.setFormatter(formatter)      # 为handler添加formatter
18 
19     logger = logging.getLogger('tst')    # 获取名为tst的logger
20     logger.addHandler(handler)           # 为logger添加handler
21     logger.setLevel(logging.DEBUG)
22     def loginfo(self, message):
23         self.logger.info(message)
24 
25     def logdebug(self, message):
26         self.logger.debug(message)
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @Time    : 2017-05-15 15:30
 4 # test_case/test_case_1/start_case_01.py
 5 
 6 import unittest
 7 from function.function_01 import *
 8 # 用例
 9 class Case_02(unittest.TestCase):
10     u'''哇塞好玩'''
11     def setUp(self):
12         pass
13 
14     def test_zzk(self):
15         u'''输入哇塞好玩后点击找找看'''
16         search("哇塞好玩")
17         print('打印方法名:test_zzk')
18 
19     def tearDown(self):
20         pass
21 
22 if __name__ == "__main__":
23     unittest.main()
 1 #!/usr/bin/env python
 2 # -*- coding: utf-8 -*-
 3 # @Time    : 2017-05-10 16:34
 4 # all_case.py
 5 
 6 import unittest
 7 import HTMLTestRunner
 8 import time,os,datetime
 9 import smtplib
10 from email.mime.text import MIMEText
11 from email.mime.multipart import MIMEMultipart
12 from email.mime.image import MIMEImage
13 
14 
15 
16 # 取test_case文件夹下所有用例文件
17 def creatsuitel(lists):
18     testunit = unittest.TestSuite()
19     # discover 方法定义
20     discover = unittest.defaultTestLoader.discover(lists, pattern='start_*.py', top_level_dir=None)
21     #discover 方法筛选出来的用例,循环添加到测试套件中
22     for test_suite in discover:
23         for test_case in test_suite:
24             testunit.addTests(test_case)
25             print(testunit)
26     return testunit
27 list_1 = 'test_case\\test_case_1'
28 alltestnames = creatsuitel(list_1)
29 
30 #取前面时间加入到测试报告文件名中
31 now = time.strftime("%Y-%m-%M-%H_%M_%S", time.localtime(time.time()))
32 filename = "report\\"+now+'result.html' #定义个报告存放路径,支持相对路径。
33 fp = open(filename, 'wb')
34 runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title='Report_title', description='Report_description')
35 
36 if __name__ == "__main__":
37     # 执行测试用例集并生成报告
38     runner = unittest.TextTestRunner()

 

感谢@大师兄+@我去热饭的指导与帮助。

 

为什么选择?

有的人喜欢创造世界,他们做了程序员

有的人喜欢拯救世界,他们做了测试员

 

转载于:https://www.cnblogs.com/hxjxb/p/6914263.html

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

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

相关文章

vs远程编译linux程序,使用Visual Studio 2015远程调试Linux程序

##安装 Visual Studio 2015安装时注意将跨平台移动开发->Visual C移动开发->Viaual C Android 开发的选项勾上##安装PUTTYVisual Studio依赖putty中的plink来连接Linux机器并发送命令##使用首先在Visual Studio中新建一个空项目这里是列表文本接下来将代码导入到这个空项…

都在说反射,反射到底是什么

概念: 什么是反射? 利用反射可以无视修饰符获取类里面所有的属性和方法对于任何对象,都能够调用它的方法和属性,这种动态获取信息以及动态调用对象方法的功能称为Java的反射 反射的应用场景? 常见的有: idea的智能提示、框架等…

LaunchScreen原理

会自动加载LaunchScreen是因为在Target当中,指定了Launch Screen file 它的底层实现其实把LaunchScreen上的东西,生成了一张图片,然后把这张图片设为程序的启动图片.可以进入沙盒当中查看,查看方法,找到应用程序根目录.获取方法: NSLog("%",NSHomeDirectory());打印出…

Mac - 苹果电脑mac系统释放硬盘空间方法汇总

硬盘空间是大家最头痛的一个问题,大家在硬盘空间变小的时候怎么腾空间的呢?下面为大家分享7个mac系统释放空间的高级方法,大家赶紧来收了! mac系统释放硬盘空间方法: 方法一:删除Emacs——可以节省出60MB的…

XML语言

XML: XML是可扩展的标记语言 标记语言: 通过标签来描述数据的一门语言(标签有时我们也将其称之为元素) 可扩展:标签的名字是可以自定义的,XML文件是由很多标签组成的,而标签名是可以自定义的 xml学习网站https://www.w3school.com.cn/x.asp 作用&#xf…

xml中的Document和Attribute

1.Document 导入dom4j的步骤 去官网下载 zip 包。http://www.dom4j.org/ 在项目中创建一个文件夹:lib将dom4j-2.1.1.jar文件复制到 lib 文件夹在jar文件上点右键,选择 Add as Library -> 点击OK在类中导包使用 得到Document对象 步骤:…

XPath表达式

什么是XPath XPath:路径表达式 作用:在DOM解析XML时,通过XPath表达让解析更加简单 XPath表达式分类 绝对路径相对路径全文搜索属性查找 什么是Node对象 DOM树中的每个节点就是Node dom4j中与XPath相关的方法 注:使用XPat…

最详细MySQL的安装与介绍Windows

数据库的安装: 打开下载的mysql安装⽂件双击解压缩,运⾏“mysql-5.5.40-win32.msi”。 选择安装类型,有“Typical(默认)”、“Complete(完全)”、“Custom(⽤户⾃定义)”…

读懂基础机器学习算法

本篇内容主要是面向机器学习初学者,介绍常见的机器学习算法,当然,欢迎同行交流。 哲学要回答的基本问题是从哪里来、我是谁、到哪里去,寻找答案的过程或许可以借鉴机器学习的套路:组织数据->挖掘知识->预测未来。…

在c语言中有函数leapyear定义如下,职业教育概论——职业教育的发展历史超星尔雅答案题库...

职业职业展历有时候,文学造诣高的中国诗歌翻译者在用词华丽方面超过莎士比亚。有int型变量x,教育教育i,j,k,则表达式x(i5,j6,k7)的值为( )从数据表student中查询张姓的所有学生,概论正确的SQL语句是( )史超世界上第一个…

tomcat安装启动配置

服务器: 服务器的概念非常的广泛,它可以指代一台特殊的计算机(相比普通计算机运行更快、负载更高、价格更贵),也可以指代用于部署网站的应用。我们这里说的服务器,其实是web服务器,或者应用服务…

JS在页面限制checkbox最大复选数

应该是挺简单的代码, 记录一下分享. 首先最直接的想法就是使用循环, 用局部变量记录已选的checkbox, 达到最大值就将余下的checkbox都禁止选择, 例如以下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ""> <html xmlns"…

c语言 二维数组 文库,c语言二维数组练习题

c语言二维数组练习题 (3页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;19.90 积分完成下列程序代码完成下列程序代码1、 将二维数组(5 行 5 列)的右上半部分置零。 即&#xff1a;1234510000678910…

android陀螺仪轨迹,陀螺仪轨迹法长距离管道测量精度实测分析

陀螺仪轨迹法长距离管道测量精度实测分析陀螺仪轨迹法用于非开挖管道的精准坐标与位置测量已被电力与燃气等行业逐步了解与接受&#xff0c;近两年不断被引入到城市地下管线探测及电力与燃气管道验收标准中。由于管道埋于地下往往不能眼见为实&#xff0c;作为一种新的测量方式…

Spring IOC详解与配置

Spring&#xff1a; 框架&#xff1a; 具有一定功能的半成品软件&#xff0c;基于框架会节省开发成本 框架作用&#xff1a; 提高开发效率、复用性、编写规范、节约维护成本、解耦底层实现原理 Spring&#xff1a; Spring是分层的JavaSE/EE应用full-stack轻量级开源框架Sprin…

android8.0的蓝牙版本,android o 新特性详解 安卓8.0蓝牙音频增强以及更加可爱的表情包...

android 8.0什么时候推出&#xff1f;有哪些新特色&#xff1f;很多安卓用户非常想知道答案吧&#xff01;不用着急&#xff0c;下面是大麦子小编整理出来的安卓8.0新特性详解&#xff0c;希望可以帮到大家。有媒体近日曝光了有关谷歌Pixel XL 2手机会首发Android 8.0系统。现在…

DOM初级篇

DOM是什么、作用、与javascript&#xff1f; DOM是对HTML文档的访问和操作&#xff0c;对文档的增删改查。 DOM相当于是javascript一个类&#xff0c;这个类中提供了多种操作HTML的方法&#xff0c;也可以说DOM是依附在JavaScript上进行操作的。 一、标签的查找命令&#xff1b…

vs2019开发android应用,VS 2019开发APP(一)界面和代码

1.界面在Resources>layout>目录下的*.xml文件就是界面文件2.关联界面接下来&#xff0c;通过将支持代码插入到 MainActivity 类中来添加代码以关联用户界面。在 MainActivity 类中找到 OnCreate 方法&#xff0c;在其中添加关联按钮代码如下&#xff1a;protected overri…

oracle 数据库字段html显示正常text显示不全,layui表格字段表格显示不全(自适应)...

本文将为您描述layui表格字段表格显示不全(自适应),具体操作方法:好记性不如烂笔头。本来就是没什么好记得东西&#xff0c;下次再用时已经想不起来了。问题如下&#x1f41f;使用layui表格&#xff0c;表格字段显示不全&#xff0c;如果超出分配的位置&#xff0c;就会显示省略…

使用 VSCode 编写 .NET Core 项目之初体验

注&#xff1a;本文在根据 微软官方文档指导下&#xff0c;根据自己的学习中整理&#xff0c;并不完全照搬文档&#xff0c;但也大体和文档学习路线相似&#xff0c;主要为记录学习过程。 官方学习地址&#xff1a; https://code.visualstudio.com/docs/other/dotnet https://d…