selenium 中装饰器作用
前面讲到unittest里面setUp可以在每次执行用例前执行,这样有效的减少了代码量,但是有个弊端,比如打开浏览器操作,每次执行用例时候都会重新打开,这样就会浪费很多时间。于是就想是不是可以只打开一次浏览器,执行完用例再关闭呢?这就需要用到装饰器(@classmethod)来解决了。
一、装饰器
1.用setUp与setUpClass区别
setup():每个测试case运行前运行
teardown():每个测试case运行完后执行
setUpClass():必须使用@classmethod 装饰器,所有case运行前只运行一次
tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次
2.@是修饰符,classmethod是python里的类方法
二、执行顺序
1.用类方法写几个简单case,可以对比这篇:Selenium2+python自动化52-unittest执行顺序
# coding:utf-8
import unittest
import time
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
print "start!"
@classmethod
def tearDownClass(cls):
time.sleep(1)
print "end!"
def test01(self):
print "执行测试用例01"
def test03(self):
print "执行测试用例03"
def test02(self):
print "执行测试用例02"
def addtest(self):
print "add方法"
if __name__ == "__main__":
unittest.main()
2.从执行结果可以看出,前置和后置在执行用例前只执行了一次。
start!
执行测试用例01
执行测试用例02
执行测试用例03
...end!
----------------------------------------------------------------------
Ran 3 tests in 1.001s
三、selenium实例
1.可以把打开浏览器操作放到前置setUpClass(cls)里,这样就可以实现打开一次浏览器,执行多个case了
# coding:utf-8
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
import unittest
class BolgHome(unittest.TestCase):
u'''博客首页'''
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Firefox()
url = "http://www.cnblogs.com/yoyoketang/"
cls.driver.get(url)
cls.driver.implicitly_wait(30)
@classmethod
def tearDownClass(cls):
cls.driver.quit()
def test_01(self):
u'''验证元素存在:博客园'''
locator = ("id", "blog_nav_sitehome")
text = u"博客园"
result = EC.text_to_be_present_in_element(locator, text)(self.driver)
self.assertTrue(result)
def test_02(self):
u'''验证元素存在:首页'''
locator = ("id", "blog_nav_myhome")
text = u"首页"
result = EC.text_to_be_present_in_element(locator, text)(self.driver)
self.assertTrue(result)
if __name__ == "__main__":
unittest.main()
#!/usr/bin/env python
# coding=utf-8
__author__ = 'Luzhuo'
__date__ = '2017/5/4'
# decorator.py 装饰器
# 装饰器: 本质是函数, 用于装饰其他函数, 附加一些本身所没有的功能
# 函数就是变量
def num():
print("num")
num()
num = 1 # 函数就是变量
# num() # num的引用被指向1,不能再调用
# ========================================
# 高阶函数
def func_1():
print("func_1")
def func_2(func): # 接收函数变量
func()
func_2(func_1) # => func_1
# ========================================
# 闭包
def func_3(line):
# 闭包: 用于代码封装 和 复用
def comp(value): # 嵌套函数: 函数里再嵌套一个函数
# 函数set_line执行完(生命周期结束), 自由变量(line)仍存活于包裹内
if value >= line:
print("{} >= {}".format(value, line))
else:
print("{} < {}".format(value, line))
return comp
f = func_3(60) # 调用函数A(set_line()),返回函数B(cmp()),这个函数B就叫闭包
f(89) # => 89 >= 60
f(59) # => 59 < 60
# ========================================
# 装饰器, 在不修改my_average()代码的情况下,为其添加了一些功能(wrapper())
def dec_1(func):
def wrapper(num1, num2):
# --- 附加功能 ---
if num2 == 0:
print("num2 值不能为0")
return func(num1, num2)
return wrapper
# 普通调用方式
def average_1(num1, num2):
return num1 / num2
average_1 = dec_1(average_1)
print(average_1(5, 3)) # => 1.6666666666666667
# 使用@语法糖的方式
@dec_1 # (sum = dec(sum))
def sum_1(num1, num2):
return num1 + num2
print(sum_1(5, 3)) # => 8
# ========================================
# 能接收任何参数的通用装饰器
def dec_2(func):
def wrapper(*arg, **kwargs):
# --- 附加功能 ---
print("loging i ...")
return func(*arg, **kwargs)
return wrapper
@dec_2
def average_2(num1, num2):
return num1 / num2
print(average_2(5, 3)) # => loging i ... => 1.6666666666666667
@dec_2
def sum_2(*args):
return sum(args)
print(sum_2(5, 3, 2, 1)) # => loging i ... => 11
# ========================================
# 能接收不同参数的装饰器
def auth(auth_type): # 在外面套一层
def dec_3(func):
def wrapper(*arg, **kwargs):
# --- 附加功能 ---
if auth_type == "admin":
print("你是管理员")
elif auth_type == "user":
print("你是普通用户")
else:
print("你是外星人吗?")
return func(*arg, **kwargs)
return wrapper
return dec_3
# 普通调用方式
@auth(auth_type="admin")
def average_3(*arg):
return sum(arg) / len(arg)
print(average_3(1, 2, 3, 4, 5)) # => 你是管理员 => 3.0
@auth(auth_type="user")
def sum_3(*arg):
return sum(arg)
print(sum_3(5, 3, 2, 1)) # => 你是普通用户 => 11
# ========================================
# 使用多个装饰器
@dec_1
@dec_2
@auth(auth_type="admin")
def average_2(num1, num2):
return num1 / num2
# 执行顺序dec_1 => dec_2 => auth => average_2
print(average_2(5, 3)) # => loging i ... => 你是管理员 => 1.6666666666666667
---------------------
首先,程序开始从guoguo()执行了,结果它发现该函数前面有个@,就知道该函数被装饰了,那就先去看看装饰了哪些功能吧。
然后,该函数就作为参数进入到decorate()中,返回另一个函数test。
最后,test()中就把需要添加给guoguo()的功能写在此处,如果需要guoguo()的结果,就在需要的地方调用即可。
这就是我理解的装饰器,概况来说,就是把需要装饰的函数当做装饰器函数的参数,然后返回一个新函数,在新函数中实现装饰功能。
selenium 中装饰器作用的更多相关文章
- 8.Python中装饰器是什么?
Python中装饰器是什么? A Python decorator is a specific change that we make in Python syntax to alter functi ...
- 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法
第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一. 案例说明 本节定义了类Sta ...
- Flask-Login中装饰器@login_manager.user_loader的作用及原理
Flask-Login通过装饰器@login_required来检查访问视图函数的用户是否已登录,没有登录时会跳转到login_manager.login_view = 'auth.login'所注册 ...
- python中装饰器的原理
装饰器这玩意挺有用,当时感觉各种绕,现在终于绕明白了,俺滴个大爷,还是要慢慢思考才能买明白各种的真谛,没事就来绕一绕 def outer(func): def inner(): print(" ...
- python中装饰器修复技术
python装饰器@wraps作用-修复被装饰后的函数名等属性的改变 Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变), 为了 ...
- Python中装饰器(转)
本文由 伯乐在线 - 7even 翻译,艾凌风 校稿.未经许可,禁止转载!英文出处:Simeon Franklin.欢迎加入翻译组. 好吧,我标题党了.作为 Python 教师,我发现理解装饰器是学生 ...
- Python中装饰器的用法
定义: 装饰器本身就是一个函数 为其他函数提供附加功能 不改变源代码 不改变原调用方式 装饰器=高阶函数+嵌套函数 知识点: 函数本身就是一个变量(意味着可以被复制给一个变量:test=test(1) ...
- python flask route中装饰器的使用
问题:route中的装饰器为什么感觉和平时使用的不太一样,装饰器带参数和不太参数有什么区别?被修饰的函数带参数和不带参数有什么区别? 测试1:装饰器不带参数,被修饰的函数也不带参数. def log( ...
- python中装饰器使用
装饰器是对已有的模块进行装饰(添加新功能)的函数. 现有一段代码: import time def func1(): time.sleep(3) print("in the func1&qu ...
随机推荐
- 关于“ORA-01747: user.table.column, table.column 或列说明无效”的报错。
今天在工程中遇到“ORA-01747: user.table.column, table.column 或列说明无效”的报错情况,查了一下是由于数据库列名起的不好引起的,名字用到了数据库的关键字.
- poj_1475 BFS+BFS
题目大意 推箱子游戏的基本玩法,求将箱子推到目的地的推动次数最少(并不是人移动总次数)的人移动路径. 题目分析 求最短路径的搜索问题,使用BFS.注意题目求的是 推动次数最少,因此将箱子移动作为状态, ...
- 网络子系统45_ip协议tos处理
//ip报头tos字段,一个字节 // 二进制位:[0 1 2] [3] [4] [5] [6] [7] // 1.[0 1 2] 表示优先级: // 000 路由 // 001 优先级 // 010 ...
- 旅游吧!我在这里 ——旅游相册POI搜索:找回你的足迹
版权声明:本文由林少彬原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/89 来源:腾云阁 https://www.qclou ...
- Cordova 3.0 初步使用
主要参考 http://docs.phonegap.com/en/3.0.0/guide_cli_index.md.html#The%20Command-line%20Interface Cordov ...
- EUI组件之DataGroup
看官网教程,这个没法单独用. http://developer.egret.com/cn/github/egret-docs/extension/EUI/dataCollection/dataGrou ...
- ShowDoc 搭建 (未成功....)
官方教程:https://www.showdoc.cc/help?page_id=13732 下载了showdoc,服务器映射本地磁盘的时候,服务器用户名和密码忘了... 远程服务器用户名和密码修改 ...
- img通过canvas转成base64编码
<script type="text/javascript"> function getBase64Image(img) { var canvas = document ...
- 【BZOJ1834】[ZJOI2010]network 网络扩容 最大流+最小费用流
[BZOJ1834][ZJOI2010]network 网络扩容 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不 ...
- 02.JMS基础
1.面向消息的中间件(MOM) 1.什么是MOM 面向消息的中间件,Message Oriented Middleware,简称MOM,中文简称消息中间件,利用高效可靠的消息传递机制进行平台无 ...