pytest 学习笔记一:参数化与组织分层

组织分层:

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



原文地址:https://www.cnblogs.com/who-care/p/8875779.html