组织分层:
1、普通方式,和unittest分层类似:
setup_module() # 通常放在类外
setup_class(cls)
setup(self)
teardown(self)
teardown_class(cls)
teardown_module()
2、pytest特有的分层方式
@pytest.fixture() 装饰fixture
@pytest.mark.usefixtures() 使用fixture
例一:
@pytest.fixture() # 默认scope是function,等同于@pytest.fixture(scope="function"),作用于每个test用例
def before():
print u"清除数据"
class TestClass(common): # 继承common类中setup_class
def setup(self): # 可以和before并存,如果某个用例使用了before,共同生效。
print "start"
def teardown(self):
print "end"
@pytest.mark.usefixtures("before") #使用fixture的方法一
def test_one(self):
x = "this"
assert "h" in x
def test_two(self,before): # 使用fixture的方法二
x = "hello"
assert x == "hello"
if __name__=="__main__":
pytest.main("-s test_pt2.py") # 指定测试文件
执行后结果:
@pytest.fixture(scope="xxx") 有4个范围,function、class、module、session 。session是作用于整个项目。
例二:
#coding:utf8
import pytest
class DB(object):
def __init__(self):
self.intransaction = []
def begin(self, name):
self.intransaction.append(name)
def rollback(self):
self.intransaction.pop()
@pytest.fixture(scope="module")
def db(): # 工厂模式
print "module start"
return DB()
# @pytest.mark.usefixtures("transact") #作用于整个类,即对类中所有用例都生效
class TestClass(object):
@pytest.fixture(autouse=True) # 设置一个function级别的fixture, autouse=True 表示对所有用例生效 ,等效于在测试类前@pytest.mark.usefixtures("transact")
def transact(self,request, db):
db.begin(request.function.__name__)
print "transact"
yield # yield之后的内容可以当成teardown !!!
db.rollback()
print "rollback"
def test_method1(self,db): # 这里需要引入db ,db是module范围,每个模块只运行一次
#module只运行一次,那么在这个module范围(module表示同一层目录中?)中所有的用例引用db得到的参数DB()是同一个。这里类似于module范围的一个全局变量
assert db.intransaction == ["test_method1"]
def test_method2(self,db):
assert db.intransaction == ["test_method2"]
if __name__=="__main__":
pytest.main("-s autofixtures.py")
执行结果:
参数化:
#参数化一,先定义函数,更灵活
@pytest.fixture(params=[2,3,4])
def before3(request): #request固定格式
param=request.param
print param
return param+1
再使用:
def test_four(self,before3): # 参数化
assert before3 !=3
# 参数化二,简便
@pytest.mark.parametrize("param", [1, 2, 3])
def test_three(self,param): # 参数化
assert param !=2
参数覆盖fixture:
conftest.py :
import pytest
@pytest.fixture
def username():
return 'username'
@pytest.fixture
def other_username(username):
return 'other-' + username
test_something.py:
#coding:utf8
import pytest
# 同一层级的fixture可以直接引用
@pytest.mark.parametrize('username', ['directly-overridden-username'])
def test_username(username): # conftest中的fixture:username,这里被参数username直接覆盖
assert username == 'directly-overridden-username'
@pytest.mark.parametrize('username', ['directly-overridden-username-other'])
def test_username_other(other_username): # conftest中的fixture:other_username,other_username引用了username,这里被参数usename间接覆盖了
assert other_username == 'other-directly-overridden-username-other'
if __name__=="__main__":
pytest.main("-s test_something.py")
更多fixture覆盖参考:https://blog.csdn.net/huitailang1991/article/details/74053781